ActivityManagerService.java revision e535a5827b7b7c7c70f4701d74051c9bb5eb0b98
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.NonNull;
67import android.annotation.UserIdInt;
68import android.app.Activity;
69import android.app.ActivityManager;
70import android.app.ActivityManager.RunningTaskInfo;
71import android.app.ActivityManager.StackId;
72import android.app.ActivityManager.StackInfo;
73import android.app.ActivityManager.TaskThumbnailInfo;
74import android.app.ActivityManagerInternal;
75import android.app.ActivityManagerInternal.SleepToken;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.AppOpsManager;
82import android.app.ApplicationErrorReport;
83import android.app.ApplicationThreadNative;
84import android.app.BroadcastOptions;
85import android.app.Dialog;
86import android.app.IActivityContainer;
87import android.app.IActivityContainerCallback;
88import android.app.IActivityController;
89import android.app.IAppTask;
90import android.app.IApplicationThread;
91import android.app.IInstrumentationWatcher;
92import android.app.INotificationManager;
93import android.app.IProcessObserver;
94import android.app.IServiceConnection;
95import android.app.IStopUserCallback;
96import android.app.ITaskStackListener;
97import android.app.IUiAutomationConnection;
98import android.app.IUidObserver;
99import android.app.IUserSwitchObserver;
100import android.app.Instrumentation;
101import android.app.Notification;
102import android.app.NotificationManager;
103import android.app.PendingIntent;
104import android.app.ProfilerInfo;
105import android.app.admin.DevicePolicyManager;
106import android.app.assist.AssistContent;
107import android.app.assist.AssistStructure;
108import android.app.backup.IBackupManager;
109import android.app.usage.UsageEvents;
110import android.app.usage.UsageStatsManagerInternal;
111import android.appwidget.AppWidgetManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.PackageManager.NameNotFoundException;
136import android.content.pm.PackageManagerInternal;
137import android.content.pm.ParceledListSlice;
138import android.content.pm.PathPermission;
139import android.content.pm.PermissionInfo;
140import android.content.pm.ProviderInfo;
141import android.content.pm.ResolveInfo;
142import android.content.pm.ServiceInfo;
143import android.content.pm.ShortcutServiceInternal;
144import android.content.pm.UserInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.content.res.Resources;
148import android.database.ContentObserver;
149import android.graphics.Bitmap;
150import android.graphics.Point;
151import android.graphics.Rect;
152import android.location.LocationManager;
153import android.net.Proxy;
154import android.net.ProxyInfo;
155import android.net.Uri;
156import android.os.BatteryStats;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IProcessInfoService;
170import android.os.IProgressListener;
171import android.os.LocaleList;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.PersistableBundle;
177import android.os.PowerManager;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.ResultReceiver;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.Trace;
188import android.os.TransactionTooLargeException;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.os.WorkSource;
193import android.os.storage.IMountService;
194import android.os.storage.MountServiceInternal;
195import android.os.storage.StorageManager;
196import android.provider.Settings;
197import android.service.voice.IVoiceInteractionSession;
198import android.service.voice.VoiceInteractionManagerInternal;
199import android.service.voice.VoiceInteractionSession;
200import android.telecom.TelecomManager;
201import android.text.format.DateUtils;
202import android.text.format.Time;
203import android.text.style.SuggestionSpan;
204import android.util.ArrayMap;
205import android.util.ArraySet;
206import android.util.AtomicFile;
207import android.util.DebugUtils;
208import android.util.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    BroadcastQueue mFgBroadcastQueue;
573    BroadcastQueue mBgBroadcastQueue;
574    // Convenient for easy iteration over the queues. Foreground is first
575    // so that dispatch of foreground broadcasts gets precedence.
576    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
577
578    BroadcastStats mLastBroadcastStats;
579    BroadcastStats mCurBroadcastStats;
580
581    BroadcastQueue broadcastQueueForIntent(Intent intent) {
582        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
583        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
584                "Broadcast intent " + intent + " on "
585                + (isFg ? "foreground" : "background") + " queue");
586        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
587    }
588
589    /**
590     * Activity we have told the window manager to have key focus.
591     */
592    ActivityRecord mFocusedActivity = null;
593
594    /**
595     * User id of the last activity mFocusedActivity was set to.
596     */
597    private int mLastFocusedUserId;
598
599    /**
600     * If non-null, we are tracking the time the user spends in the currently focused app.
601     */
602    private AppTimeTracker mCurAppTimeTracker;
603
604    /**
605     * List of intents that were used to start the most recent tasks.
606     */
607    final RecentTasks mRecentTasks;
608
609    /**
610     * For addAppTask: cached of the last activity component that was added.
611     */
612    ComponentName mLastAddedTaskComponent;
613
614    /**
615     * For addAppTask: cached of the last activity uid that was added.
616     */
617    int mLastAddedTaskUid;
618
619    /**
620     * For addAppTask: cached of the last ActivityInfo that was added.
621     */
622    ActivityInfo mLastAddedTaskActivity;
623
624    /**
625     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
626     */
627    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
628
629    /**
630     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
631     */
632    String mDeviceOwnerName;
633
634    final UserController mUserController;
635
636    final AppErrors mAppErrors;
637
638    boolean mDoingSetFocusedActivity;
639
640    public boolean canShowErrorDialogs() {
641        return mShowDialogs && !mSleeping && !mShuttingDown;
642    }
643
644    // it's a semaphore; boost when 0->1, reset when 1->0
645    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
646        @Override protected Integer initialValue() {
647            return 0;
648        }
649    };
650
651    static void boostPriorityForLockedSection() {
652        if (sIsBoosted.get() == 0) {
653            // boost to prio 118 while holding a global lock
654            Process.setThreadPriority(Process.myTid(), -2);
655            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
656        }
657        int cur = sIsBoosted.get();
658        sIsBoosted.set(cur + 1);
659    }
660
661    static void resetPriorityAfterLockedSection() {
662        sIsBoosted.set(sIsBoosted.get() - 1);
663        if (sIsBoosted.get() == 0) {
664            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
665            Process.setThreadPriority(Process.myTid(), 0);
666        }
667    }
668    public class PendingAssistExtras extends Binder implements Runnable {
669        public final ActivityRecord activity;
670        public final Bundle extras;
671        public final Intent intent;
672        public final String hint;
673        public final IResultReceiver receiver;
674        public final int userHandle;
675        public boolean haveResult = false;
676        public Bundle result = null;
677        public AssistStructure structure = null;
678        public AssistContent content = null;
679        public Bundle receiverExtras;
680
681        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
682                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
683            activity = _activity;
684            extras = _extras;
685            intent = _intent;
686            hint = _hint;
687            receiver = _receiver;
688            receiverExtras = _receiverExtras;
689            userHandle = _userHandle;
690        }
691        @Override
692        public void run() {
693            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
694            synchronized (this) {
695                haveResult = true;
696                notifyAll();
697            }
698            pendingAssistExtrasTimedOut(this);
699        }
700    }
701
702    final ArrayList<PendingAssistExtras> mPendingAssistExtras
703            = new ArrayList<PendingAssistExtras>();
704
705    /**
706     * Process management.
707     */
708    final ProcessList mProcessList = new ProcessList();
709
710    /**
711     * All of the applications we currently have running organized by name.
712     * The keys are strings of the application package name (as
713     * returned by the package manager), and the keys are ApplicationRecord
714     * objects.
715     */
716    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
717
718    /**
719     * Tracking long-term execution of processes to look for abuse and other
720     * bad app behavior.
721     */
722    final ProcessStatsService mProcessStats;
723
724    /**
725     * The currently running isolated processes.
726     */
727    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
728
729    /**
730     * Counter for assigning isolated process uids, to avoid frequently reusing the
731     * same ones.
732     */
733    int mNextIsolatedProcessUid = 0;
734
735    /**
736     * The currently running heavy-weight process, if any.
737     */
738    ProcessRecord mHeavyWeightProcess = null;
739
740    /**
741     * All of the processes we currently have running organized by pid.
742     * The keys are the pid running the application.
743     *
744     * <p>NOTE: This object is protected by its own lock, NOT the global
745     * activity manager lock!
746     */
747    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
748
749    /**
750     * All of the processes that have been forced to be foreground.  The key
751     * is the pid of the caller who requested it (we hold a death
752     * link on it).
753     */
754    abstract class ForegroundToken implements IBinder.DeathRecipient {
755        int pid;
756        IBinder token;
757    }
758    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
759
760    /**
761     * List of records for processes that someone had tried to start before the
762     * system was ready.  We don't start them at that point, but ensure they
763     * are started by the time booting is complete.
764     */
765    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
766
767    /**
768     * List of persistent applications that are in the process
769     * of being started.
770     */
771    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
772
773    /**
774     * Processes that are being forcibly torn down.
775     */
776    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
777
778    /**
779     * List of running applications, sorted by recent usage.
780     * The first entry in the list is the least recently used.
781     */
782    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
783
784    /**
785     * Where in mLruProcesses that the processes hosting activities start.
786     */
787    int mLruProcessActivityStart = 0;
788
789    /**
790     * Where in mLruProcesses that the processes hosting services start.
791     * This is after (lower index) than mLruProcessesActivityStart.
792     */
793    int mLruProcessServiceStart = 0;
794
795    /**
796     * List of processes that should gc as soon as things are idle.
797     */
798    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
799
800    /**
801     * Processes we want to collect PSS data from.
802     */
803    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
804
805    private boolean mBinderTransactionTrackingEnabled = false;
806
807    /**
808     * Last time we requested PSS data of all processes.
809     */
810    long mLastFullPssTime = SystemClock.uptimeMillis();
811
812    /**
813     * If set, the next time we collect PSS data we should do a full collection
814     * with data from native processes and the kernel.
815     */
816    boolean mFullPssPending = false;
817
818    /**
819     * This is the process holding what we currently consider to be
820     * the "home" activity.
821     */
822    ProcessRecord mHomeProcess;
823
824    /**
825     * This is the process holding the activity the user last visited that
826     * is in a different process from the one they are currently in.
827     */
828    ProcessRecord mPreviousProcess;
829
830    /**
831     * The time at which the previous process was last visible.
832     */
833    long mPreviousProcessVisibleTime;
834
835    /**
836     * Track all uids that have actively running processes.
837     */
838    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
839
840    /**
841     * This is for verifying the UID report flow.
842     */
843    static final boolean VALIDATE_UID_STATES = true;
844    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
845
846    /**
847     * Packages that the user has asked to have run in screen size
848     * compatibility mode instead of filling the screen.
849     */
850    final CompatModePackages mCompatModePackages;
851
852    /**
853     * Set of IntentSenderRecord objects that are currently active.
854     */
855    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
856            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
857
858    /**
859     * Fingerprints (hashCode()) of stack traces that we've
860     * already logged DropBox entries for.  Guarded by itself.  If
861     * something (rogue user app) forces this over
862     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
863     */
864    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
865    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
866
867    /**
868     * Strict Mode background batched logging state.
869     *
870     * The string buffer is guarded by itself, and its lock is also
871     * used to determine if another batched write is already
872     * in-flight.
873     */
874    private final StringBuilder mStrictModeBuffer = new StringBuilder();
875
876    /**
877     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
878     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
879     */
880    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
881
882    /**
883     * Resolver for broadcast intents to registered receivers.
884     * Holds BroadcastFilter (subclass of IntentFilter).
885     */
886    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
887            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
888        @Override
889        protected boolean allowFilterResult(
890                BroadcastFilter filter, List<BroadcastFilter> dest) {
891            IBinder target = filter.receiverList.receiver.asBinder();
892            for (int i = dest.size() - 1; i >= 0; i--) {
893                if (dest.get(i).receiverList.receiver.asBinder() == target) {
894                    return false;
895                }
896            }
897            return true;
898        }
899
900        @Override
901        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
902            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
903                    || userId == filter.owningUserId) {
904                return super.newResult(filter, match, userId);
905            }
906            return null;
907        }
908
909        @Override
910        protected BroadcastFilter[] newArray(int size) {
911            return new BroadcastFilter[size];
912        }
913
914        @Override
915        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
916            return packageName.equals(filter.packageName);
917        }
918    };
919
920    /**
921     * State of all active sticky broadcasts per user.  Keys are the action of the
922     * sticky Intent, values are an ArrayList of all broadcasted intents with
923     * that action (which should usually be one).  The SparseArray is keyed
924     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
925     * for stickies that are sent to all users.
926     */
927    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
928            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
929
930    final ActiveServices mServices;
931
932    final static class Association {
933        final int mSourceUid;
934        final String mSourceProcess;
935        final int mTargetUid;
936        final ComponentName mTargetComponent;
937        final String mTargetProcess;
938
939        int mCount;
940        long mTime;
941
942        int mNesting;
943        long mStartTime;
944
945        // states of the source process when the bind occurred.
946        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
947        long mLastStateUptime;
948        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
949                - ActivityManager.MIN_PROCESS_STATE+1];
950
951        Association(int sourceUid, String sourceProcess, int targetUid,
952                ComponentName targetComponent, String targetProcess) {
953            mSourceUid = sourceUid;
954            mSourceProcess = sourceProcess;
955            mTargetUid = targetUid;
956            mTargetComponent = targetComponent;
957            mTargetProcess = targetProcess;
958        }
959    }
960
961    /**
962     * When service association tracking is enabled, this is all of the associations we
963     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
964     * -> association data.
965     */
966    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
967            mAssociations = new SparseArray<>();
968    boolean mTrackingAssociations;
969
970    /**
971     * Backup/restore process management
972     */
973    String mBackupAppName = null;
974    BackupRecord mBackupTarget = null;
975
976    final ProviderMap mProviderMap;
977
978    /**
979     * List of content providers who have clients waiting for them.  The
980     * application is currently being launched and the provider will be
981     * removed from this list once it is published.
982     */
983    final ArrayList<ContentProviderRecord> mLaunchingProviders
984            = new ArrayList<ContentProviderRecord>();
985
986    /**
987     * File storing persisted {@link #mGrantedUriPermissions}.
988     */
989    private final AtomicFile mGrantFile;
990
991    /** XML constants used in {@link #mGrantFile} */
992    private static final String TAG_URI_GRANTS = "uri-grants";
993    private static final String TAG_URI_GRANT = "uri-grant";
994    private static final String ATTR_USER_HANDLE = "userHandle";
995    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
996    private static final String ATTR_TARGET_USER_ID = "targetUserId";
997    private static final String ATTR_SOURCE_PKG = "sourcePkg";
998    private static final String ATTR_TARGET_PKG = "targetPkg";
999    private static final String ATTR_URI = "uri";
1000    private static final String ATTR_MODE_FLAGS = "modeFlags";
1001    private static final String ATTR_CREATED_TIME = "createdTime";
1002    private static final String ATTR_PREFIX = "prefix";
1003
1004    /**
1005     * Global set of specific {@link Uri} permissions that have been granted.
1006     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1007     * to {@link UriPermission#uri} to {@link UriPermission}.
1008     */
1009    @GuardedBy("this")
1010    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1011            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1012
1013    public static class GrantUri {
1014        public final int sourceUserId;
1015        public final Uri uri;
1016        public boolean prefix;
1017
1018        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1019            this.sourceUserId = sourceUserId;
1020            this.uri = uri;
1021            this.prefix = prefix;
1022        }
1023
1024        @Override
1025        public int hashCode() {
1026            int hashCode = 1;
1027            hashCode = 31 * hashCode + sourceUserId;
1028            hashCode = 31 * hashCode + uri.hashCode();
1029            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1030            return hashCode;
1031        }
1032
1033        @Override
1034        public boolean equals(Object o) {
1035            if (o instanceof GrantUri) {
1036                GrantUri other = (GrantUri) o;
1037                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1038                        && prefix == other.prefix;
1039            }
1040            return false;
1041        }
1042
1043        @Override
1044        public String toString() {
1045            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1046            if (prefix) result += " [prefix]";
1047            return result;
1048        }
1049
1050        public String toSafeString() {
1051            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1052            if (prefix) result += " [prefix]";
1053            return result;
1054        }
1055
1056        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1057            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1058                    ContentProvider.getUriWithoutUserId(uri), false);
1059        }
1060    }
1061
1062    CoreSettingsObserver mCoreSettingsObserver;
1063
1064    FontScaleSettingObserver mFontScaleSettingObserver;
1065
1066    private final class FontScaleSettingObserver extends ContentObserver {
1067        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1068
1069        public FontScaleSettingObserver() {
1070            super(mHandler);
1071            ContentResolver resolver = mContext.getContentResolver();
1072            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1073        }
1074
1075        @Override
1076        public void onChange(boolean selfChange, Uri uri) {
1077            if (mFontScaleUri.equals(uri)) {
1078                updateFontScaleIfNeeded();
1079            }
1080        }
1081    }
1082
1083    /**
1084     * Thread-local storage used to carry caller permissions over through
1085     * indirect content-provider access.
1086     */
1087    private class Identity {
1088        public final IBinder token;
1089        public final int pid;
1090        public final int uid;
1091
1092        Identity(IBinder _token, int _pid, int _uid) {
1093            token = _token;
1094            pid = _pid;
1095            uid = _uid;
1096        }
1097    }
1098
1099    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1100
1101    /**
1102     * All information we have collected about the runtime performance of
1103     * any user id that can impact battery performance.
1104     */
1105    final BatteryStatsService mBatteryStatsService;
1106
1107    /**
1108     * Information about component usage
1109     */
1110    UsageStatsManagerInternal mUsageStatsService;
1111
1112    /**
1113     * Access to DeviceIdleController service.
1114     */
1115    DeviceIdleController.LocalService mLocalDeviceIdleController;
1116
1117    /**
1118     * Information about and control over application operations
1119     */
1120    final AppOpsService mAppOpsService;
1121
1122    /**
1123     * Current configuration information.  HistoryRecord objects are given
1124     * a reference to this object to indicate which configuration they are
1125     * currently running in, so this object must be kept immutable.
1126     */
1127    Configuration mConfiguration = new Configuration();
1128
1129    /**
1130     * Current sequencing integer of the configuration, for skipping old
1131     * configurations.
1132     */
1133    int mConfigurationSeq = 0;
1134
1135    boolean mSuppressResizeConfigChanges = false;
1136
1137    /**
1138     * Hardware-reported OpenGLES version.
1139     */
1140    final int GL_ES_VERSION;
1141
1142    /**
1143     * List of initialization arguments to pass to all processes when binding applications to them.
1144     * For example, references to the commonly used services.
1145     */
1146    HashMap<String, IBinder> mAppBindArgs;
1147
1148    /**
1149     * Temporary to avoid allocations.  Protected by main lock.
1150     */
1151    final StringBuilder mStringBuilder = new StringBuilder(256);
1152
1153    /**
1154     * Used to control how we initialize the service.
1155     */
1156    ComponentName mTopComponent;
1157    String mTopAction = Intent.ACTION_MAIN;
1158    String mTopData;
1159
1160    volatile boolean mProcessesReady = false;
1161    volatile boolean mSystemReady = false;
1162    volatile boolean mOnBattery = false;
1163    volatile int mFactoryTest;
1164
1165    @GuardedBy("this") boolean mBooting = false;
1166    @GuardedBy("this") boolean mCallFinishBooting = false;
1167    @GuardedBy("this") boolean mBootAnimationComplete = false;
1168    @GuardedBy("this") boolean mLaunchWarningShown = false;
1169    @GuardedBy("this") boolean mCheckedForSetup = false;
1170
1171    Context mContext;
1172
1173    /**
1174     * The time at which we will allow normal application switches again,
1175     * after a call to {@link #stopAppSwitches()}.
1176     */
1177    long mAppSwitchesAllowedTime;
1178
1179    /**
1180     * This is set to true after the first switch after mAppSwitchesAllowedTime
1181     * is set; any switches after that will clear the time.
1182     */
1183    boolean mDidAppSwitch;
1184
1185    /**
1186     * Last time (in realtime) at which we checked for power usage.
1187     */
1188    long mLastPowerCheckRealtime;
1189
1190    /**
1191     * Last time (in uptime) at which we checked for power usage.
1192     */
1193    long mLastPowerCheckUptime;
1194
1195    /**
1196     * Set while we are wanting to sleep, to prevent any
1197     * activities from being started/resumed.
1198     */
1199    private boolean mSleeping = false;
1200
1201    /**
1202     * The process state used for processes that are running the top activities.
1203     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1204     */
1205    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1206
1207    /**
1208     * Set while we are running a voice interaction.  This overrides
1209     * sleeping while it is active.
1210     */
1211    private IVoiceInteractionSession mRunningVoice;
1212
1213    /**
1214     * For some direct access we need to power manager.
1215     */
1216    PowerManagerInternal mLocalPowerManager;
1217
1218    /**
1219     * We want to hold a wake lock while running a voice interaction session, since
1220     * this may happen with the screen off and we need to keep the CPU running to
1221     * be able to continue to interact with the user.
1222     */
1223    PowerManager.WakeLock mVoiceWakeLock;
1224
1225    /**
1226     * State of external calls telling us if the device is awake or asleep.
1227     */
1228    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1229
1230    /**
1231     * A list of tokens that cause the top activity to be put to sleep.
1232     * They are used by components that may hide and block interaction with underlying
1233     * activities.
1234     */
1235    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1236
1237    static final int LOCK_SCREEN_HIDDEN = 0;
1238    static final int LOCK_SCREEN_LEAVING = 1;
1239    static final int LOCK_SCREEN_SHOWN = 2;
1240    /**
1241     * State of external call telling us if the lock screen is shown.
1242     */
1243    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1244
1245    /**
1246     * Set if we are shutting down the system, similar to sleeping.
1247     */
1248    boolean mShuttingDown = false;
1249
1250    /**
1251     * Current sequence id for oom_adj computation traversal.
1252     */
1253    int mAdjSeq = 0;
1254
1255    /**
1256     * Current sequence id for process LRU updating.
1257     */
1258    int mLruSeq = 0;
1259
1260    /**
1261     * Keep track of the non-cached/empty process we last found, to help
1262     * determine how to distribute cached/empty processes next time.
1263     */
1264    int mNumNonCachedProcs = 0;
1265
1266    /**
1267     * Keep track of the number of cached hidden procs, to balance oom adj
1268     * distribution between those and empty procs.
1269     */
1270    int mNumCachedHiddenProcs = 0;
1271
1272    /**
1273     * Keep track of the number of service processes we last found, to
1274     * determine on the next iteration which should be B services.
1275     */
1276    int mNumServiceProcs = 0;
1277    int mNewNumAServiceProcs = 0;
1278    int mNewNumServiceProcs = 0;
1279
1280    /**
1281     * Allow the current computed overall memory level of the system to go down?
1282     * This is set to false when we are killing processes for reasons other than
1283     * memory management, so that the now smaller process list will not be taken as
1284     * an indication that memory is tighter.
1285     */
1286    boolean mAllowLowerMemLevel = false;
1287
1288    /**
1289     * The last computed memory level, for holding when we are in a state that
1290     * processes are going away for other reasons.
1291     */
1292    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1293
1294    /**
1295     * The last total number of process we have, to determine if changes actually look
1296     * like a shrinking number of process due to lower RAM.
1297     */
1298    int mLastNumProcesses;
1299
1300    /**
1301     * The uptime of the last time we performed idle maintenance.
1302     */
1303    long mLastIdleTime = SystemClock.uptimeMillis();
1304
1305    /**
1306     * Total time spent with RAM that has been added in the past since the last idle time.
1307     */
1308    long mLowRamTimeSinceLastIdle = 0;
1309
1310    /**
1311     * If RAM is currently low, when that horrible situation started.
1312     */
1313    long mLowRamStartTime = 0;
1314
1315    /**
1316     * For reporting to battery stats the current top application.
1317     */
1318    private String mCurResumedPackage = null;
1319    private int mCurResumedUid = -1;
1320
1321    /**
1322     * For reporting to battery stats the apps currently running foreground
1323     * service.  The ProcessMap is package/uid tuples; each of these contain
1324     * an array of the currently foreground processes.
1325     */
1326    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1327            = new ProcessMap<ArrayList<ProcessRecord>>();
1328
1329    /**
1330     * This is set if we had to do a delayed dexopt of an app before launching
1331     * it, to increase the ANR timeouts in that case.
1332     */
1333    boolean mDidDexOpt;
1334
1335    /**
1336     * Set if the systemServer made a call to enterSafeMode.
1337     */
1338    boolean mSafeMode;
1339
1340    /**
1341     * If true, we are running under a test environment so will sample PSS from processes
1342     * much more rapidly to try to collect better data when the tests are rapidly
1343     * running through apps.
1344     */
1345    boolean mTestPssMode = false;
1346
1347    String mDebugApp = null;
1348    boolean mWaitForDebugger = false;
1349    boolean mDebugTransient = false;
1350    String mOrigDebugApp = null;
1351    boolean mOrigWaitForDebugger = false;
1352    boolean mAlwaysFinishActivities = false;
1353    boolean mLenientBackgroundCheck = false;
1354    boolean mForceResizableActivities;
1355    boolean mSupportsMultiWindow;
1356    boolean mSupportsFreeformWindowManagement;
1357    boolean mSupportsPictureInPicture;
1358    boolean mSupportsLeanbackOnly;
1359    Rect mDefaultPinnedStackBounds;
1360    IActivityController mController = null;
1361    boolean mControllerIsAMonkey = false;
1362    String mProfileApp = null;
1363    ProcessRecord mProfileProc = null;
1364    String mProfileFile;
1365    ParcelFileDescriptor mProfileFd;
1366    int mSamplingInterval = 0;
1367    boolean mAutoStopProfiler = false;
1368    int mProfileType = 0;
1369    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1370    String mMemWatchDumpProcName;
1371    String mMemWatchDumpFile;
1372    int mMemWatchDumpPid;
1373    int mMemWatchDumpUid;
1374    String mTrackAllocationApp = null;
1375    String mNativeDebuggingApp = null;
1376
1377    final long[] mTmpLong = new long[2];
1378
1379    static final class ProcessChangeItem {
1380        static final int CHANGE_ACTIVITIES = 1<<0;
1381        static final int CHANGE_PROCESS_STATE = 1<<1;
1382        int changes;
1383        int uid;
1384        int pid;
1385        int processState;
1386        boolean foregroundActivities;
1387    }
1388
1389    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1390    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1391
1392    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1393    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1394
1395    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1396    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1397
1398    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1399    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1400
1401    /**
1402     * Runtime CPU use collection thread.  This object's lock is used to
1403     * perform synchronization with the thread (notifying it to run).
1404     */
1405    final Thread mProcessCpuThread;
1406
1407    /**
1408     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1409     * Must acquire this object's lock when accessing it.
1410     * NOTE: this lock will be held while doing long operations (trawling
1411     * through all processes in /proc), so it should never be acquired by
1412     * any critical paths such as when holding the main activity manager lock.
1413     */
1414    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1415            MONITOR_THREAD_CPU_USAGE);
1416    final AtomicLong mLastCpuTime = new AtomicLong(0);
1417    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1418
1419    long mLastWriteTime = 0;
1420
1421    /**
1422     * Used to retain an update lock when the foreground activity is in
1423     * immersive mode.
1424     */
1425    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1426
1427    /**
1428     * Set to true after the system has finished booting.
1429     */
1430    boolean mBooted = false;
1431
1432    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1433    int mProcessLimitOverride = -1;
1434
1435    WindowManagerService mWindowManager;
1436    final ActivityThread mSystemThread;
1437
1438    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1439        final ProcessRecord mApp;
1440        final int mPid;
1441        final IApplicationThread mAppThread;
1442
1443        AppDeathRecipient(ProcessRecord app, int pid,
1444                IApplicationThread thread) {
1445            if (DEBUG_ALL) Slog.v(
1446                TAG, "New death recipient " + this
1447                + " for thread " + thread.asBinder());
1448            mApp = app;
1449            mPid = pid;
1450            mAppThread = thread;
1451        }
1452
1453        @Override
1454        public void binderDied() {
1455            if (DEBUG_ALL) Slog.v(
1456                TAG, "Death received in " + this
1457                + " for thread " + mAppThread.asBinder());
1458            synchronized(ActivityManagerService.this) {
1459                appDiedLocked(mApp, mPid, mAppThread, true);
1460            }
1461        }
1462    }
1463
1464    static final int SHOW_ERROR_UI_MSG = 1;
1465    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1466    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1467    static final int UPDATE_CONFIGURATION_MSG = 4;
1468    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1469    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1470    static final int SERVICE_TIMEOUT_MSG = 12;
1471    static final int UPDATE_TIME_ZONE = 13;
1472    static final int SHOW_UID_ERROR_UI_MSG = 14;
1473    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1474    static final int PROC_START_TIMEOUT_MSG = 20;
1475    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1476    static final int KILL_APPLICATION_MSG = 22;
1477    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1478    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1479    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1480    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1481    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1482    static final int CLEAR_DNS_CACHE_MSG = 28;
1483    static final int UPDATE_HTTP_PROXY_MSG = 29;
1484    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1485    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1486    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1487    static final int REPORT_MEM_USAGE_MSG = 33;
1488    static final int REPORT_USER_SWITCH_MSG = 34;
1489    static final int CONTINUE_USER_SWITCH_MSG = 35;
1490    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1491    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1492    static final int PERSIST_URI_GRANTS_MSG = 38;
1493    static final int REQUEST_ALL_PSS_MSG = 39;
1494    static final int START_PROFILES_MSG = 40;
1495    static final int UPDATE_TIME = 41;
1496    static final int SYSTEM_USER_START_MSG = 42;
1497    static final int SYSTEM_USER_CURRENT_MSG = 43;
1498    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1499    static final int FINISH_BOOTING_MSG = 45;
1500    static final int START_USER_SWITCH_UI_MSG = 46;
1501    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1502    static final int DISMISS_DIALOG_UI_MSG = 48;
1503    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1504    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1505    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1506    static final int DELETE_DUMPHEAP_MSG = 52;
1507    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1508    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1509    static final int REPORT_TIME_TRACKER_MSG = 55;
1510    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1511    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1512    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1513    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1514    static final int IDLE_UIDS_MSG = 60;
1515    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1516    static final int LOG_STACK_STATE = 62;
1517    static final int VR_MODE_CHANGE_MSG = 63;
1518    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1519    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1520    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1521    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1522    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1523    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1524    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1525
1526    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1527    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1528    static final int FIRST_COMPAT_MODE_MSG = 300;
1529    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1530
1531    static ServiceThread sKillThread = null;
1532    static KillHandler sKillHandler = null;
1533
1534    CompatModeDialog mCompatModeDialog;
1535    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1536    long mLastMemUsageReportTime = 0;
1537
1538    /**
1539     * Flag whether the current user is a "monkey", i.e. whether
1540     * the UI is driven by a UI automation tool.
1541     */
1542    private boolean mUserIsMonkey;
1543
1544    /** Flag whether the device has a Recents UI */
1545    boolean mHasRecents;
1546
1547    /** The dimensions of the thumbnails in the Recents UI. */
1548    int mThumbnailWidth;
1549    int mThumbnailHeight;
1550    float mFullscreenThumbnailScale;
1551
1552    final ServiceThread mHandlerThread;
1553    final MainHandler mHandler;
1554    final UiHandler mUiHandler;
1555
1556    PackageManagerInternal mPackageManagerInt;
1557
1558    // VoiceInteraction session ID that changes for each new request except when
1559    // being called for multiwindow assist in a single session.
1560    private int mViSessionId = 1000;
1561
1562    final class KillHandler extends Handler {
1563        static final int KILL_PROCESS_GROUP_MSG = 4000;
1564
1565        public KillHandler(Looper looper) {
1566            super(looper, null, true);
1567        }
1568
1569        @Override
1570        public void handleMessage(Message msg) {
1571            switch (msg.what) {
1572                case KILL_PROCESS_GROUP_MSG:
1573                {
1574                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1575                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1576                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1577                }
1578                break;
1579
1580                default:
1581                    super.handleMessage(msg);
1582            }
1583        }
1584    }
1585
1586    final class UiHandler extends Handler {
1587        public UiHandler() {
1588            super(com.android.server.UiThread.get().getLooper(), null, true);
1589        }
1590
1591        @Override
1592        public void handleMessage(Message msg) {
1593            switch (msg.what) {
1594            case SHOW_ERROR_UI_MSG: {
1595                mAppErrors.handleShowAppErrorUi(msg);
1596                ensureBootCompleted();
1597            } break;
1598            case SHOW_NOT_RESPONDING_UI_MSG: {
1599                mAppErrors.handleShowAnrUi(msg);
1600                ensureBootCompleted();
1601            } break;
1602            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1603                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1604                synchronized (ActivityManagerService.this) {
1605                    ProcessRecord proc = (ProcessRecord) data.get("app");
1606                    if (proc == null) {
1607                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1608                        break;
1609                    }
1610                    if (proc.crashDialog != null) {
1611                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1612                        return;
1613                    }
1614                    AppErrorResult res = (AppErrorResult) data.get("result");
1615                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1616                        Dialog d = new StrictModeViolationDialog(mContext,
1617                                ActivityManagerService.this, res, proc);
1618                        d.show();
1619                        proc.crashDialog = d;
1620                    } else {
1621                        // The device is asleep, so just pretend that the user
1622                        // saw a crash dialog and hit "force quit".
1623                        res.set(0);
1624                    }
1625                }
1626                ensureBootCompleted();
1627            } break;
1628            case SHOW_FACTORY_ERROR_UI_MSG: {
1629                Dialog d = new FactoryErrorDialog(
1630                    mContext, msg.getData().getCharSequence("msg"));
1631                d.show();
1632                ensureBootCompleted();
1633            } break;
1634            case WAIT_FOR_DEBUGGER_UI_MSG: {
1635                synchronized (ActivityManagerService.this) {
1636                    ProcessRecord app = (ProcessRecord)msg.obj;
1637                    if (msg.arg1 != 0) {
1638                        if (!app.waitedForDebugger) {
1639                            Dialog d = new AppWaitingForDebuggerDialog(
1640                                    ActivityManagerService.this,
1641                                    mContext, app);
1642                            app.waitDialog = d;
1643                            app.waitedForDebugger = true;
1644                            d.show();
1645                        }
1646                    } else {
1647                        if (app.waitDialog != null) {
1648                            app.waitDialog.dismiss();
1649                            app.waitDialog = null;
1650                        }
1651                    }
1652                }
1653            } break;
1654            case SHOW_UID_ERROR_UI_MSG: {
1655                if (mShowDialogs) {
1656                    AlertDialog d = new BaseErrorDialog(mContext);
1657                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1658                    d.setCancelable(false);
1659                    d.setTitle(mContext.getText(R.string.android_system_label));
1660                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1661                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1662                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1663                    d.show();
1664                }
1665            } break;
1666            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1667                if (mShowDialogs) {
1668                    AlertDialog d = new BaseErrorDialog(mContext);
1669                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1670                    d.setCancelable(false);
1671                    d.setTitle(mContext.getText(R.string.android_system_label));
1672                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1673                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1674                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1675                    d.show();
1676                }
1677            } break;
1678            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1679                synchronized (ActivityManagerService.this) {
1680                    ActivityRecord ar = (ActivityRecord) msg.obj;
1681                    if (mCompatModeDialog != null) {
1682                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1683                                ar.info.applicationInfo.packageName)) {
1684                            return;
1685                        }
1686                        mCompatModeDialog.dismiss();
1687                        mCompatModeDialog = null;
1688                    }
1689                    if (ar != null && false) {
1690                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1691                                ar.packageName)) {
1692                            int mode = mCompatModePackages.computeCompatModeLocked(
1693                                    ar.info.applicationInfo);
1694                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1695                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1696                                mCompatModeDialog = new CompatModeDialog(
1697                                        ActivityManagerService.this, mContext,
1698                                        ar.info.applicationInfo);
1699                                mCompatModeDialog.show();
1700                            }
1701                        }
1702                    }
1703                }
1704                break;
1705            }
1706            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1707                synchronized (ActivityManagerService.this) {
1708                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1709                    if (mUnsupportedDisplaySizeDialog != null) {
1710                        mUnsupportedDisplaySizeDialog.dismiss();
1711                        mUnsupportedDisplaySizeDialog = null;
1712                    }
1713                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1714                            ar.packageName)) {
1715                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1716                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1717                        mUnsupportedDisplaySizeDialog.show();
1718                    }
1719                }
1720                break;
1721            }
1722            case START_USER_SWITCH_UI_MSG: {
1723                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1724                break;
1725            }
1726            case DISMISS_DIALOG_UI_MSG: {
1727                final Dialog d = (Dialog) msg.obj;
1728                d.dismiss();
1729                break;
1730            }
1731            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1732                dispatchProcessesChanged();
1733                break;
1734            }
1735            case DISPATCH_PROCESS_DIED_UI_MSG: {
1736                final int pid = msg.arg1;
1737                final int uid = msg.arg2;
1738                dispatchProcessDied(pid, uid);
1739                break;
1740            }
1741            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1742                dispatchUidsChanged();
1743            } break;
1744            }
1745        }
1746    }
1747
1748    final class MainHandler extends Handler {
1749        public MainHandler(Looper looper) {
1750            super(looper, null, true);
1751        }
1752
1753        @Override
1754        public void handleMessage(Message msg) {
1755            switch (msg.what) {
1756            case UPDATE_CONFIGURATION_MSG: {
1757                final ContentResolver resolver = mContext.getContentResolver();
1758                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1759                        msg.arg1);
1760            } break;
1761            case GC_BACKGROUND_PROCESSES_MSG: {
1762                synchronized (ActivityManagerService.this) {
1763                    performAppGcsIfAppropriateLocked();
1764                }
1765            } break;
1766            case SERVICE_TIMEOUT_MSG: {
1767                if (mDidDexOpt) {
1768                    mDidDexOpt = false;
1769                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1770                    nmsg.obj = msg.obj;
1771                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1772                    return;
1773                }
1774                mServices.serviceTimeout((ProcessRecord)msg.obj);
1775            } break;
1776            case UPDATE_TIME_ZONE: {
1777                synchronized (ActivityManagerService.this) {
1778                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1779                        ProcessRecord r = mLruProcesses.get(i);
1780                        if (r.thread != null) {
1781                            try {
1782                                r.thread.updateTimeZone();
1783                            } catch (RemoteException ex) {
1784                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1785                            }
1786                        }
1787                    }
1788                }
1789            } break;
1790            case CLEAR_DNS_CACHE_MSG: {
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.clearDnsCache();
1797                            } catch (RemoteException ex) {
1798                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1799                            }
1800                        }
1801                    }
1802                }
1803            } break;
1804            case UPDATE_HTTP_PROXY_MSG: {
1805                ProxyInfo proxy = (ProxyInfo)msg.obj;
1806                String host = "";
1807                String port = "";
1808                String exclList = "";
1809                Uri pacFileUrl = Uri.EMPTY;
1810                if (proxy != null) {
1811                    host = proxy.getHost();
1812                    port = Integer.toString(proxy.getPort());
1813                    exclList = proxy.getExclusionListAsString();
1814                    pacFileUrl = proxy.getPacFileUrl();
1815                }
1816                synchronized (ActivityManagerService.this) {
1817                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1818                        ProcessRecord r = mLruProcesses.get(i);
1819                        if (r.thread != null) {
1820                            try {
1821                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1822                            } catch (RemoteException ex) {
1823                                Slog.w(TAG, "Failed to update http proxy for: " +
1824                                        r.info.processName);
1825                            }
1826                        }
1827                    }
1828                }
1829            } break;
1830            case PROC_START_TIMEOUT_MSG: {
1831                if (mDidDexOpt) {
1832                    mDidDexOpt = false;
1833                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1834                    nmsg.obj = msg.obj;
1835                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1836                    return;
1837                }
1838                ProcessRecord app = (ProcessRecord)msg.obj;
1839                synchronized (ActivityManagerService.this) {
1840                    processStartTimedOutLocked(app);
1841                }
1842            } break;
1843            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1844                ProcessRecord app = (ProcessRecord)msg.obj;
1845                synchronized (ActivityManagerService.this) {
1846                    processContentProviderPublishTimedOutLocked(app);
1847                }
1848            } break;
1849            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1850                synchronized (ActivityManagerService.this) {
1851                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1852                }
1853            } break;
1854            case KILL_APPLICATION_MSG: {
1855                synchronized (ActivityManagerService.this) {
1856                    final int appId = msg.arg1;
1857                    final int userId = msg.arg2;
1858                    Bundle bundle = (Bundle)msg.obj;
1859                    String pkg = bundle.getString("pkg");
1860                    String reason = bundle.getString("reason");
1861                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1862                            false, userId, reason);
1863                }
1864            } break;
1865            case FINALIZE_PENDING_INTENT_MSG: {
1866                ((PendingIntentRecord)msg.obj).completeFinalize();
1867            } break;
1868            case POST_HEAVY_NOTIFICATION_MSG: {
1869                INotificationManager inm = NotificationManager.getService();
1870                if (inm == null) {
1871                    return;
1872                }
1873
1874                ActivityRecord root = (ActivityRecord)msg.obj;
1875                ProcessRecord process = root.app;
1876                if (process == null) {
1877                    return;
1878                }
1879
1880                try {
1881                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1882                    String text = mContext.getString(R.string.heavy_weight_notification,
1883                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1884                    Notification notification = new Notification.Builder(context)
1885                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1886                            .setWhen(0)
1887                            .setOngoing(true)
1888                            .setTicker(text)
1889                            .setColor(mContext.getColor(
1890                                    com.android.internal.R.color.system_notification_accent_color))
1891                            .setContentTitle(text)
1892                            .setContentText(
1893                                    mContext.getText(R.string.heavy_weight_notification_detail))
1894                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1895                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1896                                    new UserHandle(root.userId)))
1897                            .build();
1898                    try {
1899                        int[] outId = new int[1];
1900                        inm.enqueueNotificationWithTag("android", "android", null,
1901                                R.string.heavy_weight_notification,
1902                                notification, outId, root.userId);
1903                    } catch (RuntimeException e) {
1904                        Slog.w(ActivityManagerService.TAG,
1905                                "Error showing notification for heavy-weight app", e);
1906                    } catch (RemoteException e) {
1907                    }
1908                } catch (NameNotFoundException e) {
1909                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1910                }
1911            } break;
1912            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1913                INotificationManager inm = NotificationManager.getService();
1914                if (inm == null) {
1915                    return;
1916                }
1917                try {
1918                    inm.cancelNotificationWithTag("android", null,
1919                            R.string.heavy_weight_notification,  msg.arg1);
1920                } catch (RuntimeException e) {
1921                    Slog.w(ActivityManagerService.TAG,
1922                            "Error canceling notification for service", e);
1923                } catch (RemoteException e) {
1924                }
1925            } break;
1926            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1927                synchronized (ActivityManagerService.this) {
1928                    checkExcessivePowerUsageLocked(true);
1929                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1930                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1931                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1932                }
1933            } break;
1934            case REPORT_MEM_USAGE_MSG: {
1935                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1936                Thread thread = new Thread() {
1937                    @Override public void run() {
1938                        reportMemUsage(memInfos);
1939                    }
1940                };
1941                thread.start();
1942                break;
1943            }
1944            case REPORT_USER_SWITCH_MSG: {
1945                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1946                break;
1947            }
1948            case CONTINUE_USER_SWITCH_MSG: {
1949                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1950                break;
1951            }
1952            case USER_SWITCH_TIMEOUT_MSG: {
1953                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1954                break;
1955            }
1956            case IMMERSIVE_MODE_LOCK_MSG: {
1957                final boolean nextState = (msg.arg1 != 0);
1958                if (mUpdateLock.isHeld() != nextState) {
1959                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1960                            "Applying new update lock state '" + nextState
1961                            + "' for " + (ActivityRecord)msg.obj);
1962                    if (nextState) {
1963                        mUpdateLock.acquire();
1964                    } else {
1965                        mUpdateLock.release();
1966                    }
1967                }
1968                break;
1969            }
1970            case PERSIST_URI_GRANTS_MSG: {
1971                writeGrantedUriPermissions();
1972                break;
1973            }
1974            case REQUEST_ALL_PSS_MSG: {
1975                synchronized (ActivityManagerService.this) {
1976                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1977                }
1978                break;
1979            }
1980            case START_PROFILES_MSG: {
1981                synchronized (ActivityManagerService.this) {
1982                    mUserController.startProfilesLocked();
1983                }
1984                break;
1985            }
1986            case UPDATE_TIME: {
1987                synchronized (ActivityManagerService.this) {
1988                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1989                        ProcessRecord r = mLruProcesses.get(i);
1990                        if (r.thread != null) {
1991                            try {
1992                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1993                            } catch (RemoteException ex) {
1994                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1995                            }
1996                        }
1997                    }
1998                }
1999                break;
2000            }
2001            case SYSTEM_USER_START_MSG: {
2002                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2003                        Integer.toString(msg.arg1), msg.arg1);
2004                mSystemServiceManager.startUser(msg.arg1);
2005                break;
2006            }
2007            case SYSTEM_USER_UNLOCK_MSG: {
2008                final int userId = msg.arg1;
2009                mSystemServiceManager.unlockUser(userId);
2010                synchronized (ActivityManagerService.this) {
2011                    mRecentTasks.loadUserRecentsLocked(userId);
2012                }
2013                if (userId == UserHandle.USER_SYSTEM) {
2014                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2015                }
2016                installEncryptionUnawareProviders(userId);
2017                mUserController.finishUserUnlocked((UserState) msg.obj);
2018                break;
2019            }
2020            case SYSTEM_USER_CURRENT_MSG: {
2021                mBatteryStatsService.noteEvent(
2022                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2023                        Integer.toString(msg.arg2), msg.arg2);
2024                mBatteryStatsService.noteEvent(
2025                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2026                        Integer.toString(msg.arg1), msg.arg1);
2027                mSystemServiceManager.switchUser(msg.arg1);
2028                break;
2029            }
2030            case ENTER_ANIMATION_COMPLETE_MSG: {
2031                synchronized (ActivityManagerService.this) {
2032                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2033                    if (r != null && r.app != null && r.app.thread != null) {
2034                        try {
2035                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2036                        } catch (RemoteException e) {
2037                        }
2038                    }
2039                }
2040                break;
2041            }
2042            case FINISH_BOOTING_MSG: {
2043                if (msg.arg1 != 0) {
2044                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2045                    finishBooting();
2046                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2047                }
2048                if (msg.arg2 != 0) {
2049                    enableScreenAfterBoot();
2050                }
2051                break;
2052            }
2053            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2054                try {
2055                    Locale l = (Locale) msg.obj;
2056                    IBinder service = ServiceManager.getService("mount");
2057                    IMountService mountService = IMountService.Stub.asInterface(service);
2058                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2059                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2060                } catch (RemoteException e) {
2061                    Log.e(TAG, "Error storing locale for decryption UI", e);
2062                }
2063                break;
2064            }
2065            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2066                synchronized (ActivityManagerService.this) {
2067                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2068                        try {
2069                            // Make a one-way callback to the listener
2070                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2071                        } catch (RemoteException e){
2072                            // Handled by the RemoteCallbackList
2073                        }
2074                    }
2075                    mTaskStackListeners.finishBroadcast();
2076                }
2077                break;
2078            }
2079            case NOTIFY_ACTIVITY_PINNED_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).onActivityPinned();
2085                        } catch (RemoteException e){
2086                            // Handled by the RemoteCallbackList
2087                        }
2088                    }
2089                    mTaskStackListeners.finishBroadcast();
2090                }
2091                break;
2092            }
2093            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_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).onPinnedActivityRestartAttempt();
2099                        } catch (RemoteException e){
2100                            // Handled by the RemoteCallbackList
2101                        }
2102                    }
2103                    mTaskStackListeners.finishBroadcast();
2104                }
2105                break;
2106            }
2107            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_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).onPinnedStackAnimationEnded();
2113                        } catch (RemoteException e){
2114                            // Handled by the RemoteCallbackList
2115                        }
2116                    }
2117                    mTaskStackListeners.finishBroadcast();
2118                }
2119                break;
2120            }
2121            case NOTIFY_FORCED_RESIZABLE_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).onActivityForcedResizable(
2127                                    (String) msg.obj, msg.arg1);
2128                        } catch (RemoteException e){
2129                            // Handled by the RemoteCallbackList
2130                        }
2131                    }
2132                    mTaskStackListeners.finishBroadcast();
2133                }
2134                break;
2135            }
2136                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2137                    synchronized (ActivityManagerService.this) {
2138                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2139                            try {
2140                                // Make a one-way callback to the listener
2141                                mTaskStackListeners.getBroadcastItem(i)
2142                                        .onActivityDismissingDockedStack();
2143                            } catch (RemoteException e){
2144                                // Handled by the RemoteCallbackList
2145                            }
2146                        }
2147                        mTaskStackListeners.finishBroadcast();
2148                    }
2149                    break;
2150                }
2151            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2152                final int uid = msg.arg1;
2153                final byte[] firstPacket = (byte[]) msg.obj;
2154
2155                synchronized (mPidsSelfLocked) {
2156                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2157                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2158                        if (p.uid == uid) {
2159                            try {
2160                                p.thread.notifyCleartextNetwork(firstPacket);
2161                            } catch (RemoteException ignored) {
2162                            }
2163                        }
2164                    }
2165                }
2166                break;
2167            }
2168            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2169                final String procName;
2170                final int uid;
2171                final long memLimit;
2172                final String reportPackage;
2173                synchronized (ActivityManagerService.this) {
2174                    procName = mMemWatchDumpProcName;
2175                    uid = mMemWatchDumpUid;
2176                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2177                    if (val == null) {
2178                        val = mMemWatchProcesses.get(procName, 0);
2179                    }
2180                    if (val != null) {
2181                        memLimit = val.first;
2182                        reportPackage = val.second;
2183                    } else {
2184                        memLimit = 0;
2185                        reportPackage = null;
2186                    }
2187                }
2188                if (procName == null) {
2189                    return;
2190                }
2191
2192                if (DEBUG_PSS) Slog.d(TAG_PSS,
2193                        "Showing dump heap notification from " + procName + "/" + uid);
2194
2195                INotificationManager inm = NotificationManager.getService();
2196                if (inm == null) {
2197                    return;
2198                }
2199
2200                String text = mContext.getString(R.string.dump_heap_notification, procName);
2201
2202
2203                Intent deleteIntent = new Intent();
2204                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2205                Intent intent = new Intent();
2206                intent.setClassName("android", DumpHeapActivity.class.getName());
2207                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2208                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2209                if (reportPackage != null) {
2210                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2211                }
2212                int userId = UserHandle.getUserId(uid);
2213                Notification notification = new Notification.Builder(mContext)
2214                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2215                        .setWhen(0)
2216                        .setOngoing(true)
2217                        .setAutoCancel(true)
2218                        .setTicker(text)
2219                        .setColor(mContext.getColor(
2220                                com.android.internal.R.color.system_notification_accent_color))
2221                        .setContentTitle(text)
2222                        .setContentText(
2223                                mContext.getText(R.string.dump_heap_notification_detail))
2224                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2225                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2226                                new UserHandle(userId)))
2227                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2228                                deleteIntent, 0, UserHandle.SYSTEM))
2229                        .build();
2230
2231                try {
2232                    int[] outId = new int[1];
2233                    inm.enqueueNotificationWithTag("android", "android", null,
2234                            R.string.dump_heap_notification,
2235                            notification, outId, userId);
2236                } catch (RuntimeException e) {
2237                    Slog.w(ActivityManagerService.TAG,
2238                            "Error showing notification for dump heap", e);
2239                } catch (RemoteException e) {
2240                }
2241            } break;
2242            case DELETE_DUMPHEAP_MSG: {
2243                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2244                        DumpHeapActivity.JAVA_URI,
2245                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2246                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2247                        UserHandle.myUserId());
2248                synchronized (ActivityManagerService.this) {
2249                    mMemWatchDumpFile = null;
2250                    mMemWatchDumpProcName = null;
2251                    mMemWatchDumpPid = -1;
2252                    mMemWatchDumpUid = -1;
2253                }
2254            } break;
2255            case FOREGROUND_PROFILE_CHANGED_MSG: {
2256                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2257            } break;
2258            case REPORT_TIME_TRACKER_MSG: {
2259                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2260                tracker.deliverResult(mContext);
2261            } break;
2262            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2263                mUserController.dispatchUserSwitchComplete(msg.arg1);
2264            } break;
2265            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2266                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2267                try {
2268                    connection.shutdown();
2269                } catch (RemoteException e) {
2270                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2271                }
2272                // Only a UiAutomation can set this flag and now that
2273                // it is finished we make sure it is reset to its default.
2274                mUserIsMonkey = false;
2275            } break;
2276            case APP_BOOST_DEACTIVATE_MSG: {
2277                synchronized(ActivityManagerService.this) {
2278                    if (mIsBoosted) {
2279                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2280                            nativeMigrateFromBoost();
2281                            mIsBoosted = false;
2282                            mBoostStartTime = 0;
2283                        } else {
2284                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2285                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2286                        }
2287                    }
2288                }
2289            } break;
2290            case IDLE_UIDS_MSG: {
2291                idleUids();
2292            } break;
2293            case LOG_STACK_STATE: {
2294                synchronized (ActivityManagerService.this) {
2295                    mStackSupervisor.logStackState();
2296                }
2297            } break;
2298            case VR_MODE_CHANGE_MSG: {
2299                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2300                final ActivityRecord r = (ActivityRecord) msg.obj;
2301                boolean vrMode;
2302                ComponentName requestedPackage;
2303                ComponentName callingPackage;
2304                int userId;
2305                synchronized (ActivityManagerService.this) {
2306                    vrMode = r.requestedVrComponent != null;
2307                    requestedPackage = r.requestedVrComponent;
2308                    userId = r.userId;
2309                    callingPackage = r.info.getComponentName();
2310                    if (mInVrMode != vrMode) {
2311                        mInVrMode = vrMode;
2312                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2313                        if (r.app != null) {
2314                            ProcessRecord proc = r.app;
2315                            if (proc.vrThreadTid > 0) {
2316                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2317                                    if (mInVrMode == true) {
2318                                        Process.setThreadScheduler(proc.vrThreadTid,
2319                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2320                                    } else {
2321                                        Process.setThreadScheduler(proc.vrThreadTid,
2322                                            Process.SCHED_OTHER, 0);
2323                                    }
2324                                }
2325                            }
2326                        }
2327                    }
2328                }
2329                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2330            } break;
2331            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2332                final ActivityRecord r = (ActivityRecord) msg.obj;
2333                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2334                if (needsVrMode) {
2335                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2336                            r.info.getComponentName(), false);
2337                }
2338            } break;
2339            }
2340        }
2341    };
2342
2343    static final int COLLECT_PSS_BG_MSG = 1;
2344
2345    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2346        @Override
2347        public void handleMessage(Message msg) {
2348            switch (msg.what) {
2349            case COLLECT_PSS_BG_MSG: {
2350                long start = SystemClock.uptimeMillis();
2351                MemInfoReader memInfo = null;
2352                synchronized (ActivityManagerService.this) {
2353                    if (mFullPssPending) {
2354                        mFullPssPending = false;
2355                        memInfo = new MemInfoReader();
2356                    }
2357                }
2358                if (memInfo != null) {
2359                    updateCpuStatsNow();
2360                    long nativeTotalPss = 0;
2361                    synchronized (mProcessCpuTracker) {
2362                        final int N = mProcessCpuTracker.countStats();
2363                        for (int j=0; j<N; j++) {
2364                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2365                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2366                                // This is definitely an application process; skip it.
2367                                continue;
2368                            }
2369                            synchronized (mPidsSelfLocked) {
2370                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2371                                    // This is one of our own processes; skip it.
2372                                    continue;
2373                                }
2374                            }
2375                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2376                        }
2377                    }
2378                    memInfo.readMemInfo();
2379                    synchronized (ActivityManagerService.this) {
2380                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2381                                + (SystemClock.uptimeMillis()-start) + "ms");
2382                        final long cachedKb = memInfo.getCachedSizeKb();
2383                        final long freeKb = memInfo.getFreeSizeKb();
2384                        final long zramKb = memInfo.getZramTotalSizeKb();
2385                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2386                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2387                                kernelKb*1024, nativeTotalPss*1024);
2388                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2389                                nativeTotalPss);
2390                    }
2391                }
2392
2393                int num = 0;
2394                long[] tmp = new long[2];
2395                do {
2396                    ProcessRecord proc;
2397                    int procState;
2398                    int pid;
2399                    long lastPssTime;
2400                    synchronized (ActivityManagerService.this) {
2401                        if (mPendingPssProcesses.size() <= 0) {
2402                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2403                                    "Collected PSS of " + num + " processes in "
2404                                    + (SystemClock.uptimeMillis() - start) + "ms");
2405                            mPendingPssProcesses.clear();
2406                            return;
2407                        }
2408                        proc = mPendingPssProcesses.remove(0);
2409                        procState = proc.pssProcState;
2410                        lastPssTime = proc.lastPssTime;
2411                        if (proc.thread != null && procState == proc.setProcState
2412                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2413                                        < SystemClock.uptimeMillis()) {
2414                            pid = proc.pid;
2415                        } else {
2416                            proc = null;
2417                            pid = 0;
2418                        }
2419                    }
2420                    if (proc != null) {
2421                        long pss = Debug.getPss(pid, tmp, null);
2422                        synchronized (ActivityManagerService.this) {
2423                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2424                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2425                                num++;
2426                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2427                                        SystemClock.uptimeMillis());
2428                            }
2429                        }
2430                    }
2431                } while (true);
2432            }
2433            }
2434        }
2435    };
2436
2437    public void setSystemProcess() {
2438        try {
2439            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2440            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2441            ServiceManager.addService("meminfo", new MemBinder(this));
2442            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2443            ServiceManager.addService("dbinfo", new DbBinder(this));
2444            if (MONITOR_CPU_USAGE) {
2445                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2446            }
2447            ServiceManager.addService("permission", new PermissionController(this));
2448            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2449
2450            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2451                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2452            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2453
2454            synchronized (this) {
2455                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2456                app.persistent = true;
2457                app.pid = MY_PID;
2458                app.maxAdj = ProcessList.SYSTEM_ADJ;
2459                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2460                synchronized (mPidsSelfLocked) {
2461                    mPidsSelfLocked.put(app.pid, app);
2462                }
2463                updateLruProcessLocked(app, false, null);
2464                updateOomAdjLocked();
2465            }
2466        } catch (PackageManager.NameNotFoundException e) {
2467            throw new RuntimeException(
2468                    "Unable to find android system package", e);
2469        }
2470    }
2471
2472    public void setWindowManager(WindowManagerService wm) {
2473        mWindowManager = wm;
2474        mStackSupervisor.setWindowManager(wm);
2475        mActivityStarter.setWindowManager(wm);
2476    }
2477
2478    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2479        mUsageStatsService = usageStatsManager;
2480    }
2481
2482    public void startObservingNativeCrashes() {
2483        final NativeCrashListener ncl = new NativeCrashListener(this);
2484        ncl.start();
2485    }
2486
2487    public IAppOpsService getAppOpsService() {
2488        return mAppOpsService;
2489    }
2490
2491    static class MemBinder extends Binder {
2492        ActivityManagerService mActivityManagerService;
2493        MemBinder(ActivityManagerService activityManagerService) {
2494            mActivityManagerService = activityManagerService;
2495        }
2496
2497        @Override
2498        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2499            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2500                    != PackageManager.PERMISSION_GRANTED) {
2501                pw.println("Permission Denial: can't dump meminfo from from pid="
2502                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2503                        + " without permission " + android.Manifest.permission.DUMP);
2504                return;
2505            }
2506
2507            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2508        }
2509    }
2510
2511    static class GraphicsBinder extends Binder {
2512        ActivityManagerService mActivityManagerService;
2513        GraphicsBinder(ActivityManagerService activityManagerService) {
2514            mActivityManagerService = activityManagerService;
2515        }
2516
2517        @Override
2518        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2519            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2520                    != PackageManager.PERMISSION_GRANTED) {
2521                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2522                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2523                        + " without permission " + android.Manifest.permission.DUMP);
2524                return;
2525            }
2526
2527            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2528        }
2529    }
2530
2531    static class DbBinder extends Binder {
2532        ActivityManagerService mActivityManagerService;
2533        DbBinder(ActivityManagerService activityManagerService) {
2534            mActivityManagerService = activityManagerService;
2535        }
2536
2537        @Override
2538        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2539            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2540                    != PackageManager.PERMISSION_GRANTED) {
2541                pw.println("Permission Denial: can't dump dbinfo from from pid="
2542                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2543                        + " without permission " + android.Manifest.permission.DUMP);
2544                return;
2545            }
2546
2547            mActivityManagerService.dumpDbInfo(fd, pw, args);
2548        }
2549    }
2550
2551    static class CpuBinder extends Binder {
2552        ActivityManagerService mActivityManagerService;
2553        CpuBinder(ActivityManagerService activityManagerService) {
2554            mActivityManagerService = activityManagerService;
2555        }
2556
2557        @Override
2558        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2559            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2560                    != PackageManager.PERMISSION_GRANTED) {
2561                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2562                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2563                        + " without permission " + android.Manifest.permission.DUMP);
2564                return;
2565            }
2566
2567            synchronized (mActivityManagerService.mProcessCpuTracker) {
2568                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2569                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2570                        SystemClock.uptimeMillis()));
2571            }
2572        }
2573    }
2574
2575    public static final class Lifecycle extends SystemService {
2576        private final ActivityManagerService mService;
2577
2578        public Lifecycle(Context context) {
2579            super(context);
2580            mService = new ActivityManagerService(context);
2581        }
2582
2583        @Override
2584        public void onStart() {
2585            mService.start();
2586        }
2587
2588        public ActivityManagerService getService() {
2589            return mService;
2590        }
2591    }
2592
2593    // Note: This method is invoked on the main thread but may need to attach various
2594    // handlers to other threads.  So take care to be explicit about the looper.
2595    public ActivityManagerService(Context systemContext) {
2596        mContext = systemContext;
2597        mFactoryTest = FactoryTest.getMode();
2598        mSystemThread = ActivityThread.currentActivityThread();
2599
2600        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2601
2602        mHandlerThread = new ServiceThread(TAG,
2603                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2604        mHandlerThread.start();
2605        mHandler = new MainHandler(mHandlerThread.getLooper());
2606        mUiHandler = new UiHandler();
2607
2608        /* static; one-time init here */
2609        if (sKillHandler == null) {
2610            sKillThread = new ServiceThread(TAG + ":kill",
2611                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2612            sKillThread.start();
2613            sKillHandler = new KillHandler(sKillThread.getLooper());
2614        }
2615
2616        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2617                "foreground", BROADCAST_FG_TIMEOUT, false);
2618        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2619                "background", BROADCAST_BG_TIMEOUT, true);
2620        mBroadcastQueues[0] = mFgBroadcastQueue;
2621        mBroadcastQueues[1] = mBgBroadcastQueue;
2622
2623        mServices = new ActiveServices(this);
2624        mProviderMap = new ProviderMap(this);
2625        mAppErrors = new AppErrors(mContext, this);
2626
2627        // TODO: Move creation of battery stats service outside of activity manager service.
2628        File dataDir = Environment.getDataDirectory();
2629        File systemDir = new File(dataDir, "system");
2630        systemDir.mkdirs();
2631        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2632        mBatteryStatsService.getActiveStatistics().readLocked();
2633        mBatteryStatsService.scheduleWriteToDisk();
2634        mOnBattery = DEBUG_POWER ? true
2635                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2636        mBatteryStatsService.getActiveStatistics().setCallback(this);
2637
2638        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2639
2640        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2641        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2642                new IAppOpsCallback.Stub() {
2643                    @Override public void opChanged(int op, int uid, String packageName) {
2644                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2645                            if (mAppOpsService.checkOperation(op, uid, packageName)
2646                                    != AppOpsManager.MODE_ALLOWED) {
2647                                runInBackgroundDisabled(uid);
2648                            }
2649                        }
2650                    }
2651                });
2652
2653        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2654
2655        mUserController = new UserController(this);
2656
2657        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2658            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2659
2660        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2661
2662        mConfiguration.setToDefaults();
2663        mConfiguration.setLocales(LocaleList.getDefault());
2664
2665        mConfigurationSeq = mConfiguration.seq = 1;
2666        mProcessCpuTracker.init();
2667
2668        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2669        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2670        mStackSupervisor = new ActivityStackSupervisor(this);
2671        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2672        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2673
2674        mProcessCpuThread = new Thread("CpuTracker") {
2675            @Override
2676            public void run() {
2677                while (true) {
2678                    try {
2679                        try {
2680                            synchronized(this) {
2681                                final long now = SystemClock.uptimeMillis();
2682                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2683                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2684                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2685                                //        + ", write delay=" + nextWriteDelay);
2686                                if (nextWriteDelay < nextCpuDelay) {
2687                                    nextCpuDelay = nextWriteDelay;
2688                                }
2689                                if (nextCpuDelay > 0) {
2690                                    mProcessCpuMutexFree.set(true);
2691                                    this.wait(nextCpuDelay);
2692                                }
2693                            }
2694                        } catch (InterruptedException e) {
2695                        }
2696                        updateCpuStatsNow();
2697                    } catch (Exception e) {
2698                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2699                    }
2700                }
2701            }
2702        };
2703
2704        Watchdog.getInstance().addMonitor(this);
2705        Watchdog.getInstance().addThread(mHandler);
2706    }
2707
2708    public void setSystemServiceManager(SystemServiceManager mgr) {
2709        mSystemServiceManager = mgr;
2710    }
2711
2712    public void setInstaller(Installer installer) {
2713        mInstaller = installer;
2714    }
2715
2716    private void start() {
2717        Process.removeAllProcessGroups();
2718        mProcessCpuThread.start();
2719
2720        mBatteryStatsService.publish(mContext);
2721        mAppOpsService.publish(mContext);
2722        Slog.d("AppOps", "AppOpsService published");
2723        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2724    }
2725
2726    void onUserStoppedLocked(int userId) {
2727        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2728    }
2729
2730    public void initPowerManagement() {
2731        mStackSupervisor.initPowerManagement();
2732        mBatteryStatsService.initPowerManagement();
2733        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2734        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2735        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2736        mVoiceWakeLock.setReferenceCounted(false);
2737    }
2738
2739    @Override
2740    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2741            throws RemoteException {
2742        if (code == SYSPROPS_TRANSACTION) {
2743            // We need to tell all apps about the system property change.
2744            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2745            synchronized(this) {
2746                final int NP = mProcessNames.getMap().size();
2747                for (int ip=0; ip<NP; ip++) {
2748                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2749                    final int NA = apps.size();
2750                    for (int ia=0; ia<NA; ia++) {
2751                        ProcessRecord app = apps.valueAt(ia);
2752                        if (app.thread != null) {
2753                            procs.add(app.thread.asBinder());
2754                        }
2755                    }
2756                }
2757            }
2758
2759            int N = procs.size();
2760            for (int i=0; i<N; i++) {
2761                Parcel data2 = Parcel.obtain();
2762                try {
2763                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2764                } catch (RemoteException e) {
2765                }
2766                data2.recycle();
2767            }
2768        }
2769        try {
2770            return super.onTransact(code, data, reply, flags);
2771        } catch (RuntimeException e) {
2772            // The activity manager only throws security exceptions, so let's
2773            // log all others.
2774            if (!(e instanceof SecurityException)) {
2775                Slog.wtf(TAG, "Activity Manager Crash", e);
2776            }
2777            throw e;
2778        }
2779    }
2780
2781    void updateCpuStats() {
2782        final long now = SystemClock.uptimeMillis();
2783        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2784            return;
2785        }
2786        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2787            synchronized (mProcessCpuThread) {
2788                mProcessCpuThread.notify();
2789            }
2790        }
2791    }
2792
2793    void updateCpuStatsNow() {
2794        synchronized (mProcessCpuTracker) {
2795            mProcessCpuMutexFree.set(false);
2796            final long now = SystemClock.uptimeMillis();
2797            boolean haveNewCpuStats = false;
2798
2799            if (MONITOR_CPU_USAGE &&
2800                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2801                mLastCpuTime.set(now);
2802                mProcessCpuTracker.update();
2803                if (mProcessCpuTracker.hasGoodLastStats()) {
2804                    haveNewCpuStats = true;
2805                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2806                    //Slog.i(TAG, "Total CPU usage: "
2807                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2808
2809                    // Slog the cpu usage if the property is set.
2810                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2811                        int user = mProcessCpuTracker.getLastUserTime();
2812                        int system = mProcessCpuTracker.getLastSystemTime();
2813                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2814                        int irq = mProcessCpuTracker.getLastIrqTime();
2815                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2816                        int idle = mProcessCpuTracker.getLastIdleTime();
2817
2818                        int total = user + system + iowait + irq + softIrq + idle;
2819                        if (total == 0) total = 1;
2820
2821                        EventLog.writeEvent(EventLogTags.CPU,
2822                                ((user+system+iowait+irq+softIrq) * 100) / total,
2823                                (user * 100) / total,
2824                                (system * 100) / total,
2825                                (iowait * 100) / total,
2826                                (irq * 100) / total,
2827                                (softIrq * 100) / total);
2828                    }
2829                }
2830            }
2831
2832            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2833            synchronized(bstats) {
2834                synchronized(mPidsSelfLocked) {
2835                    if (haveNewCpuStats) {
2836                        if (bstats.startAddingCpuLocked()) {
2837                            int totalUTime = 0;
2838                            int totalSTime = 0;
2839                            final int N = mProcessCpuTracker.countStats();
2840                            for (int i=0; i<N; i++) {
2841                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2842                                if (!st.working) {
2843                                    continue;
2844                                }
2845                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2846                                totalUTime += st.rel_utime;
2847                                totalSTime += st.rel_stime;
2848                                if (pr != null) {
2849                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2850                                    if (ps == null || !ps.isActive()) {
2851                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2852                                                pr.info.uid, pr.processName);
2853                                    }
2854                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2855                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2856                                } else {
2857                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2858                                    if (ps == null || !ps.isActive()) {
2859                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2860                                                bstats.mapUid(st.uid), st.name);
2861                                    }
2862                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2863                                }
2864                            }
2865                            final int userTime = mProcessCpuTracker.getLastUserTime();
2866                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2867                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2868                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2869                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2870                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2871                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2872                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2873                        }
2874                    }
2875                }
2876
2877                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2878                    mLastWriteTime = now;
2879                    mBatteryStatsService.scheduleWriteToDisk();
2880                }
2881            }
2882        }
2883    }
2884
2885    @Override
2886    public void batteryNeedsCpuUpdate() {
2887        updateCpuStatsNow();
2888    }
2889
2890    @Override
2891    public void batteryPowerChanged(boolean onBattery) {
2892        // When plugging in, update the CPU stats first before changing
2893        // the plug state.
2894        updateCpuStatsNow();
2895        synchronized (this) {
2896            synchronized(mPidsSelfLocked) {
2897                mOnBattery = DEBUG_POWER ? true : onBattery;
2898            }
2899        }
2900    }
2901
2902    @Override
2903    public void batterySendBroadcast(Intent intent) {
2904        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2905                AppOpsManager.OP_NONE, null, false, false,
2906                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2907    }
2908
2909    /**
2910     * Initialize the application bind args. These are passed to each
2911     * process when the bindApplication() IPC is sent to the process. They're
2912     * lazily setup to make sure the services are running when they're asked for.
2913     */
2914    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2915        if (mAppBindArgs == null) {
2916            mAppBindArgs = new HashMap<>();
2917
2918            // Isolated processes won't get this optimization, so that we don't
2919            // violate the rules about which services they have access to.
2920            if (!isolated) {
2921                // Setup the application init args
2922                mAppBindArgs.put("package", ServiceManager.getService("package"));
2923                mAppBindArgs.put("window", ServiceManager.getService("window"));
2924                mAppBindArgs.put(Context.ALARM_SERVICE,
2925                        ServiceManager.getService(Context.ALARM_SERVICE));
2926            }
2927        }
2928        return mAppBindArgs;
2929    }
2930
2931    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2932        if (r == null || mFocusedActivity == r) {
2933            return false;
2934        }
2935
2936        if (!r.isFocusable()) {
2937            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2938            return false;
2939        }
2940
2941        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2942
2943        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2944        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2945                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2946        mDoingSetFocusedActivity = true;
2947
2948        final ActivityRecord last = mFocusedActivity;
2949        mFocusedActivity = r;
2950        if (r.task.isApplicationTask()) {
2951            if (mCurAppTimeTracker != r.appTimeTracker) {
2952                // We are switching app tracking.  Complete the current one.
2953                if (mCurAppTimeTracker != null) {
2954                    mCurAppTimeTracker.stop();
2955                    mHandler.obtainMessage(
2956                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2957                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2958                    mCurAppTimeTracker = null;
2959                }
2960                if (r.appTimeTracker != null) {
2961                    mCurAppTimeTracker = r.appTimeTracker;
2962                    startTimeTrackingFocusedActivityLocked();
2963                }
2964            } else {
2965                startTimeTrackingFocusedActivityLocked();
2966            }
2967        } else {
2968            r.appTimeTracker = null;
2969        }
2970        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2971        // TODO: Probably not, because we don't want to resume voice on switching
2972        // back to this activity
2973        if (r.task.voiceInteractor != null) {
2974            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2975        } else {
2976            finishRunningVoiceLocked();
2977            IVoiceInteractionSession session;
2978            if (last != null && ((session = last.task.voiceSession) != null
2979                    || (session = last.voiceSession) != null)) {
2980                // We had been in a voice interaction session, but now focused has
2981                // move to something different.  Just finish the session, we can't
2982                // return to it and retain the proper state and synchronization with
2983                // the voice interaction service.
2984                finishVoiceTask(session);
2985            }
2986        }
2987        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2988            mWindowManager.setFocusedApp(r.appToken, true);
2989        }
2990        applyUpdateLockStateLocked(r);
2991        applyUpdateVrModeLocked(r);
2992        if (mFocusedActivity.userId != mLastFocusedUserId) {
2993            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2994            mHandler.obtainMessage(
2995                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2996            mLastFocusedUserId = mFocusedActivity.userId;
2997        }
2998
2999        // Log a warning if the focused app is changed during the process. This could
3000        // indicate a problem of the focus setting logic!
3001        if (mFocusedActivity != r) Slog.w(TAG,
3002                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3003        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3004
3005        EventLogTags.writeAmFocusedActivity(
3006                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3007                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3008                reason);
3009        return true;
3010    }
3011
3012    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3013        if (mFocusedActivity != goingAway) {
3014            return;
3015        }
3016
3017        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3018        if (focusedStack != null) {
3019            final ActivityRecord top = focusedStack.topActivity();
3020            if (top != null && top.userId != mLastFocusedUserId) {
3021                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3022                mHandler.sendMessage(
3023                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3024                mLastFocusedUserId = top.userId;
3025            }
3026        }
3027
3028        // Try to move focus to another activity if possible.
3029        if (setFocusedActivityLocked(
3030                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3031            return;
3032        }
3033
3034        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3035                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3036        mFocusedActivity = null;
3037        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3038    }
3039
3040    @Override
3041    public void setFocusedStack(int stackId) {
3042        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3043        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3044        final long callingId = Binder.clearCallingIdentity();
3045        try {
3046            synchronized (this) {
3047                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3048                if (stack == null) {
3049                    return;
3050                }
3051                final ActivityRecord r = stack.topRunningActivityLocked();
3052                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3053                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3054                }
3055            }
3056        } finally {
3057            Binder.restoreCallingIdentity(callingId);
3058        }
3059    }
3060
3061    @Override
3062    public void setFocusedTask(int taskId) {
3063        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3064        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3065        final long callingId = Binder.clearCallingIdentity();
3066        try {
3067            synchronized (this) {
3068                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3069                if (task == null) {
3070                    return;
3071                }
3072                final ActivityRecord r = task.topRunningActivityLocked();
3073                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3074                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3075                }
3076            }
3077        } finally {
3078            Binder.restoreCallingIdentity(callingId);
3079        }
3080    }
3081
3082    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3083    @Override
3084    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3085        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3086        synchronized (this) {
3087            if (listener != null) {
3088                mTaskStackListeners.register(listener);
3089            }
3090        }
3091    }
3092
3093    @Override
3094    public void notifyActivityDrawn(IBinder token) {
3095        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3096        synchronized (this) {
3097            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3098            if (r != null) {
3099                r.task.stack.notifyActivityDrawnLocked(r);
3100            }
3101        }
3102    }
3103
3104    final void applyUpdateLockStateLocked(ActivityRecord r) {
3105        // Modifications to the UpdateLock state are done on our handler, outside
3106        // the activity manager's locks.  The new state is determined based on the
3107        // state *now* of the relevant activity record.  The object is passed to
3108        // the handler solely for logging detail, not to be consulted/modified.
3109        final boolean nextState = r != null && r.immersive;
3110        mHandler.sendMessage(
3111                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3112    }
3113
3114    final void applyUpdateVrModeLocked(ActivityRecord r) {
3115        mHandler.sendMessage(
3116                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3117    }
3118
3119    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3120        mHandler.sendMessage(
3121                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3122    }
3123
3124    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3125            ComponentName callingPackage, boolean immediate) {
3126        VrManagerInternal vrService =
3127                LocalServices.getService(VrManagerInternal.class);
3128        if (immediate) {
3129            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3130        } else {
3131            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3132        }
3133    }
3134
3135    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3136        Message msg = Message.obtain();
3137        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3138        msg.obj = r.task.askedCompatMode ? null : r;
3139        mUiHandler.sendMessage(msg);
3140    }
3141
3142    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3143        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3144                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3145            final Message msg = Message.obtain();
3146            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3147            msg.obj = r;
3148            mUiHandler.sendMessage(msg);
3149        }
3150    }
3151
3152    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3153            String what, Object obj, ProcessRecord srcApp) {
3154        app.lastActivityTime = now;
3155
3156        if (app.activities.size() > 0) {
3157            // Don't want to touch dependent processes that are hosting activities.
3158            return index;
3159        }
3160
3161        int lrui = mLruProcesses.lastIndexOf(app);
3162        if (lrui < 0) {
3163            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3164                    + what + " " + obj + " from " + srcApp);
3165            return index;
3166        }
3167
3168        if (lrui >= index) {
3169            // Don't want to cause this to move dependent processes *back* in the
3170            // list as if they were less frequently used.
3171            return index;
3172        }
3173
3174        if (lrui >= mLruProcessActivityStart) {
3175            // Don't want to touch dependent processes that are hosting activities.
3176            return index;
3177        }
3178
3179        mLruProcesses.remove(lrui);
3180        if (index > 0) {
3181            index--;
3182        }
3183        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3184                + " in LRU list: " + app);
3185        mLruProcesses.add(index, app);
3186        return index;
3187    }
3188
3189    static void killProcessGroup(int uid, int pid) {
3190        if (sKillHandler != null) {
3191            sKillHandler.sendMessage(
3192                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3193        } else {
3194            Slog.w(TAG, "Asked to kill process group before system bringup!");
3195            Process.killProcessGroup(uid, pid);
3196        }
3197    }
3198
3199    final void removeLruProcessLocked(ProcessRecord app) {
3200        int lrui = mLruProcesses.lastIndexOf(app);
3201        if (lrui >= 0) {
3202            if (!app.killed) {
3203                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3204                Process.killProcessQuiet(app.pid);
3205                killProcessGroup(app.uid, app.pid);
3206            }
3207            if (lrui <= mLruProcessActivityStart) {
3208                mLruProcessActivityStart--;
3209            }
3210            if (lrui <= mLruProcessServiceStart) {
3211                mLruProcessServiceStart--;
3212            }
3213            mLruProcesses.remove(lrui);
3214        }
3215    }
3216
3217    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3218            ProcessRecord client) {
3219        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3220                || app.treatLikeActivity;
3221        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3222        if (!activityChange && hasActivity) {
3223            // The process has activities, so we are only allowing activity-based adjustments
3224            // to move it.  It should be kept in the front of the list with other
3225            // processes that have activities, and we don't want those to change their
3226            // order except due to activity operations.
3227            return;
3228        }
3229
3230        mLruSeq++;
3231        final long now = SystemClock.uptimeMillis();
3232        app.lastActivityTime = now;
3233
3234        // First a quick reject: if the app is already at the position we will
3235        // put it, then there is nothing to do.
3236        if (hasActivity) {
3237            final int N = mLruProcesses.size();
3238            if (N > 0 && mLruProcesses.get(N-1) == app) {
3239                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3240                return;
3241            }
3242        } else {
3243            if (mLruProcessServiceStart > 0
3244                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3245                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3246                return;
3247            }
3248        }
3249
3250        int lrui = mLruProcesses.lastIndexOf(app);
3251
3252        if (app.persistent && lrui >= 0) {
3253            // We don't care about the position of persistent processes, as long as
3254            // they are in the list.
3255            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3256            return;
3257        }
3258
3259        /* In progress: compute new position first, so we can avoid doing work
3260           if the process is not actually going to move.  Not yet working.
3261        int addIndex;
3262        int nextIndex;
3263        boolean inActivity = false, inService = false;
3264        if (hasActivity) {
3265            // Process has activities, put it at the very tipsy-top.
3266            addIndex = mLruProcesses.size();
3267            nextIndex = mLruProcessServiceStart;
3268            inActivity = true;
3269        } else if (hasService) {
3270            // Process has services, put it at the top of the service list.
3271            addIndex = mLruProcessActivityStart;
3272            nextIndex = mLruProcessServiceStart;
3273            inActivity = true;
3274            inService = true;
3275        } else  {
3276            // Process not otherwise of interest, it goes to the top of the non-service area.
3277            addIndex = mLruProcessServiceStart;
3278            if (client != null) {
3279                int clientIndex = mLruProcesses.lastIndexOf(client);
3280                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3281                        + app);
3282                if (clientIndex >= 0 && addIndex > clientIndex) {
3283                    addIndex = clientIndex;
3284                }
3285            }
3286            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3287        }
3288
3289        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3290                + mLruProcessActivityStart + "): " + app);
3291        */
3292
3293        if (lrui >= 0) {
3294            if (lrui < mLruProcessActivityStart) {
3295                mLruProcessActivityStart--;
3296            }
3297            if (lrui < mLruProcessServiceStart) {
3298                mLruProcessServiceStart--;
3299            }
3300            /*
3301            if (addIndex > lrui) {
3302                addIndex--;
3303            }
3304            if (nextIndex > lrui) {
3305                nextIndex--;
3306            }
3307            */
3308            mLruProcesses.remove(lrui);
3309        }
3310
3311        /*
3312        mLruProcesses.add(addIndex, app);
3313        if (inActivity) {
3314            mLruProcessActivityStart++;
3315        }
3316        if (inService) {
3317            mLruProcessActivityStart++;
3318        }
3319        */
3320
3321        int nextIndex;
3322        if (hasActivity) {
3323            final int N = mLruProcesses.size();
3324            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3325                // Process doesn't have activities, but has clients with
3326                // activities...  move it up, but one below the top (the top
3327                // should always have a real activity).
3328                if (DEBUG_LRU) Slog.d(TAG_LRU,
3329                        "Adding to second-top of LRU activity list: " + app);
3330                mLruProcesses.add(N - 1, app);
3331                // To keep it from spamming the LRU list (by making a bunch of clients),
3332                // we will push down any other entries owned by the app.
3333                final int uid = app.info.uid;
3334                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3335                    ProcessRecord subProc = mLruProcesses.get(i);
3336                    if (subProc.info.uid == uid) {
3337                        // We want to push this one down the list.  If the process after
3338                        // it is for the same uid, however, don't do so, because we don't
3339                        // want them internally to be re-ordered.
3340                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3341                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3342                                    "Pushing uid " + uid + " swapping at " + i + ": "
3343                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3344                            ProcessRecord tmp = mLruProcesses.get(i);
3345                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3346                            mLruProcesses.set(i - 1, tmp);
3347                            i--;
3348                        }
3349                    } else {
3350                        // A gap, we can stop here.
3351                        break;
3352                    }
3353                }
3354            } else {
3355                // Process has activities, put it at the very tipsy-top.
3356                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3357                mLruProcesses.add(app);
3358            }
3359            nextIndex = mLruProcessServiceStart;
3360        } else if (hasService) {
3361            // Process has services, put it at the top of the service list.
3362            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3363            mLruProcesses.add(mLruProcessActivityStart, app);
3364            nextIndex = mLruProcessServiceStart;
3365            mLruProcessActivityStart++;
3366        } else  {
3367            // Process not otherwise of interest, it goes to the top of the non-service area.
3368            int index = mLruProcessServiceStart;
3369            if (client != null) {
3370                // If there is a client, don't allow the process to be moved up higher
3371                // in the list than that client.
3372                int clientIndex = mLruProcesses.lastIndexOf(client);
3373                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3374                        + " when updating " + app);
3375                if (clientIndex <= lrui) {
3376                    // Don't allow the client index restriction to push it down farther in the
3377                    // list than it already is.
3378                    clientIndex = lrui;
3379                }
3380                if (clientIndex >= 0 && index > clientIndex) {
3381                    index = clientIndex;
3382                }
3383            }
3384            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3385            mLruProcesses.add(index, app);
3386            nextIndex = index-1;
3387            mLruProcessActivityStart++;
3388            mLruProcessServiceStart++;
3389        }
3390
3391        // If the app is currently using a content provider or service,
3392        // bump those processes as well.
3393        for (int j=app.connections.size()-1; j>=0; j--) {
3394            ConnectionRecord cr = app.connections.valueAt(j);
3395            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3396                    && cr.binding.service.app != null
3397                    && cr.binding.service.app.lruSeq != mLruSeq
3398                    && !cr.binding.service.app.persistent) {
3399                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3400                        "service connection", cr, app);
3401            }
3402        }
3403        for (int j=app.conProviders.size()-1; j>=0; j--) {
3404            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3405            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3406                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3407                        "provider reference", cpr, app);
3408            }
3409        }
3410    }
3411
3412    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3413        if (uid == Process.SYSTEM_UID) {
3414            // The system gets to run in any process.  If there are multiple
3415            // processes with the same uid, just pick the first (this
3416            // should never happen).
3417            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3418            if (procs == null) return null;
3419            final int procCount = procs.size();
3420            for (int i = 0; i < procCount; i++) {
3421                final int procUid = procs.keyAt(i);
3422                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3423                    // Don't use an app process or different user process for system component.
3424                    continue;
3425                }
3426                return procs.valueAt(i);
3427            }
3428        }
3429        ProcessRecord proc = mProcessNames.get(processName, uid);
3430        if (false && proc != null && !keepIfLarge
3431                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3432                && proc.lastCachedPss >= 4000) {
3433            // Turn this condition on to cause killing to happen regularly, for testing.
3434            if (proc.baseProcessTracker != null) {
3435                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3436            }
3437            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3438        } else if (proc != null && !keepIfLarge
3439                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3440                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3441            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3442            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3443                if (proc.baseProcessTracker != null) {
3444                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3445                }
3446                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3447            }
3448        }
3449        return proc;
3450    }
3451
3452    void notifyPackageUse(String packageName, int reason) {
3453        IPackageManager pm = AppGlobals.getPackageManager();
3454        try {
3455            pm.notifyPackageUse(packageName, reason);
3456        } catch (RemoteException e) {
3457        }
3458    }
3459
3460    boolean isNextTransitionForward() {
3461        int transit = mWindowManager.getPendingAppTransition();
3462        return transit == TRANSIT_ACTIVITY_OPEN
3463                || transit == TRANSIT_TASK_OPEN
3464                || transit == TRANSIT_TASK_TO_FRONT;
3465    }
3466
3467    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3468            String processName, String abiOverride, int uid, Runnable crashHandler) {
3469        synchronized(this) {
3470            ApplicationInfo info = new ApplicationInfo();
3471            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3472            // For isolated processes, the former contains the parent's uid and the latter the
3473            // actual uid of the isolated process.
3474            // In the special case introduced by this method (which is, starting an isolated
3475            // process directly from the SystemServer without an actual parent app process) the
3476            // closest thing to a parent's uid is SYSTEM_UID.
3477            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3478            // the |isolated| logic in the ProcessRecord constructor.
3479            info.uid = Process.SYSTEM_UID;
3480            info.processName = processName;
3481            info.className = entryPoint;
3482            info.packageName = "android";
3483            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3484                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3485                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3486                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3487                    crashHandler);
3488            return proc != null ? proc.pid : 0;
3489        }
3490    }
3491
3492    final ProcessRecord startProcessLocked(String processName,
3493            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3494            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3495            boolean isolated, boolean keepIfLarge) {
3496        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3497                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3498                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3499                null /* crashHandler */);
3500    }
3501
3502    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3503            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3504            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3505            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3506        long startTime = SystemClock.elapsedRealtime();
3507        ProcessRecord app;
3508        if (!isolated) {
3509            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3510            checkTime(startTime, "startProcess: after getProcessRecord");
3511
3512            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3513                // If we are in the background, then check to see if this process
3514                // is bad.  If so, we will just silently fail.
3515                if (mAppErrors.isBadProcessLocked(info)) {
3516                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3517                            + "/" + info.processName);
3518                    return null;
3519                }
3520            } else {
3521                // When the user is explicitly starting a process, then clear its
3522                // crash count so that we won't make it bad until they see at
3523                // least one crash dialog again, and make the process good again
3524                // if it had been bad.
3525                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3526                        + "/" + info.processName);
3527                mAppErrors.resetProcessCrashTimeLocked(info);
3528                if (mAppErrors.isBadProcessLocked(info)) {
3529                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3530                            UserHandle.getUserId(info.uid), info.uid,
3531                            info.processName);
3532                    mAppErrors.clearBadProcessLocked(info);
3533                    if (app != null) {
3534                        app.bad = false;
3535                    }
3536                }
3537            }
3538        } else {
3539            // If this is an isolated process, it can't re-use an existing process.
3540            app = null;
3541        }
3542
3543        // app launch boost for big.little configurations
3544        // use cpusets to migrate freshly launched tasks to big cores
3545        nativeMigrateToBoost();
3546        mIsBoosted = true;
3547        mBoostStartTime = SystemClock.uptimeMillis();
3548        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3549        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3550
3551        // We don't have to do anything more if:
3552        // (1) There is an existing application record; and
3553        // (2) The caller doesn't think it is dead, OR there is no thread
3554        //     object attached to it so we know it couldn't have crashed; and
3555        // (3) There is a pid assigned to it, so it is either starting or
3556        //     already running.
3557        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3558                + " app=" + app + " knownToBeDead=" + knownToBeDead
3559                + " thread=" + (app != null ? app.thread : null)
3560                + " pid=" + (app != null ? app.pid : -1));
3561        if (app != null && app.pid > 0) {
3562            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3563                // We already have the app running, or are waiting for it to
3564                // come up (we have a pid but not yet its thread), so keep it.
3565                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3566                // If this is a new package in the process, add the package to the list
3567                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3568                checkTime(startTime, "startProcess: done, added package to proc");
3569                return app;
3570            }
3571
3572            // An application record is attached to a previous process,
3573            // clean it up now.
3574            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3575            checkTime(startTime, "startProcess: bad proc running, killing");
3576            killProcessGroup(app.uid, app.pid);
3577            handleAppDiedLocked(app, true, true);
3578            checkTime(startTime, "startProcess: done killing old proc");
3579        }
3580
3581        String hostingNameStr = hostingName != null
3582                ? hostingName.flattenToShortString() : null;
3583
3584        if (app == null) {
3585            checkTime(startTime, "startProcess: creating new process record");
3586            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3587            if (app == null) {
3588                Slog.w(TAG, "Failed making new process record for "
3589                        + processName + "/" + info.uid + " isolated=" + isolated);
3590                return null;
3591            }
3592            app.crashHandler = crashHandler;
3593            checkTime(startTime, "startProcess: done creating new process record");
3594        } else {
3595            // If this is a new package in the process, add the package to the list
3596            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3597            checkTime(startTime, "startProcess: added package to existing proc");
3598        }
3599
3600        // If the system is not ready yet, then hold off on starting this
3601        // process until it is.
3602        if (!mProcessesReady
3603                && !isAllowedWhileBooting(info)
3604                && !allowWhileBooting) {
3605            if (!mProcessesOnHold.contains(app)) {
3606                mProcessesOnHold.add(app);
3607            }
3608            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3609                    "System not ready, putting on hold: " + app);
3610            checkTime(startTime, "startProcess: returning with proc on hold");
3611            return app;
3612        }
3613
3614        checkTime(startTime, "startProcess: stepping in to startProcess");
3615        startProcessLocked(
3616                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3617        checkTime(startTime, "startProcess: done starting proc!");
3618        return (app.pid != 0) ? app : null;
3619    }
3620
3621    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3622        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3623    }
3624
3625    private final void startProcessLocked(ProcessRecord app,
3626            String hostingType, String hostingNameStr) {
3627        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3628                null /* entryPoint */, null /* entryPointArgs */);
3629    }
3630
3631    private final void startProcessLocked(ProcessRecord app, String hostingType,
3632            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3633        long startTime = SystemClock.elapsedRealtime();
3634        if (app.pid > 0 && app.pid != MY_PID) {
3635            checkTime(startTime, "startProcess: removing from pids map");
3636            synchronized (mPidsSelfLocked) {
3637                mPidsSelfLocked.remove(app.pid);
3638                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3639            }
3640            checkTime(startTime, "startProcess: done removing from pids map");
3641            app.setPid(0);
3642        }
3643
3644        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3645                "startProcessLocked removing on hold: " + app);
3646        mProcessesOnHold.remove(app);
3647
3648        checkTime(startTime, "startProcess: starting to update cpu stats");
3649        updateCpuStats();
3650        checkTime(startTime, "startProcess: done updating cpu stats");
3651
3652        try {
3653            try {
3654                final int userId = UserHandle.getUserId(app.uid);
3655                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3656            } catch (RemoteException e) {
3657                throw e.rethrowAsRuntimeException();
3658            }
3659
3660            int uid = app.uid;
3661            int[] gids = null;
3662            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3663            if (!app.isolated) {
3664                int[] permGids = null;
3665                try {
3666                    checkTime(startTime, "startProcess: getting gids from package manager");
3667                    final IPackageManager pm = AppGlobals.getPackageManager();
3668                    permGids = pm.getPackageGids(app.info.packageName,
3669                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3670                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3671                            MountServiceInternal.class);
3672                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3673                            app.info.packageName);
3674                } catch (RemoteException e) {
3675                    throw e.rethrowAsRuntimeException();
3676                }
3677
3678                /*
3679                 * Add shared application and profile GIDs so applications can share some
3680                 * resources like shared libraries and access user-wide resources
3681                 */
3682                if (ArrayUtils.isEmpty(permGids)) {
3683                    gids = new int[2];
3684                } else {
3685                    gids = new int[permGids.length + 2];
3686                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3687                }
3688                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3689                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3690            }
3691            checkTime(startTime, "startProcess: building args");
3692            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3693                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3694                        && mTopComponent != null
3695                        && app.processName.equals(mTopComponent.getPackageName())) {
3696                    uid = 0;
3697                }
3698                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3699                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3700                    uid = 0;
3701                }
3702            }
3703            int debugFlags = 0;
3704            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3705                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3706                // Also turn on CheckJNI for debuggable apps. It's quite
3707                // awkward to turn on otherwise.
3708                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3709            }
3710            // Run the app in safe mode if its manifest requests so or the
3711            // system is booted in safe mode.
3712            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3713                mSafeMode == true) {
3714                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3715            }
3716            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3717                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3718            }
3719            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3720            if ("true".equals(genDebugInfoProperty)) {
3721                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3722            }
3723            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3724                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3725            }
3726            if ("1".equals(SystemProperties.get("debug.assert"))) {
3727                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3728            }
3729            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3730                // Enable all debug flags required by the native debugger.
3731                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3732                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3733                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3734                mNativeDebuggingApp = null;
3735            }
3736
3737            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3738            if (requiredAbi == null) {
3739                requiredAbi = Build.SUPPORTED_ABIS[0];
3740            }
3741
3742            String instructionSet = null;
3743            if (app.info.primaryCpuAbi != null) {
3744                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3745            }
3746
3747            app.gids = gids;
3748            app.requiredAbi = requiredAbi;
3749            app.instructionSet = instructionSet;
3750
3751            // Start the process.  It will either succeed and return a result containing
3752            // the PID of the new process, or else throw a RuntimeException.
3753            boolean isActivityProcess = (entryPoint == null);
3754            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3755            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3756                    app.processName);
3757            checkTime(startTime, "startProcess: asking zygote to start proc");
3758            Process.ProcessStartResult startResult = Process.start(entryPoint,
3759                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3760                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3761                    app.info.dataDir, entryPointArgs);
3762            checkTime(startTime, "startProcess: returned from zygote!");
3763            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3764
3765            if (app.isolated) {
3766                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3767            }
3768            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3769            checkTime(startTime, "startProcess: done updating battery stats");
3770
3771            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3772                    UserHandle.getUserId(uid), startResult.pid, uid,
3773                    app.processName, hostingType,
3774                    hostingNameStr != null ? hostingNameStr : "");
3775
3776            try {
3777                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3778                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3779            } catch (RemoteException ex) {
3780                // Ignore
3781            }
3782
3783            if (app.persistent) {
3784                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3785            }
3786
3787            checkTime(startTime, "startProcess: building log message");
3788            StringBuilder buf = mStringBuilder;
3789            buf.setLength(0);
3790            buf.append("Start proc ");
3791            buf.append(startResult.pid);
3792            buf.append(':');
3793            buf.append(app.processName);
3794            buf.append('/');
3795            UserHandle.formatUid(buf, uid);
3796            if (!isActivityProcess) {
3797                buf.append(" [");
3798                buf.append(entryPoint);
3799                buf.append("]");
3800            }
3801            buf.append(" for ");
3802            buf.append(hostingType);
3803            if (hostingNameStr != null) {
3804                buf.append(" ");
3805                buf.append(hostingNameStr);
3806            }
3807            Slog.i(TAG, buf.toString());
3808            app.setPid(startResult.pid);
3809            app.usingWrapper = startResult.usingWrapper;
3810            app.removed = false;
3811            app.killed = false;
3812            app.killedByAm = false;
3813            checkTime(startTime, "startProcess: starting to update pids map");
3814            synchronized (mPidsSelfLocked) {
3815                this.mPidsSelfLocked.put(startResult.pid, app);
3816                if (isActivityProcess) {
3817                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3818                    msg.obj = app;
3819                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3820                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3821                }
3822            }
3823            checkTime(startTime, "startProcess: done updating pids map");
3824        } catch (RuntimeException e) {
3825            Slog.e(TAG, "Failure starting process " + app.processName, e);
3826
3827            // Something went very wrong while trying to start this process; one
3828            // common case is when the package is frozen due to an active
3829            // upgrade. To recover, clean up any active bookkeeping related to
3830            // starting this process. (We already invoked this method once when
3831            // the package was initially frozen through KILL_APPLICATION_MSG, so
3832            // it doesn't hurt to use it again.)
3833            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3834                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3835        }
3836    }
3837
3838    void updateUsageStats(ActivityRecord component, boolean resumed) {
3839        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3840                "updateUsageStats: comp=" + component + "res=" + resumed);
3841        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3842        if (resumed) {
3843            if (mUsageStatsService != null) {
3844                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3845                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3846            }
3847            synchronized (stats) {
3848                stats.noteActivityResumedLocked(component.app.uid);
3849            }
3850        } else {
3851            if (mUsageStatsService != null) {
3852                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3853                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3854            }
3855            synchronized (stats) {
3856                stats.noteActivityPausedLocked(component.app.uid);
3857            }
3858        }
3859    }
3860
3861    Intent getHomeIntent() {
3862        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3863        intent.setComponent(mTopComponent);
3864        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3865        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3866            intent.addCategory(Intent.CATEGORY_HOME);
3867        }
3868        return intent;
3869    }
3870
3871    boolean startHomeActivityLocked(int userId, String reason) {
3872        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3873                && mTopAction == null) {
3874            // We are running in factory test mode, but unable to find
3875            // the factory test app, so just sit around displaying the
3876            // error message and don't try to start anything.
3877            return false;
3878        }
3879        Intent intent = getHomeIntent();
3880        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3881        if (aInfo != null) {
3882            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3883            // Don't do this if the home app is currently being
3884            // instrumented.
3885            aInfo = new ActivityInfo(aInfo);
3886            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3887            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3888                    aInfo.applicationInfo.uid, true);
3889            if (app == null || app.instrumentationClass == null) {
3890                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3891                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3892            }
3893        } else {
3894            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3895        }
3896
3897        return true;
3898    }
3899
3900    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3901        ActivityInfo ai = null;
3902        ComponentName comp = intent.getComponent();
3903        try {
3904            if (comp != null) {
3905                // Factory test.
3906                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3907            } else {
3908                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3909                        intent,
3910                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3911                        flags, userId);
3912
3913                if (info != null) {
3914                    ai = info.activityInfo;
3915                }
3916            }
3917        } catch (RemoteException e) {
3918            // ignore
3919        }
3920
3921        return ai;
3922    }
3923
3924    /**
3925     * Starts the "new version setup screen" if appropriate.
3926     */
3927    void startSetupActivityLocked() {
3928        // Only do this once per boot.
3929        if (mCheckedForSetup) {
3930            return;
3931        }
3932
3933        // We will show this screen if the current one is a different
3934        // version than the last one shown, and we are not running in
3935        // low-level factory test mode.
3936        final ContentResolver resolver = mContext.getContentResolver();
3937        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3938                Settings.Global.getInt(resolver,
3939                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3940            mCheckedForSetup = true;
3941
3942            // See if we should be showing the platform update setup UI.
3943            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3944            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3945                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3946            if (!ris.isEmpty()) {
3947                final ResolveInfo ri = ris.get(0);
3948                String vers = ri.activityInfo.metaData != null
3949                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3950                        : null;
3951                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3952                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3953                            Intent.METADATA_SETUP_VERSION);
3954                }
3955                String lastVers = Settings.Secure.getString(
3956                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3957                if (vers != null && !vers.equals(lastVers)) {
3958                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3959                    intent.setComponent(new ComponentName(
3960                            ri.activityInfo.packageName, ri.activityInfo.name));
3961                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3962                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3963                            null, 0, 0, 0, null, false, false, null, null, null);
3964                }
3965            }
3966        }
3967    }
3968
3969    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3970        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3971    }
3972
3973    void enforceNotIsolatedCaller(String caller) {
3974        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3975            throw new SecurityException("Isolated process not allowed to call " + caller);
3976        }
3977    }
3978
3979    void enforceShellRestriction(String restriction, int userHandle) {
3980        if (Binder.getCallingUid() == Process.SHELL_UID) {
3981            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3982                throw new SecurityException("Shell does not have permission to access user "
3983                        + userHandle);
3984            }
3985        }
3986    }
3987
3988    @Override
3989    public int getFrontActivityScreenCompatMode() {
3990        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3991        synchronized (this) {
3992            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3993        }
3994    }
3995
3996    @Override
3997    public void setFrontActivityScreenCompatMode(int mode) {
3998        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3999                "setFrontActivityScreenCompatMode");
4000        synchronized (this) {
4001            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4002        }
4003    }
4004
4005    @Override
4006    public int getPackageScreenCompatMode(String packageName) {
4007        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4008        synchronized (this) {
4009            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4010        }
4011    }
4012
4013    @Override
4014    public void setPackageScreenCompatMode(String packageName, int mode) {
4015        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4016                "setPackageScreenCompatMode");
4017        synchronized (this) {
4018            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4019        }
4020    }
4021
4022    @Override
4023    public boolean getPackageAskScreenCompat(String packageName) {
4024        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4025        synchronized (this) {
4026            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4027        }
4028    }
4029
4030    @Override
4031    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4032        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4033                "setPackageAskScreenCompat");
4034        synchronized (this) {
4035            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4036        }
4037    }
4038
4039    private boolean hasUsageStatsPermission(String callingPackage) {
4040        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4041                Binder.getCallingUid(), callingPackage);
4042        if (mode == AppOpsManager.MODE_DEFAULT) {
4043            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4044                    == PackageManager.PERMISSION_GRANTED;
4045        }
4046        return mode == AppOpsManager.MODE_ALLOWED;
4047    }
4048
4049    @Override
4050    public int getPackageProcessState(String packageName, String callingPackage) {
4051        if (!hasUsageStatsPermission(callingPackage)) {
4052            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4053                    "getPackageProcessState");
4054        }
4055
4056        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4057        synchronized (this) {
4058            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4059                final ProcessRecord proc = mLruProcesses.get(i);
4060                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4061                        || procState > proc.setProcState) {
4062                    boolean found = false;
4063                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4064                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4065                            procState = proc.setProcState;
4066                            found = true;
4067                        }
4068                    }
4069                    if (proc.pkgDeps != null && !found) {
4070                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4071                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4072                                procState = proc.setProcState;
4073                                break;
4074                            }
4075                        }
4076                    }
4077                }
4078            }
4079        }
4080        return procState;
4081    }
4082
4083    @Override
4084    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4085        synchronized (this) {
4086            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4087            if (app == null) {
4088                return false;
4089            }
4090            if (app.trimMemoryLevel < level && app.thread != null &&
4091                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4092                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4093                try {
4094                    app.thread.scheduleTrimMemory(level);
4095                    app.trimMemoryLevel = level;
4096                    return true;
4097                } catch (RemoteException e) {
4098                    // Fallthrough to failure case.
4099                }
4100            }
4101        }
4102        return false;
4103    }
4104
4105    private void dispatchProcessesChanged() {
4106        int N;
4107        synchronized (this) {
4108            N = mPendingProcessChanges.size();
4109            if (mActiveProcessChanges.length < N) {
4110                mActiveProcessChanges = new ProcessChangeItem[N];
4111            }
4112            mPendingProcessChanges.toArray(mActiveProcessChanges);
4113            mPendingProcessChanges.clear();
4114            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4115                    "*** Delivering " + N + " process changes");
4116        }
4117
4118        int i = mProcessObservers.beginBroadcast();
4119        while (i > 0) {
4120            i--;
4121            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4122            if (observer != null) {
4123                try {
4124                    for (int j=0; j<N; j++) {
4125                        ProcessChangeItem item = mActiveProcessChanges[j];
4126                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4127                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4128                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4129                                    + item.uid + ": " + item.foregroundActivities);
4130                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4131                                    item.foregroundActivities);
4132                        }
4133                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4134                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4135                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4136                                    + ": " + item.processState);
4137                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4138                        }
4139                    }
4140                } catch (RemoteException e) {
4141                }
4142            }
4143        }
4144        mProcessObservers.finishBroadcast();
4145
4146        synchronized (this) {
4147            for (int j=0; j<N; j++) {
4148                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4149            }
4150        }
4151    }
4152
4153    private void dispatchProcessDied(int pid, int uid) {
4154        int i = mProcessObservers.beginBroadcast();
4155        while (i > 0) {
4156            i--;
4157            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4158            if (observer != null) {
4159                try {
4160                    observer.onProcessDied(pid, uid);
4161                } catch (RemoteException e) {
4162                }
4163            }
4164        }
4165        mProcessObservers.finishBroadcast();
4166    }
4167
4168    private void dispatchUidsChanged() {
4169        int N;
4170        synchronized (this) {
4171            N = mPendingUidChanges.size();
4172            if (mActiveUidChanges.length < N) {
4173                mActiveUidChanges = new UidRecord.ChangeItem[N];
4174            }
4175            for (int i=0; i<N; i++) {
4176                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4177                mActiveUidChanges[i] = change;
4178                if (change.uidRecord != null) {
4179                    change.uidRecord.pendingChange = null;
4180                    change.uidRecord = null;
4181                }
4182            }
4183            mPendingUidChanges.clear();
4184            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4185                    "*** Delivering " + N + " uid changes");
4186        }
4187
4188        if (mLocalPowerManager != null) {
4189            for (int j=0; j<N; j++) {
4190                UidRecord.ChangeItem item = mActiveUidChanges[j];
4191                if (item.change == UidRecord.CHANGE_GONE
4192                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4193                    mLocalPowerManager.uidGone(item.uid);
4194                } else {
4195                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4196                }
4197            }
4198        }
4199
4200        int i = mUidObservers.beginBroadcast();
4201        while (i > 0) {
4202            i--;
4203            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4204            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4205            if (observer != null) {
4206                try {
4207                    for (int j=0; j<N; j++) {
4208                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4209                        final int change = item.change;
4210                        UidRecord validateUid = null;
4211                        if (VALIDATE_UID_STATES && i == 0) {
4212                            validateUid = mValidateUids.get(item.uid);
4213                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4214                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4215                                validateUid = new UidRecord(item.uid);
4216                                mValidateUids.put(item.uid, validateUid);
4217                            }
4218                        }
4219                        if (change == UidRecord.CHANGE_IDLE
4220                                || change == UidRecord.CHANGE_GONE_IDLE) {
4221                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4222                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4223                                        "UID idle uid=" + item.uid);
4224                                observer.onUidIdle(item.uid);
4225                            }
4226                            if (VALIDATE_UID_STATES && i == 0) {
4227                                if (validateUid != null) {
4228                                    validateUid.idle = true;
4229                                }
4230                            }
4231                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4232                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4233                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4234                                        "UID active uid=" + item.uid);
4235                                observer.onUidActive(item.uid);
4236                            }
4237                            if (VALIDATE_UID_STATES && i == 0) {
4238                                validateUid.idle = false;
4239                            }
4240                        }
4241                        if (change == UidRecord.CHANGE_GONE
4242                                || change == UidRecord.CHANGE_GONE_IDLE) {
4243                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4244                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4245                                        "UID gone uid=" + item.uid);
4246                                observer.onUidGone(item.uid);
4247                            }
4248                            if (VALIDATE_UID_STATES && i == 0) {
4249                                if (validateUid != null) {
4250                                    mValidateUids.remove(item.uid);
4251                                }
4252                            }
4253                        } else {
4254                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4255                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4256                                        "UID CHANGED uid=" + item.uid
4257                                                + ": " + item.processState);
4258                                observer.onUidStateChanged(item.uid, item.processState);
4259                            }
4260                            if (VALIDATE_UID_STATES && i == 0) {
4261                                validateUid.curProcState = validateUid.setProcState
4262                                        = item.processState;
4263                            }
4264                        }
4265                    }
4266                } catch (RemoteException e) {
4267                }
4268            }
4269        }
4270        mUidObservers.finishBroadcast();
4271
4272        synchronized (this) {
4273            for (int j=0; j<N; j++) {
4274                mAvailUidChanges.add(mActiveUidChanges[j]);
4275            }
4276        }
4277    }
4278
4279    @Override
4280    public final int startActivity(IApplicationThread caller, String callingPackage,
4281            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4282            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4283        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4284                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4285                UserHandle.getCallingUserId());
4286    }
4287
4288    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4289        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4290        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4291                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4292                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4293
4294        // TODO: Switch to user app stacks here.
4295        String mimeType = intent.getType();
4296        final Uri data = intent.getData();
4297        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4298            mimeType = getProviderMimeType(data, userId);
4299        }
4300        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4301
4302        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4303        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4304                null, 0, 0, null, null, null, null, false, userId, container, null);
4305    }
4306
4307    @Override
4308    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4309            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4310            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4311        enforceNotIsolatedCaller("startActivity");
4312        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4313                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4314        // TODO: Switch to user app stacks here.
4315        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4316                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4317                profilerInfo, null, null, bOptions, false, userId, null, null);
4318    }
4319
4320    @Override
4321    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4322            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4323            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4324            int userId) {
4325
4326        // This is very dangerous -- it allows you to perform a start activity (including
4327        // permission grants) as any app that may launch one of your own activities.  So
4328        // we will only allow this to be done from activities that are part of the core framework,
4329        // and then only when they are running as the system.
4330        final ActivityRecord sourceRecord;
4331        final int targetUid;
4332        final String targetPackage;
4333        synchronized (this) {
4334            if (resultTo == null) {
4335                throw new SecurityException("Must be called from an activity");
4336            }
4337            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4338            if (sourceRecord == null) {
4339                throw new SecurityException("Called with bad activity token: " + resultTo);
4340            }
4341            if (!sourceRecord.info.packageName.equals("android")) {
4342                throw new SecurityException(
4343                        "Must be called from an activity that is declared in the android package");
4344            }
4345            if (sourceRecord.app == null) {
4346                throw new SecurityException("Called without a process attached to activity");
4347            }
4348            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4349                // This is still okay, as long as this activity is running under the
4350                // uid of the original calling activity.
4351                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4352                    throw new SecurityException(
4353                            "Calling activity in uid " + sourceRecord.app.uid
4354                                    + " must be system uid or original calling uid "
4355                                    + sourceRecord.launchedFromUid);
4356                }
4357            }
4358            if (ignoreTargetSecurity) {
4359                if (intent.getComponent() == null) {
4360                    throw new SecurityException(
4361                            "Component must be specified with ignoreTargetSecurity");
4362                }
4363                if (intent.getSelector() != null) {
4364                    throw new SecurityException(
4365                            "Selector not allowed with ignoreTargetSecurity");
4366                }
4367            }
4368            targetUid = sourceRecord.launchedFromUid;
4369            targetPackage = sourceRecord.launchedFromPackage;
4370        }
4371
4372        if (userId == UserHandle.USER_NULL) {
4373            userId = UserHandle.getUserId(sourceRecord.app.uid);
4374        }
4375
4376        // TODO: Switch to user app stacks here.
4377        try {
4378            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4379                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4380                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4381            return ret;
4382        } catch (SecurityException e) {
4383            // XXX need to figure out how to propagate to original app.
4384            // A SecurityException here is generally actually a fault of the original
4385            // calling activity (such as a fairly granting permissions), so propagate it
4386            // back to them.
4387            /*
4388            StringBuilder msg = new StringBuilder();
4389            msg.append("While launching");
4390            msg.append(intent.toString());
4391            msg.append(": ");
4392            msg.append(e.getMessage());
4393            */
4394            throw e;
4395        }
4396    }
4397
4398    @Override
4399    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4400            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4401            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4402        enforceNotIsolatedCaller("startActivityAndWait");
4403        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4404                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4405        WaitResult res = new WaitResult();
4406        // TODO: Switch to user app stacks here.
4407        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4408                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4409                bOptions, false, userId, null, null);
4410        return res;
4411    }
4412
4413    @Override
4414    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4415            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4416            int startFlags, Configuration config, Bundle bOptions, int userId) {
4417        enforceNotIsolatedCaller("startActivityWithConfig");
4418        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4419                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4420        // TODO: Switch to user app stacks here.
4421        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4422                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4423                null, null, config, bOptions, false, userId, null, null);
4424        return ret;
4425    }
4426
4427    @Override
4428    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4429            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4430            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4431            throws TransactionTooLargeException {
4432        enforceNotIsolatedCaller("startActivityIntentSender");
4433        // Refuse possible leaked file descriptors
4434        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4435            throw new IllegalArgumentException("File descriptors passed in Intent");
4436        }
4437
4438        IIntentSender sender = intent.getTarget();
4439        if (!(sender instanceof PendingIntentRecord)) {
4440            throw new IllegalArgumentException("Bad PendingIntent object");
4441        }
4442
4443        PendingIntentRecord pir = (PendingIntentRecord)sender;
4444
4445        synchronized (this) {
4446            // If this is coming from the currently resumed activity, it is
4447            // effectively saying that app switches are allowed at this point.
4448            final ActivityStack stack = getFocusedStack();
4449            if (stack.mResumedActivity != null &&
4450                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4451                mAppSwitchesAllowedTime = 0;
4452            }
4453        }
4454        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4455                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4456        return ret;
4457    }
4458
4459    @Override
4460    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4461            Intent intent, String resolvedType, IVoiceInteractionSession session,
4462            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4463            Bundle bOptions, int userId) {
4464        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4465                != PackageManager.PERMISSION_GRANTED) {
4466            String msg = "Permission Denial: startVoiceActivity() from pid="
4467                    + Binder.getCallingPid()
4468                    + ", uid=" + Binder.getCallingUid()
4469                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4470            Slog.w(TAG, msg);
4471            throw new SecurityException(msg);
4472        }
4473        if (session == null || interactor == null) {
4474            throw new NullPointerException("null session or interactor");
4475        }
4476        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4477                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4478        // TODO: Switch to user app stacks here.
4479        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4480                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4481                null, bOptions, false, userId, null, null);
4482    }
4483
4484    @Override
4485    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4486            throws RemoteException {
4487        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4488        synchronized (this) {
4489            ActivityRecord activity = getFocusedStack().topActivity();
4490            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4491                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4492            }
4493            if (mRunningVoice != null || activity.task.voiceSession != null
4494                    || activity.voiceSession != null) {
4495                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4496                return;
4497            }
4498            if (activity.pendingVoiceInteractionStart) {
4499                Slog.w(TAG, "Pending start of voice interaction already.");
4500                return;
4501            }
4502            activity.pendingVoiceInteractionStart = true;
4503        }
4504        LocalServices.getService(VoiceInteractionManagerInternal.class)
4505                .startLocalVoiceInteraction(callingActivity, options);
4506    }
4507
4508    @Override
4509    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4510        LocalServices.getService(VoiceInteractionManagerInternal.class)
4511                .stopLocalVoiceInteraction(callingActivity);
4512    }
4513
4514    @Override
4515    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4516        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4517                .supportsLocalVoiceInteraction();
4518    }
4519
4520    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4521            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4522        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4523        if (activityToCallback == null) return;
4524        activityToCallback.setVoiceSessionLocked(voiceSession);
4525
4526        // Inform the activity
4527        try {
4528            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4529                    voiceInteractor);
4530            long token = Binder.clearCallingIdentity();
4531            try {
4532                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4533            } finally {
4534                Binder.restoreCallingIdentity(token);
4535            }
4536            // TODO: VI Should we cache the activity so that it's easier to find later
4537            // rather than scan through all the stacks and activities?
4538        } catch (RemoteException re) {
4539            activityToCallback.clearVoiceSessionLocked();
4540            // TODO: VI Should this terminate the voice session?
4541        }
4542    }
4543
4544    @Override
4545    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4546        synchronized (this) {
4547            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4548                if (keepAwake) {
4549                    mVoiceWakeLock.acquire();
4550                } else {
4551                    mVoiceWakeLock.release();
4552                }
4553            }
4554        }
4555    }
4556
4557    @Override
4558    public boolean startNextMatchingActivity(IBinder callingActivity,
4559            Intent intent, Bundle bOptions) {
4560        // Refuse possible leaked file descriptors
4561        if (intent != null && intent.hasFileDescriptors() == true) {
4562            throw new IllegalArgumentException("File descriptors passed in Intent");
4563        }
4564        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4565
4566        synchronized (this) {
4567            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4568            if (r == null) {
4569                ActivityOptions.abort(options);
4570                return false;
4571            }
4572            if (r.app == null || r.app.thread == null) {
4573                // The caller is not running...  d'oh!
4574                ActivityOptions.abort(options);
4575                return false;
4576            }
4577            intent = new Intent(intent);
4578            // The caller is not allowed to change the data.
4579            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4580            // And we are resetting to find the next component...
4581            intent.setComponent(null);
4582
4583            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4584
4585            ActivityInfo aInfo = null;
4586            try {
4587                List<ResolveInfo> resolves =
4588                    AppGlobals.getPackageManager().queryIntentActivities(
4589                            intent, r.resolvedType,
4590                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4591                            UserHandle.getCallingUserId()).getList();
4592
4593                // Look for the original activity in the list...
4594                final int N = resolves != null ? resolves.size() : 0;
4595                for (int i=0; i<N; i++) {
4596                    ResolveInfo rInfo = resolves.get(i);
4597                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4598                            && rInfo.activityInfo.name.equals(r.info.name)) {
4599                        // We found the current one...  the next matching is
4600                        // after it.
4601                        i++;
4602                        if (i<N) {
4603                            aInfo = resolves.get(i).activityInfo;
4604                        }
4605                        if (debug) {
4606                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4607                                    + "/" + r.info.name);
4608                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4609                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4610                        }
4611                        break;
4612                    }
4613                }
4614            } catch (RemoteException e) {
4615            }
4616
4617            if (aInfo == null) {
4618                // Nobody who is next!
4619                ActivityOptions.abort(options);
4620                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4621                return false;
4622            }
4623
4624            intent.setComponent(new ComponentName(
4625                    aInfo.applicationInfo.packageName, aInfo.name));
4626            intent.setFlags(intent.getFlags()&~(
4627                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4628                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4629                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4630                    Intent.FLAG_ACTIVITY_NEW_TASK));
4631
4632            // Okay now we need to start the new activity, replacing the
4633            // currently running activity.  This is a little tricky because
4634            // we want to start the new one as if the current one is finished,
4635            // but not finish the current one first so that there is no flicker.
4636            // And thus...
4637            final boolean wasFinishing = r.finishing;
4638            r.finishing = true;
4639
4640            // Propagate reply information over to the new activity.
4641            final ActivityRecord resultTo = r.resultTo;
4642            final String resultWho = r.resultWho;
4643            final int requestCode = r.requestCode;
4644            r.resultTo = null;
4645            if (resultTo != null) {
4646                resultTo.removeResultsLocked(r, resultWho, requestCode);
4647            }
4648
4649            final long origId = Binder.clearCallingIdentity();
4650            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4651                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4652                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4653                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4654                    false, false, null, null, null);
4655            Binder.restoreCallingIdentity(origId);
4656
4657            r.finishing = wasFinishing;
4658            if (res != ActivityManager.START_SUCCESS) {
4659                return false;
4660            }
4661            return true;
4662        }
4663    }
4664
4665    @Override
4666    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4667        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4668            String msg = "Permission Denial: startActivityFromRecents called without " +
4669                    START_TASKS_FROM_RECENTS;
4670            Slog.w(TAG, msg);
4671            throw new SecurityException(msg);
4672        }
4673        final long origId = Binder.clearCallingIdentity();
4674        try {
4675            synchronized (this) {
4676                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4677            }
4678        } finally {
4679            Binder.restoreCallingIdentity(origId);
4680        }
4681    }
4682
4683    final int startActivityInPackage(int uid, String callingPackage,
4684            Intent intent, String resolvedType, IBinder resultTo,
4685            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4686            IActivityContainer container, TaskRecord inTask) {
4687
4688        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4689                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4690
4691        // TODO: Switch to user app stacks here.
4692        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4693                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4694                null, null, null, bOptions, false, userId, container, inTask);
4695        return ret;
4696    }
4697
4698    @Override
4699    public final int startActivities(IApplicationThread caller, String callingPackage,
4700            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4701            int userId) {
4702        enforceNotIsolatedCaller("startActivities");
4703        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4704                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4705        // TODO: Switch to user app stacks here.
4706        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4707                resolvedTypes, resultTo, bOptions, userId);
4708        return ret;
4709    }
4710
4711    final int startActivitiesInPackage(int uid, String callingPackage,
4712            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4713            Bundle bOptions, int userId) {
4714
4715        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4716                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4717        // TODO: Switch to user app stacks here.
4718        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4719                resultTo, bOptions, userId);
4720        return ret;
4721    }
4722
4723    @Override
4724    public void reportActivityFullyDrawn(IBinder token) {
4725        synchronized (this) {
4726            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4727            if (r == null) {
4728                return;
4729            }
4730            r.reportFullyDrawnLocked();
4731        }
4732    }
4733
4734    @Override
4735    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4736        synchronized (this) {
4737            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4738            if (r == null) {
4739                return;
4740            }
4741            TaskRecord task = r.task;
4742            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4743                // Fixed screen orientation isn't supported when activities aren't in full screen
4744                // mode.
4745                return;
4746            }
4747            final long origId = Binder.clearCallingIdentity();
4748            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4749            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4750                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4751            if (config != null) {
4752                r.frozenBeforeDestroy = true;
4753                if (!updateConfigurationLocked(config, r, false)) {
4754                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4755                }
4756            }
4757            Binder.restoreCallingIdentity(origId);
4758        }
4759    }
4760
4761    @Override
4762    public int getRequestedOrientation(IBinder token) {
4763        synchronized (this) {
4764            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4765            if (r == null) {
4766                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4767            }
4768            return mWindowManager.getAppOrientation(r.appToken);
4769        }
4770    }
4771
4772    /**
4773     * This is the internal entry point for handling Activity.finish().
4774     *
4775     * @param token The Binder token referencing the Activity we want to finish.
4776     * @param resultCode Result code, if any, from this Activity.
4777     * @param resultData Result data (Intent), if any, from this Activity.
4778     * @param finishTask Whether to finish the task associated with this Activity.
4779     *
4780     * @return Returns true if the activity successfully finished, or false if it is still running.
4781     */
4782    @Override
4783    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4784            int finishTask) {
4785        // Refuse possible leaked file descriptors
4786        if (resultData != null && resultData.hasFileDescriptors() == true) {
4787            throw new IllegalArgumentException("File descriptors passed in Intent");
4788        }
4789
4790        synchronized(this) {
4791            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4792            if (r == null) {
4793                return true;
4794            }
4795            // Keep track of the root activity of the task before we finish it
4796            TaskRecord tr = r.task;
4797            ActivityRecord rootR = tr.getRootActivity();
4798            if (rootR == null) {
4799                Slog.w(TAG, "Finishing task with all activities already finished");
4800            }
4801            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4802            // finish.
4803            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4804                    mStackSupervisor.isLastLockedTask(tr)) {
4805                Slog.i(TAG, "Not finishing task in lock task mode");
4806                mStackSupervisor.showLockTaskToast();
4807                return false;
4808            }
4809            if (mController != null) {
4810                // Find the first activity that is not finishing.
4811                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4812                if (next != null) {
4813                    // ask watcher if this is allowed
4814                    boolean resumeOK = true;
4815                    try {
4816                        resumeOK = mController.activityResuming(next.packageName);
4817                    } catch (RemoteException e) {
4818                        mController = null;
4819                        Watchdog.getInstance().setActivityController(null);
4820                    }
4821
4822                    if (!resumeOK) {
4823                        Slog.i(TAG, "Not finishing activity because controller resumed");
4824                        return false;
4825                    }
4826                }
4827            }
4828            final long origId = Binder.clearCallingIdentity();
4829            try {
4830                boolean res;
4831                final boolean finishWithRootActivity =
4832                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4833                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4834                        || (finishWithRootActivity && r == rootR)) {
4835                    // If requested, remove the task that is associated to this activity only if it
4836                    // was the root activity in the task. The result code and data is ignored
4837                    // because we don't support returning them across task boundaries. Also, to
4838                    // keep backwards compatibility we remove the task from recents when finishing
4839                    // task with root activity.
4840                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4841                    if (!res) {
4842                        Slog.i(TAG, "Removing task failed to finish activity");
4843                    }
4844                } else {
4845                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4846                            resultData, "app-request", true);
4847                    if (!res) {
4848                        Slog.i(TAG, "Failed to finish by app-request");
4849                    }
4850                }
4851                return res;
4852            } finally {
4853                Binder.restoreCallingIdentity(origId);
4854            }
4855        }
4856    }
4857
4858    @Override
4859    public final void finishHeavyWeightApp() {
4860        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4861                != PackageManager.PERMISSION_GRANTED) {
4862            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4863                    + Binder.getCallingPid()
4864                    + ", uid=" + Binder.getCallingUid()
4865                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4866            Slog.w(TAG, msg);
4867            throw new SecurityException(msg);
4868        }
4869
4870        synchronized(this) {
4871            if (mHeavyWeightProcess == null) {
4872                return;
4873            }
4874
4875            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4876            for (int i = 0; i < activities.size(); i++) {
4877                ActivityRecord r = activities.get(i);
4878                if (!r.finishing && r.isInStackLocked()) {
4879                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4880                            null, "finish-heavy", true);
4881                }
4882            }
4883
4884            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4885                    mHeavyWeightProcess.userId, 0));
4886            mHeavyWeightProcess = null;
4887        }
4888    }
4889
4890    @Override
4891    public void crashApplication(int uid, int initialPid, String packageName,
4892            String message) {
4893        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4894                != PackageManager.PERMISSION_GRANTED) {
4895            String msg = "Permission Denial: crashApplication() from pid="
4896                    + Binder.getCallingPid()
4897                    + ", uid=" + Binder.getCallingUid()
4898                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4899            Slog.w(TAG, msg);
4900            throw new SecurityException(msg);
4901        }
4902
4903        synchronized(this) {
4904            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4905        }
4906    }
4907
4908    @Override
4909    public final void finishSubActivity(IBinder token, String resultWho,
4910            int requestCode) {
4911        synchronized(this) {
4912            final long origId = Binder.clearCallingIdentity();
4913            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4914            if (r != null) {
4915                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4916            }
4917            Binder.restoreCallingIdentity(origId);
4918        }
4919    }
4920
4921    @Override
4922    public boolean finishActivityAffinity(IBinder token) {
4923        synchronized(this) {
4924            final long origId = Binder.clearCallingIdentity();
4925            try {
4926                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4927                if (r == null) {
4928                    return false;
4929                }
4930
4931                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4932                // can finish.
4933                final TaskRecord task = r.task;
4934                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4935                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4936                    mStackSupervisor.showLockTaskToast();
4937                    return false;
4938                }
4939                return task.stack.finishActivityAffinityLocked(r);
4940            } finally {
4941                Binder.restoreCallingIdentity(origId);
4942            }
4943        }
4944    }
4945
4946    @Override
4947    public void finishVoiceTask(IVoiceInteractionSession session) {
4948        synchronized (this) {
4949            final long origId = Binder.clearCallingIdentity();
4950            try {
4951                // TODO: VI Consider treating local voice interactions and voice tasks
4952                // differently here
4953                mStackSupervisor.finishVoiceTask(session);
4954            } finally {
4955                Binder.restoreCallingIdentity(origId);
4956            }
4957        }
4958
4959    }
4960
4961    @Override
4962    public boolean releaseActivityInstance(IBinder token) {
4963        synchronized(this) {
4964            final long origId = Binder.clearCallingIdentity();
4965            try {
4966                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4967                if (r == null) {
4968                    return false;
4969                }
4970                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4971            } finally {
4972                Binder.restoreCallingIdentity(origId);
4973            }
4974        }
4975    }
4976
4977    @Override
4978    public void releaseSomeActivities(IApplicationThread appInt) {
4979        synchronized(this) {
4980            final long origId = Binder.clearCallingIdentity();
4981            try {
4982                ProcessRecord app = getRecordForAppLocked(appInt);
4983                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4984            } finally {
4985                Binder.restoreCallingIdentity(origId);
4986            }
4987        }
4988    }
4989
4990    @Override
4991    public boolean willActivityBeVisible(IBinder token) {
4992        synchronized(this) {
4993            ActivityStack stack = ActivityRecord.getStackLocked(token);
4994            if (stack != null) {
4995                return stack.willActivityBeVisibleLocked(token);
4996            }
4997            return false;
4998        }
4999    }
5000
5001    @Override
5002    public void overridePendingTransition(IBinder token, String packageName,
5003            int enterAnim, int exitAnim) {
5004        synchronized(this) {
5005            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5006            if (self == null) {
5007                return;
5008            }
5009
5010            final long origId = Binder.clearCallingIdentity();
5011
5012            if (self.state == ActivityState.RESUMED
5013                    || self.state == ActivityState.PAUSING) {
5014                mWindowManager.overridePendingAppTransition(packageName,
5015                        enterAnim, exitAnim, null);
5016            }
5017
5018            Binder.restoreCallingIdentity(origId);
5019        }
5020    }
5021
5022    /**
5023     * Main function for removing an existing process from the activity manager
5024     * as a result of that process going away.  Clears out all connections
5025     * to the process.
5026     */
5027    private final void handleAppDiedLocked(ProcessRecord app,
5028            boolean restarting, boolean allowRestart) {
5029        int pid = app.pid;
5030        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5031        if (!kept && !restarting) {
5032            removeLruProcessLocked(app);
5033            if (pid > 0) {
5034                ProcessList.remove(pid);
5035            }
5036        }
5037
5038        if (mProfileProc == app) {
5039            clearProfilerLocked();
5040        }
5041
5042        // Remove this application's activities from active lists.
5043        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5044
5045        app.activities.clear();
5046
5047        if (app.instrumentationClass != null) {
5048            Slog.w(TAG, "Crash of app " + app.processName
5049                  + " running instrumentation " + app.instrumentationClass);
5050            Bundle info = new Bundle();
5051            info.putString("shortMsg", "Process crashed.");
5052            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5053        }
5054
5055        if (!restarting && hasVisibleActivities
5056                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5057            // If there was nothing to resume, and we are not already restarting this process, but
5058            // there is a visible activity that is hosted by the process...  then make sure all
5059            // visible activities are running, taking care of restarting this process.
5060            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5061        }
5062    }
5063
5064    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5065        IBinder threadBinder = thread.asBinder();
5066        // Find the application record.
5067        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5068            ProcessRecord rec = mLruProcesses.get(i);
5069            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5070                return i;
5071            }
5072        }
5073        return -1;
5074    }
5075
5076    final ProcessRecord getRecordForAppLocked(
5077            IApplicationThread thread) {
5078        if (thread == null) {
5079            return null;
5080        }
5081
5082        int appIndex = getLRURecordIndexForAppLocked(thread);
5083        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5084    }
5085
5086    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5087        // If there are no longer any background processes running,
5088        // and the app that died was not running instrumentation,
5089        // then tell everyone we are now low on memory.
5090        boolean haveBg = false;
5091        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5092            ProcessRecord rec = mLruProcesses.get(i);
5093            if (rec.thread != null
5094                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5095                haveBg = true;
5096                break;
5097            }
5098        }
5099
5100        if (!haveBg) {
5101            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5102            if (doReport) {
5103                long now = SystemClock.uptimeMillis();
5104                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5105                    doReport = false;
5106                } else {
5107                    mLastMemUsageReportTime = now;
5108                }
5109            }
5110            final ArrayList<ProcessMemInfo> memInfos
5111                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5112            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5113            long now = SystemClock.uptimeMillis();
5114            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5115                ProcessRecord rec = mLruProcesses.get(i);
5116                if (rec == dyingProc || rec.thread == null) {
5117                    continue;
5118                }
5119                if (doReport) {
5120                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5121                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5122                }
5123                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5124                    // The low memory report is overriding any current
5125                    // state for a GC request.  Make sure to do
5126                    // heavy/important/visible/foreground processes first.
5127                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5128                        rec.lastRequestedGc = 0;
5129                    } else {
5130                        rec.lastRequestedGc = rec.lastLowMemory;
5131                    }
5132                    rec.reportLowMemory = true;
5133                    rec.lastLowMemory = now;
5134                    mProcessesToGc.remove(rec);
5135                    addProcessToGcListLocked(rec);
5136                }
5137            }
5138            if (doReport) {
5139                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5140                mHandler.sendMessage(msg);
5141            }
5142            scheduleAppGcsLocked();
5143        }
5144    }
5145
5146    final void appDiedLocked(ProcessRecord app) {
5147       appDiedLocked(app, app.pid, app.thread, false);
5148    }
5149
5150    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5151            boolean fromBinderDied) {
5152        // First check if this ProcessRecord is actually active for the pid.
5153        synchronized (mPidsSelfLocked) {
5154            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5155            if (curProc != app) {
5156                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5157                return;
5158            }
5159        }
5160
5161        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5162        synchronized (stats) {
5163            stats.noteProcessDiedLocked(app.info.uid, pid);
5164        }
5165
5166        if (!app.killed) {
5167            if (!fromBinderDied) {
5168                Process.killProcessQuiet(pid);
5169            }
5170            killProcessGroup(app.uid, pid);
5171            app.killed = true;
5172        }
5173
5174        // Clean up already done if the process has been re-started.
5175        if (app.pid == pid && app.thread != null &&
5176                app.thread.asBinder() == thread.asBinder()) {
5177            boolean doLowMem = app.instrumentationClass == null;
5178            boolean doOomAdj = doLowMem;
5179            if (!app.killedByAm) {
5180                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5181                        + ") has died");
5182                mAllowLowerMemLevel = true;
5183            } else {
5184                // Note that we always want to do oom adj to update our state with the
5185                // new number of procs.
5186                mAllowLowerMemLevel = false;
5187                doLowMem = false;
5188            }
5189            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5190            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5191                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5192            handleAppDiedLocked(app, false, true);
5193
5194            if (doOomAdj) {
5195                updateOomAdjLocked();
5196            }
5197            if (doLowMem) {
5198                doLowMemReportIfNeededLocked(app);
5199            }
5200        } else if (app.pid != pid) {
5201            // A new process has already been started.
5202            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5203                    + ") has died and restarted (pid " + app.pid + ").");
5204            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5205        } else if (DEBUG_PROCESSES) {
5206            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5207                    + thread.asBinder());
5208        }
5209    }
5210
5211    /**
5212     * If a stack trace dump file is configured, dump process stack traces.
5213     * @param clearTraces causes the dump file to be erased prior to the new
5214     *    traces being written, if true; when false, the new traces will be
5215     *    appended to any existing file content.
5216     * @param firstPids of dalvik VM processes to dump stack traces for first
5217     * @param lastPids of dalvik VM processes to dump stack traces for last
5218     * @param nativeProcs optional list of native process names to dump stack crawls
5219     * @return file containing stack traces, or null if no dump file is configured
5220     */
5221    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5222            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5223        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5224        if (tracesPath == null || tracesPath.length() == 0) {
5225            return null;
5226        }
5227
5228        File tracesFile = new File(tracesPath);
5229        try {
5230            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5231            tracesFile.createNewFile();
5232            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5233        } catch (IOException e) {
5234            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5235            return null;
5236        }
5237
5238        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5239        return tracesFile;
5240    }
5241
5242    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5243            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5244        // Use a FileObserver to detect when traces finish writing.
5245        // The order of traces is considered important to maintain for legibility.
5246        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5247            @Override
5248            public synchronized void onEvent(int event, String path) { notify(); }
5249        };
5250
5251        try {
5252            observer.startWatching();
5253
5254            // First collect all of the stacks of the most important pids.
5255            if (firstPids != null) {
5256                try {
5257                    int num = firstPids.size();
5258                    for (int i = 0; i < num; i++) {
5259                        synchronized (observer) {
5260                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5261                                    + firstPids.get(i));
5262                            final long sime = SystemClock.elapsedRealtime();
5263                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5264                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5265                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5266                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5267                        }
5268                    }
5269                } catch (InterruptedException e) {
5270                    Slog.wtf(TAG, e);
5271                }
5272            }
5273
5274            // Next collect the stacks of the native pids
5275            if (nativeProcs != null) {
5276                int[] pids = Process.getPidsForCommands(nativeProcs);
5277                if (pids != null) {
5278                    for (int pid : pids) {
5279                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5280                        final long sime = SystemClock.elapsedRealtime();
5281                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5282                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5283                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5284                    }
5285                }
5286            }
5287
5288            // Lastly, measure CPU usage.
5289            if (processCpuTracker != null) {
5290                processCpuTracker.init();
5291                System.gc();
5292                processCpuTracker.update();
5293                try {
5294                    synchronized (processCpuTracker) {
5295                        processCpuTracker.wait(500); // measure over 1/2 second.
5296                    }
5297                } catch (InterruptedException e) {
5298                }
5299                processCpuTracker.update();
5300
5301                // We'll take the stack crawls of just the top apps using CPU.
5302                final int N = processCpuTracker.countWorkingStats();
5303                int numProcs = 0;
5304                for (int i=0; i<N && numProcs<5; i++) {
5305                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5306                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5307                        numProcs++;
5308                        try {
5309                            synchronized (observer) {
5310                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5311                                        + stats.pid);
5312                                final long stime = SystemClock.elapsedRealtime();
5313                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5314                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5315                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5316                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5317                            }
5318                        } catch (InterruptedException e) {
5319                            Slog.wtf(TAG, e);
5320                        }
5321                    } else if (DEBUG_ANR) {
5322                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5323                                + stats.pid);
5324                    }
5325                }
5326            }
5327        } finally {
5328            observer.stopWatching();
5329        }
5330    }
5331
5332    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5333        if (true || IS_USER_BUILD) {
5334            return;
5335        }
5336        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5337        if (tracesPath == null || tracesPath.length() == 0) {
5338            return;
5339        }
5340
5341        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5342        StrictMode.allowThreadDiskWrites();
5343        try {
5344            final File tracesFile = new File(tracesPath);
5345            final File tracesDir = tracesFile.getParentFile();
5346            final File tracesTmp = new File(tracesDir, "__tmp__");
5347            try {
5348                if (tracesFile.exists()) {
5349                    tracesTmp.delete();
5350                    tracesFile.renameTo(tracesTmp);
5351                }
5352                StringBuilder sb = new StringBuilder();
5353                Time tobj = new Time();
5354                tobj.set(System.currentTimeMillis());
5355                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5356                sb.append(": ");
5357                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5358                sb.append(" since ");
5359                sb.append(msg);
5360                FileOutputStream fos = new FileOutputStream(tracesFile);
5361                fos.write(sb.toString().getBytes());
5362                if (app == null) {
5363                    fos.write("\n*** No application process!".getBytes());
5364                }
5365                fos.close();
5366                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5367            } catch (IOException e) {
5368                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5369                return;
5370            }
5371
5372            if (app != null) {
5373                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5374                firstPids.add(app.pid);
5375                dumpStackTraces(tracesPath, firstPids, null, null, null);
5376            }
5377
5378            File lastTracesFile = null;
5379            File curTracesFile = null;
5380            for (int i=9; i>=0; i--) {
5381                String name = String.format(Locale.US, "slow%02d.txt", i);
5382                curTracesFile = new File(tracesDir, name);
5383                if (curTracesFile.exists()) {
5384                    if (lastTracesFile != null) {
5385                        curTracesFile.renameTo(lastTracesFile);
5386                    } else {
5387                        curTracesFile.delete();
5388                    }
5389                }
5390                lastTracesFile = curTracesFile;
5391            }
5392            tracesFile.renameTo(curTracesFile);
5393            if (tracesTmp.exists()) {
5394                tracesTmp.renameTo(tracesFile);
5395            }
5396        } finally {
5397            StrictMode.setThreadPolicy(oldPolicy);
5398        }
5399    }
5400
5401    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5402        if (!mLaunchWarningShown) {
5403            mLaunchWarningShown = true;
5404            mUiHandler.post(new Runnable() {
5405                @Override
5406                public void run() {
5407                    synchronized (ActivityManagerService.this) {
5408                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5409                        d.show();
5410                        mUiHandler.postDelayed(new Runnable() {
5411                            @Override
5412                            public void run() {
5413                                synchronized (ActivityManagerService.this) {
5414                                    d.dismiss();
5415                                    mLaunchWarningShown = false;
5416                                }
5417                            }
5418                        }, 4000);
5419                    }
5420                }
5421            });
5422        }
5423    }
5424
5425    @Override
5426    public boolean clearApplicationUserData(final String packageName,
5427            final IPackageDataObserver observer, int userId) {
5428        enforceNotIsolatedCaller("clearApplicationUserData");
5429        int uid = Binder.getCallingUid();
5430        int pid = Binder.getCallingPid();
5431        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5432                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5433
5434
5435        long callingId = Binder.clearCallingIdentity();
5436        try {
5437            IPackageManager pm = AppGlobals.getPackageManager();
5438            int pkgUid = -1;
5439            synchronized(this) {
5440                if (getPackageManagerInternalLocked().isPackageDataProtected(
5441                        userId, packageName)) {
5442                    throw new SecurityException(
5443                            "Cannot clear data for a protected package: " + packageName);
5444                }
5445
5446                try {
5447                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5448                } catch (RemoteException e) {
5449                }
5450                if (pkgUid == -1) {
5451                    Slog.w(TAG, "Invalid packageName: " + packageName);
5452                    if (observer != null) {
5453                        try {
5454                            observer.onRemoveCompleted(packageName, false);
5455                        } catch (RemoteException e) {
5456                            Slog.i(TAG, "Observer no longer exists.");
5457                        }
5458                    }
5459                    return false;
5460                }
5461                if (uid == pkgUid || checkComponentPermission(
5462                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5463                        pid, uid, -1, true)
5464                        == PackageManager.PERMISSION_GRANTED) {
5465                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5466                } else {
5467                    throw new SecurityException("PID " + pid + " does not have permission "
5468                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5469                                    + " of package " + packageName);
5470                }
5471
5472                // Remove all tasks match the cleared application package and user
5473                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5474                    final TaskRecord tr = mRecentTasks.get(i);
5475                    final String taskPackageName =
5476                            tr.getBaseIntent().getComponent().getPackageName();
5477                    if (tr.userId != userId) continue;
5478                    if (!taskPackageName.equals(packageName)) continue;
5479                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5480                }
5481            }
5482
5483            final int pkgUidF = pkgUid;
5484            final int userIdF = userId;
5485            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5486                @Override
5487                public void onRemoveCompleted(String packageName, boolean succeeded)
5488                        throws RemoteException {
5489                    synchronized (ActivityManagerService.this) {
5490                        finishForceStopPackageLocked(packageName, pkgUidF);
5491                    }
5492
5493                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5494                            Uri.fromParts("package", packageName, null));
5495                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5496                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5497                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5498                            null, null, 0, null, null, null, null, false, false, userIdF);
5499
5500                    if (observer != null) {
5501                        observer.onRemoveCompleted(packageName, succeeded);
5502                    }
5503                }
5504            };
5505
5506            try {
5507                // Clear application user data
5508                pm.clearApplicationUserData(packageName, localObserver, userId);
5509
5510                synchronized(this) {
5511                    // Remove all permissions granted from/to this package
5512                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5513                }
5514
5515                // Remove all zen rules created by this package; revoke it's zen access.
5516                INotificationManager inm = NotificationManager.getService();
5517                inm.removeAutomaticZenRules(packageName);
5518                inm.setNotificationPolicyAccessGranted(packageName, false);
5519
5520            } catch (RemoteException e) {
5521            }
5522        } finally {
5523            Binder.restoreCallingIdentity(callingId);
5524        }
5525        return true;
5526    }
5527
5528    @Override
5529    public void killBackgroundProcesses(final String packageName, int userId) {
5530        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5531                != PackageManager.PERMISSION_GRANTED &&
5532                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5533                        != PackageManager.PERMISSION_GRANTED) {
5534            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5535                    + Binder.getCallingPid()
5536                    + ", uid=" + Binder.getCallingUid()
5537                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5538            Slog.w(TAG, msg);
5539            throw new SecurityException(msg);
5540        }
5541
5542        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5543                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5544        long callingId = Binder.clearCallingIdentity();
5545        try {
5546            IPackageManager pm = AppGlobals.getPackageManager();
5547            synchronized(this) {
5548                int appId = -1;
5549                try {
5550                    appId = UserHandle.getAppId(
5551                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5552                } catch (RemoteException e) {
5553                }
5554                if (appId == -1) {
5555                    Slog.w(TAG, "Invalid packageName: " + packageName);
5556                    return;
5557                }
5558                killPackageProcessesLocked(packageName, appId, userId,
5559                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5560            }
5561        } finally {
5562            Binder.restoreCallingIdentity(callingId);
5563        }
5564    }
5565
5566    @Override
5567    public void killAllBackgroundProcesses() {
5568        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5569                != PackageManager.PERMISSION_GRANTED) {
5570            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5571                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5572                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5573            Slog.w(TAG, msg);
5574            throw new SecurityException(msg);
5575        }
5576
5577        final long callingId = Binder.clearCallingIdentity();
5578        try {
5579            synchronized (this) {
5580                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5581                final int NP = mProcessNames.getMap().size();
5582                for (int ip = 0; ip < NP; ip++) {
5583                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5584                    final int NA = apps.size();
5585                    for (int ia = 0; ia < NA; ia++) {
5586                        final ProcessRecord app = apps.valueAt(ia);
5587                        if (app.persistent) {
5588                            // We don't kill persistent processes.
5589                            continue;
5590                        }
5591                        if (app.removed) {
5592                            procs.add(app);
5593                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5594                            app.removed = true;
5595                            procs.add(app);
5596                        }
5597                    }
5598                }
5599
5600                final int N = procs.size();
5601                for (int i = 0; i < N; i++) {
5602                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5603                }
5604
5605                mAllowLowerMemLevel = true;
5606
5607                updateOomAdjLocked();
5608                doLowMemReportIfNeededLocked(null);
5609            }
5610        } finally {
5611            Binder.restoreCallingIdentity(callingId);
5612        }
5613    }
5614
5615    /**
5616     * Kills all background processes, except those matching any of the
5617     * specified properties.
5618     *
5619     * @param minTargetSdk the target SDK version at or above which to preserve
5620     *                     processes, or {@code -1} to ignore the target SDK
5621     * @param maxProcState the process state at or below which to preserve
5622     *                     processes, or {@code -1} to ignore the process state
5623     */
5624    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5625        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5626                != PackageManager.PERMISSION_GRANTED) {
5627            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5628                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5629                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5630            Slog.w(TAG, msg);
5631            throw new SecurityException(msg);
5632        }
5633
5634        final long callingId = Binder.clearCallingIdentity();
5635        try {
5636            synchronized (this) {
5637                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5638                final int NP = mProcessNames.getMap().size();
5639                for (int ip = 0; ip < NP; ip++) {
5640                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5641                    final int NA = apps.size();
5642                    for (int ia = 0; ia < NA; ia++) {
5643                        final ProcessRecord app = apps.valueAt(ia);
5644                        if (app.removed) {
5645                            procs.add(app);
5646                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5647                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5648                            app.removed = true;
5649                            procs.add(app);
5650                        }
5651                    }
5652                }
5653
5654                final int N = procs.size();
5655                for (int i = 0; i < N; i++) {
5656                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5657                }
5658            }
5659        } finally {
5660            Binder.restoreCallingIdentity(callingId);
5661        }
5662    }
5663
5664    @Override
5665    public void forceStopPackage(final String packageName, int userId) {
5666        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5667                != PackageManager.PERMISSION_GRANTED) {
5668            String msg = "Permission Denial: forceStopPackage() from pid="
5669                    + Binder.getCallingPid()
5670                    + ", uid=" + Binder.getCallingUid()
5671                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5672            Slog.w(TAG, msg);
5673            throw new SecurityException(msg);
5674        }
5675        final int callingPid = Binder.getCallingPid();
5676        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5677                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5678        long callingId = Binder.clearCallingIdentity();
5679        try {
5680            IPackageManager pm = AppGlobals.getPackageManager();
5681            synchronized(this) {
5682                int[] users = userId == UserHandle.USER_ALL
5683                        ? mUserController.getUsers() : new int[] { userId };
5684                for (int user : users) {
5685                    int pkgUid = -1;
5686                    try {
5687                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5688                                user);
5689                    } catch (RemoteException e) {
5690                    }
5691                    if (pkgUid == -1) {
5692                        Slog.w(TAG, "Invalid packageName: " + packageName);
5693                        continue;
5694                    }
5695                    try {
5696                        pm.setPackageStoppedState(packageName, true, user);
5697                    } catch (RemoteException e) {
5698                    } catch (IllegalArgumentException e) {
5699                        Slog.w(TAG, "Failed trying to unstop package "
5700                                + packageName + ": " + e);
5701                    }
5702                    if (mUserController.isUserRunningLocked(user, 0)) {
5703                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5704                        finishForceStopPackageLocked(packageName, pkgUid);
5705                    }
5706                }
5707            }
5708        } finally {
5709            Binder.restoreCallingIdentity(callingId);
5710        }
5711    }
5712
5713    @Override
5714    public void addPackageDependency(String packageName) {
5715        synchronized (this) {
5716            int callingPid = Binder.getCallingPid();
5717            if (callingPid == Process.myPid()) {
5718                //  Yeah, um, no.
5719                return;
5720            }
5721            ProcessRecord proc;
5722            synchronized (mPidsSelfLocked) {
5723                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5724            }
5725            if (proc != null) {
5726                if (proc.pkgDeps == null) {
5727                    proc.pkgDeps = new ArraySet<String>(1);
5728                }
5729                proc.pkgDeps.add(packageName);
5730            }
5731        }
5732    }
5733
5734    /*
5735     * The pkg name and app id have to be specified.
5736     */
5737    @Override
5738    public void killApplication(String pkg, int appId, int userId, String reason) {
5739        if (pkg == null) {
5740            return;
5741        }
5742        // Make sure the uid is valid.
5743        if (appId < 0) {
5744            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5745            return;
5746        }
5747        int callerUid = Binder.getCallingUid();
5748        // Only the system server can kill an application
5749        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5750            // Post an aysnc message to kill the application
5751            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5752            msg.arg1 = appId;
5753            msg.arg2 = userId;
5754            Bundle bundle = new Bundle();
5755            bundle.putString("pkg", pkg);
5756            bundle.putString("reason", reason);
5757            msg.obj = bundle;
5758            mHandler.sendMessage(msg);
5759        } else {
5760            throw new SecurityException(callerUid + " cannot kill pkg: " +
5761                    pkg);
5762        }
5763    }
5764
5765    @Override
5766    public void closeSystemDialogs(String reason) {
5767        enforceNotIsolatedCaller("closeSystemDialogs");
5768
5769        final int pid = Binder.getCallingPid();
5770        final int uid = Binder.getCallingUid();
5771        final long origId = Binder.clearCallingIdentity();
5772        try {
5773            synchronized (this) {
5774                // Only allow this from foreground processes, so that background
5775                // applications can't abuse it to prevent system UI from being shown.
5776                if (uid >= Process.FIRST_APPLICATION_UID) {
5777                    ProcessRecord proc;
5778                    synchronized (mPidsSelfLocked) {
5779                        proc = mPidsSelfLocked.get(pid);
5780                    }
5781                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5782                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5783                                + " from background process " + proc);
5784                        return;
5785                    }
5786                }
5787                closeSystemDialogsLocked(reason);
5788            }
5789        } finally {
5790            Binder.restoreCallingIdentity(origId);
5791        }
5792    }
5793
5794    void closeSystemDialogsLocked(String reason) {
5795        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5796        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5797                | Intent.FLAG_RECEIVER_FOREGROUND);
5798        if (reason != null) {
5799            intent.putExtra("reason", reason);
5800        }
5801        mWindowManager.closeSystemDialogs(reason);
5802
5803        mStackSupervisor.closeSystemDialogsLocked();
5804
5805        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5806                AppOpsManager.OP_NONE, null, false, false,
5807                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5808    }
5809
5810    @Override
5811    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5812        enforceNotIsolatedCaller("getProcessMemoryInfo");
5813        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5814        for (int i=pids.length-1; i>=0; i--) {
5815            ProcessRecord proc;
5816            int oomAdj;
5817            synchronized (this) {
5818                synchronized (mPidsSelfLocked) {
5819                    proc = mPidsSelfLocked.get(pids[i]);
5820                    oomAdj = proc != null ? proc.setAdj : 0;
5821                }
5822            }
5823            infos[i] = new Debug.MemoryInfo();
5824            Debug.getMemoryInfo(pids[i], infos[i]);
5825            if (proc != null) {
5826                synchronized (this) {
5827                    if (proc.thread != null && proc.setAdj == oomAdj) {
5828                        // Record this for posterity if the process has been stable.
5829                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5830                                infos[i].getTotalUss(), false, proc.pkgList);
5831                    }
5832                }
5833            }
5834        }
5835        return infos;
5836    }
5837
5838    @Override
5839    public long[] getProcessPss(int[] pids) {
5840        enforceNotIsolatedCaller("getProcessPss");
5841        long[] pss = new long[pids.length];
5842        for (int i=pids.length-1; i>=0; i--) {
5843            ProcessRecord proc;
5844            int oomAdj;
5845            synchronized (this) {
5846                synchronized (mPidsSelfLocked) {
5847                    proc = mPidsSelfLocked.get(pids[i]);
5848                    oomAdj = proc != null ? proc.setAdj : 0;
5849                }
5850            }
5851            long[] tmpUss = new long[1];
5852            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5853            if (proc != null) {
5854                synchronized (this) {
5855                    if (proc.thread != null && proc.setAdj == oomAdj) {
5856                        // Record this for posterity if the process has been stable.
5857                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5858                    }
5859                }
5860            }
5861        }
5862        return pss;
5863    }
5864
5865    @Override
5866    public void killApplicationProcess(String processName, int uid) {
5867        if (processName == null) {
5868            return;
5869        }
5870
5871        int callerUid = Binder.getCallingUid();
5872        // Only the system server can kill an application
5873        if (callerUid == Process.SYSTEM_UID) {
5874            synchronized (this) {
5875                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5876                if (app != null && app.thread != null) {
5877                    try {
5878                        app.thread.scheduleSuicide();
5879                    } catch (RemoteException e) {
5880                        // If the other end already died, then our work here is done.
5881                    }
5882                } else {
5883                    Slog.w(TAG, "Process/uid not found attempting kill of "
5884                            + processName + " / " + uid);
5885                }
5886            }
5887        } else {
5888            throw new SecurityException(callerUid + " cannot kill app process: " +
5889                    processName);
5890        }
5891    }
5892
5893    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5894        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5895                false, true, false, false, UserHandle.getUserId(uid), reason);
5896    }
5897
5898    private void finishForceStopPackageLocked(final String packageName, int uid) {
5899        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5900                Uri.fromParts("package", packageName, null));
5901        if (!mProcessesReady) {
5902            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5903                    | Intent.FLAG_RECEIVER_FOREGROUND);
5904        }
5905        intent.putExtra(Intent.EXTRA_UID, uid);
5906        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5907        broadcastIntentLocked(null, null, intent,
5908                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5909                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5910    }
5911
5912
5913    private final boolean killPackageProcessesLocked(String packageName, int appId,
5914            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5915            boolean doit, boolean evenPersistent, String reason) {
5916        ArrayList<ProcessRecord> procs = new ArrayList<>();
5917
5918        // Remove all processes this package may have touched: all with the
5919        // same UID (except for the system or root user), and all whose name
5920        // matches the package name.
5921        final int NP = mProcessNames.getMap().size();
5922        for (int ip=0; ip<NP; ip++) {
5923            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5924            final int NA = apps.size();
5925            for (int ia=0; ia<NA; ia++) {
5926                ProcessRecord app = apps.valueAt(ia);
5927                if (app.persistent && !evenPersistent) {
5928                    // we don't kill persistent processes
5929                    continue;
5930                }
5931                if (app.removed) {
5932                    if (doit) {
5933                        procs.add(app);
5934                    }
5935                    continue;
5936                }
5937
5938                // Skip process if it doesn't meet our oom adj requirement.
5939                if (app.setAdj < minOomAdj) {
5940                    continue;
5941                }
5942
5943                // If no package is specified, we call all processes under the
5944                // give user id.
5945                if (packageName == null) {
5946                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5947                        continue;
5948                    }
5949                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5950                        continue;
5951                    }
5952                // Package has been specified, we want to hit all processes
5953                // that match it.  We need to qualify this by the processes
5954                // that are running under the specified app and user ID.
5955                } else {
5956                    final boolean isDep = app.pkgDeps != null
5957                            && app.pkgDeps.contains(packageName);
5958                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5959                        continue;
5960                    }
5961                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5962                        continue;
5963                    }
5964                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5965                        continue;
5966                    }
5967                }
5968
5969                // Process has passed all conditions, kill it!
5970                if (!doit) {
5971                    return true;
5972                }
5973                app.removed = true;
5974                procs.add(app);
5975            }
5976        }
5977
5978        int N = procs.size();
5979        for (int i=0; i<N; i++) {
5980            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5981        }
5982        updateOomAdjLocked();
5983        return N > 0;
5984    }
5985
5986    private void cleanupDisabledPackageComponentsLocked(
5987            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5988
5989        Set<String> disabledClasses = null;
5990        boolean packageDisabled = false;
5991        IPackageManager pm = AppGlobals.getPackageManager();
5992
5993        if (changedClasses == null) {
5994            // Nothing changed...
5995            return;
5996        }
5997
5998        // Determine enable/disable state of the package and its components.
5999        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6000        for (int i = changedClasses.length - 1; i >= 0; i--) {
6001            final String changedClass = changedClasses[i];
6002
6003            if (changedClass.equals(packageName)) {
6004                try {
6005                    // Entire package setting changed
6006                    enabled = pm.getApplicationEnabledSetting(packageName,
6007                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6008                } catch (Exception e) {
6009                    // No such package/component; probably racing with uninstall.  In any
6010                    // event it means we have nothing further to do here.
6011                    return;
6012                }
6013                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6014                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6015                if (packageDisabled) {
6016                    // Entire package is disabled.
6017                    // No need to continue to check component states.
6018                    disabledClasses = null;
6019                    break;
6020                }
6021            } else {
6022                try {
6023                    enabled = pm.getComponentEnabledSetting(
6024                            new ComponentName(packageName, changedClass),
6025                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6026                } catch (Exception e) {
6027                    // As above, probably racing with uninstall.
6028                    return;
6029                }
6030                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6031                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6032                    if (disabledClasses == null) {
6033                        disabledClasses = new ArraySet<>(changedClasses.length);
6034                    }
6035                    disabledClasses.add(changedClass);
6036                }
6037            }
6038        }
6039
6040        if (!packageDisabled && disabledClasses == null) {
6041            // Nothing to do here...
6042            return;
6043        }
6044
6045        // Clean-up disabled activities.
6046        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6047                packageName, disabledClasses, true, false, userId) && mBooted) {
6048            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6049            mStackSupervisor.scheduleIdleLocked();
6050        }
6051
6052        // Clean-up disabled tasks
6053        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6054
6055        // Clean-up disabled services.
6056        mServices.bringDownDisabledPackageServicesLocked(
6057                packageName, disabledClasses, userId, false, killProcess, true);
6058
6059        // Clean-up disabled providers.
6060        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6061        mProviderMap.collectPackageProvidersLocked(
6062                packageName, disabledClasses, true, false, userId, providers);
6063        for (int i = providers.size() - 1; i >= 0; i--) {
6064            removeDyingProviderLocked(null, providers.get(i), true);
6065        }
6066
6067        // Clean-up disabled broadcast receivers.
6068        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6069            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6070                    packageName, disabledClasses, userId, true);
6071        }
6072
6073    }
6074
6075    final boolean clearBroadcastQueueForUserLocked(int userId) {
6076        boolean didSomething = false;
6077        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6078            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6079                    null, null, userId, true);
6080        }
6081        return didSomething;
6082    }
6083
6084    final boolean forceStopPackageLocked(String packageName, int appId,
6085            boolean callerWillRestart, boolean purgeCache, boolean doit,
6086            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6087        int i;
6088
6089        if (userId == UserHandle.USER_ALL && packageName == null) {
6090            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6091        }
6092
6093        if (appId < 0 && packageName != null) {
6094            try {
6095                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6096                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6097            } catch (RemoteException e) {
6098            }
6099        }
6100
6101        if (doit) {
6102            if (packageName != null) {
6103                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6104                        + " user=" + userId + ": " + reason);
6105            } else {
6106                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6107            }
6108
6109            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6110        }
6111
6112        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6113                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6114                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6115
6116        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6117                packageName, null, doit, evenPersistent, userId)) {
6118            if (!doit) {
6119                return true;
6120            }
6121            didSomething = true;
6122        }
6123
6124        if (mServices.bringDownDisabledPackageServicesLocked(
6125                packageName, null, userId, evenPersistent, true, doit)) {
6126            if (!doit) {
6127                return true;
6128            }
6129            didSomething = true;
6130        }
6131
6132        if (packageName == null) {
6133            // Remove all sticky broadcasts from this user.
6134            mStickyBroadcasts.remove(userId);
6135        }
6136
6137        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6138        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6139                userId, providers)) {
6140            if (!doit) {
6141                return true;
6142            }
6143            didSomething = true;
6144        }
6145        for (i = providers.size() - 1; i >= 0; i--) {
6146            removeDyingProviderLocked(null, providers.get(i), true);
6147        }
6148
6149        // Remove transient permissions granted from/to this package/user
6150        removeUriPermissionsForPackageLocked(packageName, userId, false);
6151
6152        if (doit) {
6153            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6154                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6155                        packageName, null, userId, doit);
6156            }
6157        }
6158
6159        if (packageName == null || uninstalling) {
6160            // Remove pending intents.  For now we only do this when force
6161            // stopping users, because we have some problems when doing this
6162            // for packages -- app widgets are not currently cleaned up for
6163            // such packages, so they can be left with bad pending intents.
6164            if (mIntentSenderRecords.size() > 0) {
6165                Iterator<WeakReference<PendingIntentRecord>> it
6166                        = mIntentSenderRecords.values().iterator();
6167                while (it.hasNext()) {
6168                    WeakReference<PendingIntentRecord> wpir = it.next();
6169                    if (wpir == null) {
6170                        it.remove();
6171                        continue;
6172                    }
6173                    PendingIntentRecord pir = wpir.get();
6174                    if (pir == null) {
6175                        it.remove();
6176                        continue;
6177                    }
6178                    if (packageName == null) {
6179                        // Stopping user, remove all objects for the user.
6180                        if (pir.key.userId != userId) {
6181                            // Not the same user, skip it.
6182                            continue;
6183                        }
6184                    } else {
6185                        if (UserHandle.getAppId(pir.uid) != appId) {
6186                            // Different app id, skip it.
6187                            continue;
6188                        }
6189                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6190                            // Different user, skip it.
6191                            continue;
6192                        }
6193                        if (!pir.key.packageName.equals(packageName)) {
6194                            // Different package, skip it.
6195                            continue;
6196                        }
6197                    }
6198                    if (!doit) {
6199                        return true;
6200                    }
6201                    didSomething = true;
6202                    it.remove();
6203                    pir.canceled = true;
6204                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6205                        pir.key.activity.pendingResults.remove(pir.ref);
6206                    }
6207                }
6208            }
6209        }
6210
6211        if (doit) {
6212            if (purgeCache && packageName != null) {
6213                AttributeCache ac = AttributeCache.instance();
6214                if (ac != null) {
6215                    ac.removePackage(packageName);
6216                }
6217            }
6218            if (mBooted) {
6219                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6220                mStackSupervisor.scheduleIdleLocked();
6221            }
6222        }
6223
6224        return didSomething;
6225    }
6226
6227    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6228        ProcessRecord old = mProcessNames.remove(name, uid);
6229        if (old != null) {
6230            old.uidRecord.numProcs--;
6231            if (old.uidRecord.numProcs == 0) {
6232                // No more processes using this uid, tell clients it is gone.
6233                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6234                        "No more processes in " + old.uidRecord);
6235                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6236                mActiveUids.remove(uid);
6237                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6238            }
6239            old.uidRecord = null;
6240        }
6241        mIsolatedProcesses.remove(uid);
6242        return old;
6243    }
6244
6245    private final void addProcessNameLocked(ProcessRecord proc) {
6246        // We shouldn't already have a process under this name, but just in case we
6247        // need to clean up whatever may be there now.
6248        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6249        if (old == proc && proc.persistent) {
6250            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6251            Slog.w(TAG, "Re-adding persistent process " + proc);
6252        } else if (old != null) {
6253            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6254        }
6255        UidRecord uidRec = mActiveUids.get(proc.uid);
6256        if (uidRec == null) {
6257            uidRec = new UidRecord(proc.uid);
6258            // This is the first appearance of the uid, report it now!
6259            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6260                    "Creating new process uid: " + uidRec);
6261            mActiveUids.put(proc.uid, uidRec);
6262            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6263            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6264        }
6265        proc.uidRecord = uidRec;
6266        uidRec.numProcs++;
6267        mProcessNames.put(proc.processName, proc.uid, proc);
6268        if (proc.isolated) {
6269            mIsolatedProcesses.put(proc.uid, proc);
6270        }
6271    }
6272
6273    boolean removeProcessLocked(ProcessRecord app,
6274            boolean callerWillRestart, boolean allowRestart, String reason) {
6275        final String name = app.processName;
6276        final int uid = app.uid;
6277        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6278            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6279
6280        ProcessRecord old = mProcessNames.get(name, uid);
6281        if (old != app) {
6282            // This process is no longer active, so nothing to do.
6283            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6284            return false;
6285        }
6286        removeProcessNameLocked(name, uid);
6287        if (mHeavyWeightProcess == app) {
6288            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6289                    mHeavyWeightProcess.userId, 0));
6290            mHeavyWeightProcess = null;
6291        }
6292        boolean needRestart = false;
6293        if (app.pid > 0 && app.pid != MY_PID) {
6294            int pid = app.pid;
6295            synchronized (mPidsSelfLocked) {
6296                mPidsSelfLocked.remove(pid);
6297                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6298            }
6299            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6300            if (app.isolated) {
6301                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6302            }
6303            boolean willRestart = false;
6304            if (app.persistent && !app.isolated) {
6305                if (!callerWillRestart) {
6306                    willRestart = true;
6307                } else {
6308                    needRestart = true;
6309                }
6310            }
6311            app.kill(reason, true);
6312            handleAppDiedLocked(app, willRestart, allowRestart);
6313            if (willRestart) {
6314                removeLruProcessLocked(app);
6315                addAppLocked(app.info, false, null /* ABI override */);
6316            }
6317        } else {
6318            mRemovedProcesses.add(app);
6319        }
6320
6321        return needRestart;
6322    }
6323
6324    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6325        cleanupAppInLaunchingProvidersLocked(app, true);
6326        removeProcessLocked(app, false, true, "timeout publishing content providers");
6327    }
6328
6329    private final void processStartTimedOutLocked(ProcessRecord app) {
6330        final int pid = app.pid;
6331        boolean gone = false;
6332        synchronized (mPidsSelfLocked) {
6333            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6334            if (knownApp != null && knownApp.thread == null) {
6335                mPidsSelfLocked.remove(pid);
6336                gone = true;
6337            }
6338        }
6339
6340        if (gone) {
6341            Slog.w(TAG, "Process " + app + " failed to attach");
6342            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6343                    pid, app.uid, app.processName);
6344            removeProcessNameLocked(app.processName, app.uid);
6345            if (mHeavyWeightProcess == app) {
6346                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6347                        mHeavyWeightProcess.userId, 0));
6348                mHeavyWeightProcess = null;
6349            }
6350            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6351            if (app.isolated) {
6352                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6353            }
6354            // Take care of any launching providers waiting for this process.
6355            cleanupAppInLaunchingProvidersLocked(app, true);
6356            // Take care of any services that are waiting for the process.
6357            mServices.processStartTimedOutLocked(app);
6358            app.kill("start timeout", true);
6359            removeLruProcessLocked(app);
6360            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6361                Slog.w(TAG, "Unattached app died before backup, skipping");
6362                try {
6363                    IBackupManager bm = IBackupManager.Stub.asInterface(
6364                            ServiceManager.getService(Context.BACKUP_SERVICE));
6365                    bm.agentDisconnected(app.info.packageName);
6366                } catch (RemoteException e) {
6367                    // Can't happen; the backup manager is local
6368                }
6369            }
6370            if (isPendingBroadcastProcessLocked(pid)) {
6371                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6372                skipPendingBroadcastLocked(pid);
6373            }
6374        } else {
6375            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6376        }
6377    }
6378
6379    private final boolean attachApplicationLocked(IApplicationThread thread,
6380            int pid) {
6381
6382        // Find the application record that is being attached...  either via
6383        // the pid if we are running in multiple processes, or just pull the
6384        // next app record if we are emulating process with anonymous threads.
6385        ProcessRecord app;
6386        if (pid != MY_PID && pid >= 0) {
6387            synchronized (mPidsSelfLocked) {
6388                app = mPidsSelfLocked.get(pid);
6389            }
6390        } else {
6391            app = null;
6392        }
6393
6394        if (app == null) {
6395            Slog.w(TAG, "No pending application record for pid " + pid
6396                    + " (IApplicationThread " + thread + "); dropping process");
6397            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6398            if (pid > 0 && pid != MY_PID) {
6399                Process.killProcessQuiet(pid);
6400                //TODO: killProcessGroup(app.info.uid, pid);
6401            } else {
6402                try {
6403                    thread.scheduleExit();
6404                } catch (Exception e) {
6405                    // Ignore exceptions.
6406                }
6407            }
6408            return false;
6409        }
6410
6411        // If this application record is still attached to a previous
6412        // process, clean it up now.
6413        if (app.thread != null) {
6414            handleAppDiedLocked(app, true, true);
6415        }
6416
6417        // Tell the process all about itself.
6418
6419        if (DEBUG_ALL) Slog.v(
6420                TAG, "Binding process pid " + pid + " to record " + app);
6421
6422        final String processName = app.processName;
6423        try {
6424            AppDeathRecipient adr = new AppDeathRecipient(
6425                    app, pid, thread);
6426            thread.asBinder().linkToDeath(adr, 0);
6427            app.deathRecipient = adr;
6428        } catch (RemoteException e) {
6429            app.resetPackageList(mProcessStats);
6430            startProcessLocked(app, "link fail", processName);
6431            return false;
6432        }
6433
6434        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6435
6436        app.makeActive(thread, mProcessStats);
6437        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6438        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6439        app.forcingToForeground = null;
6440        updateProcessForegroundLocked(app, false, false);
6441        app.hasShownUi = false;
6442        app.debugging = false;
6443        app.cached = false;
6444        app.killedByAm = false;
6445
6446        // We carefully use the same state that PackageManager uses for
6447        // filtering, since we use this flag to decide if we need to install
6448        // providers when user is unlocked later
6449        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6450
6451        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6452
6453        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6454        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6455
6456        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6457            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6458            msg.obj = app;
6459            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6460        }
6461
6462        if (!normalMode) {
6463            Slog.i(TAG, "Launching preboot mode app: " + app);
6464        }
6465
6466        if (DEBUG_ALL) Slog.v(
6467            TAG, "New app record " + app
6468            + " thread=" + thread.asBinder() + " pid=" + pid);
6469        try {
6470            int testMode = IApplicationThread.DEBUG_OFF;
6471            if (mDebugApp != null && mDebugApp.equals(processName)) {
6472                testMode = mWaitForDebugger
6473                    ? IApplicationThread.DEBUG_WAIT
6474                    : IApplicationThread.DEBUG_ON;
6475                app.debugging = true;
6476                if (mDebugTransient) {
6477                    mDebugApp = mOrigDebugApp;
6478                    mWaitForDebugger = mOrigWaitForDebugger;
6479                }
6480            }
6481            String profileFile = app.instrumentationProfileFile;
6482            ParcelFileDescriptor profileFd = null;
6483            int samplingInterval = 0;
6484            boolean profileAutoStop = false;
6485            if (mProfileApp != null && mProfileApp.equals(processName)) {
6486                mProfileProc = app;
6487                profileFile = mProfileFile;
6488                profileFd = mProfileFd;
6489                samplingInterval = mSamplingInterval;
6490                profileAutoStop = mAutoStopProfiler;
6491            }
6492            boolean enableTrackAllocation = false;
6493            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6494                enableTrackAllocation = true;
6495                mTrackAllocationApp = null;
6496            }
6497
6498            // If the app is being launched for restore or full backup, set it up specially
6499            boolean isRestrictedBackupMode = false;
6500            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6501                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6502                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6503                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6504                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6505            }
6506
6507            if (app.instrumentationClass != null) {
6508                notifyPackageUse(app.instrumentationClass.getPackageName(),
6509                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6510            }
6511            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6512                    + processName + " with config " + mConfiguration);
6513            ApplicationInfo appInfo = app.instrumentationInfo != null
6514                    ? app.instrumentationInfo : app.info;
6515            app.compat = compatibilityInfoForPackageLocked(appInfo);
6516            if (profileFd != null) {
6517                profileFd = profileFd.dup();
6518            }
6519            ProfilerInfo profilerInfo = profileFile == null ? null
6520                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6521            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6522                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6523                    app.instrumentationUiAutomationConnection, testMode,
6524                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6525                    isRestrictedBackupMode || !normalMode, app.persistent,
6526                    new Configuration(mConfiguration), app.compat,
6527                    getCommonServicesLocked(app.isolated),
6528                    mCoreSettingsObserver.getCoreSettingsLocked());
6529            updateLruProcessLocked(app, false, null);
6530            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6531        } catch (Exception e) {
6532            // todo: Yikes!  What should we do?  For now we will try to
6533            // start another process, but that could easily get us in
6534            // an infinite loop of restarting processes...
6535            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6536
6537            app.resetPackageList(mProcessStats);
6538            app.unlinkDeathRecipient();
6539            startProcessLocked(app, "bind fail", processName);
6540            return false;
6541        }
6542
6543        // Remove this record from the list of starting applications.
6544        mPersistentStartingProcesses.remove(app);
6545        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6546                "Attach application locked removing on hold: " + app);
6547        mProcessesOnHold.remove(app);
6548
6549        boolean badApp = false;
6550        boolean didSomething = false;
6551
6552        // See if the top visible activity is waiting to run in this process...
6553        if (normalMode) {
6554            try {
6555                if (mStackSupervisor.attachApplicationLocked(app)) {
6556                    didSomething = true;
6557                }
6558            } catch (Exception e) {
6559                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6560                badApp = true;
6561            }
6562        }
6563
6564        // Find any services that should be running in this process...
6565        if (!badApp) {
6566            try {
6567                didSomething |= mServices.attachApplicationLocked(app, processName);
6568            } catch (Exception e) {
6569                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6570                badApp = true;
6571            }
6572        }
6573
6574        // Check if a next-broadcast receiver is in this process...
6575        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6576            try {
6577                didSomething |= sendPendingBroadcastsLocked(app);
6578            } catch (Exception e) {
6579                // If the app died trying to launch the receiver we declare it 'bad'
6580                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6581                badApp = true;
6582            }
6583        }
6584
6585        // Check whether the next backup agent is in this process...
6586        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6587            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6588                    "New app is backup target, launching agent for " + app);
6589            notifyPackageUse(mBackupTarget.appInfo.packageName,
6590                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6591            try {
6592                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6593                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6594                        mBackupTarget.backupMode);
6595            } catch (Exception e) {
6596                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6597                badApp = true;
6598            }
6599        }
6600
6601        if (badApp) {
6602            app.kill("error during init", true);
6603            handleAppDiedLocked(app, false, true);
6604            return false;
6605        }
6606
6607        if (!didSomething) {
6608            updateOomAdjLocked();
6609        }
6610
6611        return true;
6612    }
6613
6614    @Override
6615    public final void attachApplication(IApplicationThread thread) {
6616        synchronized (this) {
6617            int callingPid = Binder.getCallingPid();
6618            final long origId = Binder.clearCallingIdentity();
6619            attachApplicationLocked(thread, callingPid);
6620            Binder.restoreCallingIdentity(origId);
6621        }
6622    }
6623
6624    @Override
6625    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6626        final long origId = Binder.clearCallingIdentity();
6627        synchronized (this) {
6628            ActivityStack stack = ActivityRecord.getStackLocked(token);
6629            if (stack != null) {
6630                ActivityRecord r =
6631                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6632                if (stopProfiling) {
6633                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6634                        try {
6635                            mProfileFd.close();
6636                        } catch (IOException e) {
6637                        }
6638                        clearProfilerLocked();
6639                    }
6640                }
6641            }
6642        }
6643        Binder.restoreCallingIdentity(origId);
6644    }
6645
6646    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6647        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6648                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6649    }
6650
6651    void enableScreenAfterBoot() {
6652        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6653                SystemClock.uptimeMillis());
6654        mWindowManager.enableScreenAfterBoot();
6655
6656        synchronized (this) {
6657            updateEventDispatchingLocked();
6658        }
6659    }
6660
6661    @Override
6662    public void showBootMessage(final CharSequence msg, final boolean always) {
6663        if (Binder.getCallingUid() != Process.myUid()) {
6664            // These days only the core system can call this, so apps can't get in
6665            // the way of what we show about running them.
6666        }
6667        mWindowManager.showBootMessage(msg, always);
6668    }
6669
6670    @Override
6671    public void keyguardWaitingForActivityDrawn() {
6672        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6673        final long token = Binder.clearCallingIdentity();
6674        try {
6675            synchronized (this) {
6676                if (DEBUG_LOCKSCREEN) logLockScreen("");
6677                mWindowManager.keyguardWaitingForActivityDrawn();
6678                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6679                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6680                    updateSleepIfNeededLocked();
6681                }
6682            }
6683        } finally {
6684            Binder.restoreCallingIdentity(token);
6685        }
6686    }
6687
6688    @Override
6689    public void keyguardGoingAway(int flags) {
6690        enforceNotIsolatedCaller("keyguardGoingAway");
6691        final long token = Binder.clearCallingIdentity();
6692        try {
6693            synchronized (this) {
6694                if (DEBUG_LOCKSCREEN) logLockScreen("");
6695                mWindowManager.keyguardGoingAway(flags);
6696                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6697                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6698                    updateSleepIfNeededLocked();
6699
6700                    // Some stack visibility might change (e.g. docked stack)
6701                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6702                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6703                }
6704            }
6705        } finally {
6706            Binder.restoreCallingIdentity(token);
6707        }
6708    }
6709
6710    final void finishBooting() {
6711        synchronized (this) {
6712            if (!mBootAnimationComplete) {
6713                mCallFinishBooting = true;
6714                return;
6715            }
6716            mCallFinishBooting = false;
6717        }
6718
6719        ArraySet<String> completedIsas = new ArraySet<String>();
6720        for (String abi : Build.SUPPORTED_ABIS) {
6721            Process.establishZygoteConnectionForAbi(abi);
6722            final String instructionSet = VMRuntime.getInstructionSet(abi);
6723            if (!completedIsas.contains(instructionSet)) {
6724                try {
6725                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6726                } catch (InstallerException e) {
6727                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6728                            e.getMessage() +")");
6729                }
6730                completedIsas.add(instructionSet);
6731            }
6732        }
6733
6734        IntentFilter pkgFilter = new IntentFilter();
6735        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6736        pkgFilter.addDataScheme("package");
6737        mContext.registerReceiver(new BroadcastReceiver() {
6738            @Override
6739            public void onReceive(Context context, Intent intent) {
6740                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6741                if (pkgs != null) {
6742                    for (String pkg : pkgs) {
6743                        synchronized (ActivityManagerService.this) {
6744                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6745                                    0, "query restart")) {
6746                                setResultCode(Activity.RESULT_OK);
6747                                return;
6748                            }
6749                        }
6750                    }
6751                }
6752            }
6753        }, pkgFilter);
6754
6755        IntentFilter dumpheapFilter = new IntentFilter();
6756        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6757        mContext.registerReceiver(new BroadcastReceiver() {
6758            @Override
6759            public void onReceive(Context context, Intent intent) {
6760                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6761                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6762                } else {
6763                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6764                }
6765            }
6766        }, dumpheapFilter);
6767
6768        // Let system services know.
6769        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6770
6771        synchronized (this) {
6772            // Ensure that any processes we had put on hold are now started
6773            // up.
6774            final int NP = mProcessesOnHold.size();
6775            if (NP > 0) {
6776                ArrayList<ProcessRecord> procs =
6777                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6778                for (int ip=0; ip<NP; ip++) {
6779                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6780                            + procs.get(ip));
6781                    startProcessLocked(procs.get(ip), "on-hold", null);
6782                }
6783            }
6784
6785            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6786                // Start looking for apps that are abusing wake locks.
6787                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6788                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6789                // Tell anyone interested that we are done booting!
6790                SystemProperties.set("sys.boot_completed", "1");
6791
6792                // And trigger dev.bootcomplete if we are not showing encryption progress
6793                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6794                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6795                    SystemProperties.set("dev.bootcomplete", "1");
6796                }
6797                mUserController.sendBootCompletedLocked(
6798                        new IIntentReceiver.Stub() {
6799                            @Override
6800                            public void performReceive(Intent intent, int resultCode,
6801                                    String data, Bundle extras, boolean ordered,
6802                                    boolean sticky, int sendingUser) {
6803                                synchronized (ActivityManagerService.this) {
6804                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6805                                            true, false);
6806                                }
6807                            }
6808                        });
6809                scheduleStartProfilesLocked();
6810            }
6811        }
6812    }
6813
6814    @Override
6815    public void bootAnimationComplete() {
6816        final boolean callFinishBooting;
6817        synchronized (this) {
6818            callFinishBooting = mCallFinishBooting;
6819            mBootAnimationComplete = true;
6820        }
6821        if (callFinishBooting) {
6822            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6823            finishBooting();
6824            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6825        }
6826    }
6827
6828    final void ensureBootCompleted() {
6829        boolean booting;
6830        boolean enableScreen;
6831        synchronized (this) {
6832            booting = mBooting;
6833            mBooting = false;
6834            enableScreen = !mBooted;
6835            mBooted = true;
6836        }
6837
6838        if (booting) {
6839            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6840            finishBooting();
6841            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6842        }
6843
6844        if (enableScreen) {
6845            enableScreenAfterBoot();
6846        }
6847    }
6848
6849    @Override
6850    public final void activityResumed(IBinder token) {
6851        final long origId = Binder.clearCallingIdentity();
6852        synchronized(this) {
6853            ActivityStack stack = ActivityRecord.getStackLocked(token);
6854            if (stack != null) {
6855                stack.activityResumedLocked(token);
6856            }
6857        }
6858        Binder.restoreCallingIdentity(origId);
6859    }
6860
6861    @Override
6862    public final void activityPaused(IBinder token) {
6863        final long origId = Binder.clearCallingIdentity();
6864        synchronized(this) {
6865            ActivityStack stack = ActivityRecord.getStackLocked(token);
6866            if (stack != null) {
6867                stack.activityPausedLocked(token, false);
6868            }
6869        }
6870        Binder.restoreCallingIdentity(origId);
6871    }
6872
6873    @Override
6874    public final void activityStopped(IBinder token, Bundle icicle,
6875            PersistableBundle persistentState, CharSequence description) {
6876        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6877
6878        // Refuse possible leaked file descriptors
6879        if (icicle != null && icicle.hasFileDescriptors()) {
6880            throw new IllegalArgumentException("File descriptors passed in Bundle");
6881        }
6882
6883        final long origId = Binder.clearCallingIdentity();
6884
6885        synchronized (this) {
6886            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6887            if (r != null) {
6888                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6889            }
6890        }
6891
6892        trimApplications();
6893
6894        Binder.restoreCallingIdentity(origId);
6895    }
6896
6897    @Override
6898    public final void activityDestroyed(IBinder token) {
6899        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6900        synchronized (this) {
6901            ActivityStack stack = ActivityRecord.getStackLocked(token);
6902            if (stack != null) {
6903                stack.activityDestroyedLocked(token, "activityDestroyed");
6904            }
6905        }
6906    }
6907
6908    @Override
6909    public final void activityRelaunched(IBinder token) {
6910        final long origId = Binder.clearCallingIdentity();
6911        synchronized (this) {
6912            mStackSupervisor.activityRelaunchedLocked(token);
6913        }
6914        Binder.restoreCallingIdentity(origId);
6915    }
6916
6917    @Override
6918    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6919            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6920        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6921                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6922        synchronized (this) {
6923            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6924            if (record == null) {
6925                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6926                        + "found for: " + token);
6927            }
6928            record.setSizeConfigurations(horizontalSizeConfiguration,
6929                    verticalSizeConfigurations, smallestSizeConfigurations);
6930        }
6931    }
6932
6933    @Override
6934    public final void backgroundResourcesReleased(IBinder token) {
6935        final long origId = Binder.clearCallingIdentity();
6936        try {
6937            synchronized (this) {
6938                ActivityStack stack = ActivityRecord.getStackLocked(token);
6939                if (stack != null) {
6940                    stack.backgroundResourcesReleased();
6941                }
6942            }
6943        } finally {
6944            Binder.restoreCallingIdentity(origId);
6945        }
6946    }
6947
6948    @Override
6949    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6950        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6951    }
6952
6953    @Override
6954    public final void notifyEnterAnimationComplete(IBinder token) {
6955        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6956    }
6957
6958    @Override
6959    public String getCallingPackage(IBinder token) {
6960        synchronized (this) {
6961            ActivityRecord r = getCallingRecordLocked(token);
6962            return r != null ? r.info.packageName : null;
6963        }
6964    }
6965
6966    @Override
6967    public ComponentName getCallingActivity(IBinder token) {
6968        synchronized (this) {
6969            ActivityRecord r = getCallingRecordLocked(token);
6970            return r != null ? r.intent.getComponent() : null;
6971        }
6972    }
6973
6974    private ActivityRecord getCallingRecordLocked(IBinder token) {
6975        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6976        if (r == null) {
6977            return null;
6978        }
6979        return r.resultTo;
6980    }
6981
6982    @Override
6983    public ComponentName getActivityClassForToken(IBinder token) {
6984        synchronized(this) {
6985            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6986            if (r == null) {
6987                return null;
6988            }
6989            return r.intent.getComponent();
6990        }
6991    }
6992
6993    @Override
6994    public String getPackageForToken(IBinder token) {
6995        synchronized(this) {
6996            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6997            if (r == null) {
6998                return null;
6999            }
7000            return r.packageName;
7001        }
7002    }
7003
7004    @Override
7005    public boolean isRootVoiceInteraction(IBinder token) {
7006        synchronized(this) {
7007            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7008            if (r == null) {
7009                return false;
7010            }
7011            return r.rootVoiceInteraction;
7012        }
7013    }
7014
7015    @Override
7016    public IIntentSender getIntentSender(int type,
7017            String packageName, IBinder token, String resultWho,
7018            int requestCode, Intent[] intents, String[] resolvedTypes,
7019            int flags, Bundle bOptions, int userId) {
7020        enforceNotIsolatedCaller("getIntentSender");
7021        // Refuse possible leaked file descriptors
7022        if (intents != null) {
7023            if (intents.length < 1) {
7024                throw new IllegalArgumentException("Intents array length must be >= 1");
7025            }
7026            for (int i=0; i<intents.length; i++) {
7027                Intent intent = intents[i];
7028                if (intent != null) {
7029                    if (intent.hasFileDescriptors()) {
7030                        throw new IllegalArgumentException("File descriptors passed in Intent");
7031                    }
7032                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7033                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7034                        throw new IllegalArgumentException(
7035                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7036                    }
7037                    intents[i] = new Intent(intent);
7038                }
7039            }
7040            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7041                throw new IllegalArgumentException(
7042                        "Intent array length does not match resolvedTypes length");
7043            }
7044        }
7045        if (bOptions != null) {
7046            if (bOptions.hasFileDescriptors()) {
7047                throw new IllegalArgumentException("File descriptors passed in options");
7048            }
7049        }
7050
7051        synchronized(this) {
7052            int callingUid = Binder.getCallingUid();
7053            int origUserId = userId;
7054            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7055                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7056                    ALLOW_NON_FULL, "getIntentSender", null);
7057            if (origUserId == UserHandle.USER_CURRENT) {
7058                // We don't want to evaluate this until the pending intent is
7059                // actually executed.  However, we do want to always do the
7060                // security checking for it above.
7061                userId = UserHandle.USER_CURRENT;
7062            }
7063            try {
7064                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7065                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7066                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7067                    if (!UserHandle.isSameApp(callingUid, uid)) {
7068                        String msg = "Permission Denial: getIntentSender() from pid="
7069                            + Binder.getCallingPid()
7070                            + ", uid=" + Binder.getCallingUid()
7071                            + ", (need uid=" + uid + ")"
7072                            + " is not allowed to send as package " + packageName;
7073                        Slog.w(TAG, msg);
7074                        throw new SecurityException(msg);
7075                    }
7076                }
7077
7078                return getIntentSenderLocked(type, packageName, callingUid, userId,
7079                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7080
7081            } catch (RemoteException e) {
7082                throw new SecurityException(e);
7083            }
7084        }
7085    }
7086
7087    IIntentSender getIntentSenderLocked(int type, String packageName,
7088            int callingUid, int userId, IBinder token, String resultWho,
7089            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7090            Bundle bOptions) {
7091        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7092        ActivityRecord activity = null;
7093        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7094            activity = ActivityRecord.isInStackLocked(token);
7095            if (activity == null) {
7096                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7097                return null;
7098            }
7099            if (activity.finishing) {
7100                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7101                return null;
7102            }
7103        }
7104
7105        // We're going to be splicing together extras before sending, so we're
7106        // okay poking into any contained extras.
7107        if (intents != null) {
7108            for (int i = 0; i < intents.length; i++) {
7109                intents[i].setDefusable(true);
7110            }
7111        }
7112        Bundle.setDefusable(bOptions, true);
7113
7114        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7115        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7116        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7117        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7118                |PendingIntent.FLAG_UPDATE_CURRENT);
7119
7120        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7121                type, packageName, activity, resultWho,
7122                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7123        WeakReference<PendingIntentRecord> ref;
7124        ref = mIntentSenderRecords.get(key);
7125        PendingIntentRecord rec = ref != null ? ref.get() : null;
7126        if (rec != null) {
7127            if (!cancelCurrent) {
7128                if (updateCurrent) {
7129                    if (rec.key.requestIntent != null) {
7130                        rec.key.requestIntent.replaceExtras(intents != null ?
7131                                intents[intents.length - 1] : null);
7132                    }
7133                    if (intents != null) {
7134                        intents[intents.length-1] = rec.key.requestIntent;
7135                        rec.key.allIntents = intents;
7136                        rec.key.allResolvedTypes = resolvedTypes;
7137                    } else {
7138                        rec.key.allIntents = null;
7139                        rec.key.allResolvedTypes = null;
7140                    }
7141                }
7142                return rec;
7143            }
7144            rec.canceled = true;
7145            mIntentSenderRecords.remove(key);
7146        }
7147        if (noCreate) {
7148            return rec;
7149        }
7150        rec = new PendingIntentRecord(this, key, callingUid);
7151        mIntentSenderRecords.put(key, rec.ref);
7152        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7153            if (activity.pendingResults == null) {
7154                activity.pendingResults
7155                        = new HashSet<WeakReference<PendingIntentRecord>>();
7156            }
7157            activity.pendingResults.add(rec.ref);
7158        }
7159        return rec;
7160    }
7161
7162    @Override
7163    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7164            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7165        if (target instanceof PendingIntentRecord) {
7166            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7167                    finishedReceiver, requiredPermission, options);
7168        } else {
7169            if (intent == null) {
7170                // Weird case: someone has given us their own custom IIntentSender, and now
7171                // they have someone else trying to send to it but of course this isn't
7172                // really a PendingIntent, so there is no base Intent, and the caller isn't
7173                // supplying an Intent... but we never want to dispatch a null Intent to
7174                // a receiver, so um...  let's make something up.
7175                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7176                intent = new Intent(Intent.ACTION_MAIN);
7177            }
7178            try {
7179                target.send(code, intent, resolvedType, null, requiredPermission, options);
7180            } catch (RemoteException e) {
7181            }
7182            // Platform code can rely on getting a result back when the send is done, but if
7183            // this intent sender is from outside of the system we can't rely on it doing that.
7184            // So instead we don't give it the result receiver, and instead just directly
7185            // report the finish immediately.
7186            if (finishedReceiver != null) {
7187                try {
7188                    finishedReceiver.performReceive(intent, 0,
7189                            null, null, false, false, UserHandle.getCallingUserId());
7190                } catch (RemoteException e) {
7191                }
7192            }
7193            return 0;
7194        }
7195    }
7196
7197    /**
7198     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7199     *
7200     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7201     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7202     */
7203    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7204        if (DEBUG_WHITELISTS) {
7205            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7206                    + targetUid + ", " + duration + ")");
7207        }
7208        synchronized (mPidsSelfLocked) {
7209            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7210            if (pr == null) {
7211                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7212                return;
7213            }
7214            if (!pr.whitelistManager) {
7215                if (DEBUG_WHITELISTS) {
7216                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7217                            + callerPid + " is not allowed");
7218                }
7219                return;
7220            }
7221        }
7222
7223        final long token = Binder.clearCallingIdentity();
7224        try {
7225            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7226                    true, "pe from uid:" + callerUid);
7227        } finally {
7228            Binder.restoreCallingIdentity(token);
7229        }
7230    }
7231
7232    @Override
7233    public void cancelIntentSender(IIntentSender sender) {
7234        if (!(sender instanceof PendingIntentRecord)) {
7235            return;
7236        }
7237        synchronized(this) {
7238            PendingIntentRecord rec = (PendingIntentRecord)sender;
7239            try {
7240                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7241                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7242                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7243                    String msg = "Permission Denial: cancelIntentSender() from pid="
7244                        + Binder.getCallingPid()
7245                        + ", uid=" + Binder.getCallingUid()
7246                        + " is not allowed to cancel packges "
7247                        + rec.key.packageName;
7248                    Slog.w(TAG, msg);
7249                    throw new SecurityException(msg);
7250                }
7251            } catch (RemoteException e) {
7252                throw new SecurityException(e);
7253            }
7254            cancelIntentSenderLocked(rec, true);
7255        }
7256    }
7257
7258    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7259        rec.canceled = true;
7260        mIntentSenderRecords.remove(rec.key);
7261        if (cleanActivity && rec.key.activity != null) {
7262            rec.key.activity.pendingResults.remove(rec.ref);
7263        }
7264    }
7265
7266    @Override
7267    public String getPackageForIntentSender(IIntentSender pendingResult) {
7268        if (!(pendingResult instanceof PendingIntentRecord)) {
7269            return null;
7270        }
7271        try {
7272            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7273            return res.key.packageName;
7274        } catch (ClassCastException e) {
7275        }
7276        return null;
7277    }
7278
7279    @Override
7280    public int getUidForIntentSender(IIntentSender sender) {
7281        if (sender instanceof PendingIntentRecord) {
7282            try {
7283                PendingIntentRecord res = (PendingIntentRecord)sender;
7284                return res.uid;
7285            } catch (ClassCastException e) {
7286            }
7287        }
7288        return -1;
7289    }
7290
7291    @Override
7292    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7293        if (!(pendingResult instanceof PendingIntentRecord)) {
7294            return false;
7295        }
7296        try {
7297            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7298            if (res.key.allIntents == null) {
7299                return false;
7300            }
7301            for (int i=0; i<res.key.allIntents.length; i++) {
7302                Intent intent = res.key.allIntents[i];
7303                if (intent.getPackage() != null && intent.getComponent() != null) {
7304                    return false;
7305                }
7306            }
7307            return true;
7308        } catch (ClassCastException e) {
7309        }
7310        return false;
7311    }
7312
7313    @Override
7314    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7315        if (!(pendingResult instanceof PendingIntentRecord)) {
7316            return false;
7317        }
7318        try {
7319            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7320            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7321                return true;
7322            }
7323            return false;
7324        } catch (ClassCastException e) {
7325        }
7326        return false;
7327    }
7328
7329    @Override
7330    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7331        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7332                "getIntentForIntentSender()");
7333        if (!(pendingResult instanceof PendingIntentRecord)) {
7334            return null;
7335        }
7336        try {
7337            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7338            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7339        } catch (ClassCastException e) {
7340        }
7341        return null;
7342    }
7343
7344    @Override
7345    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7346        if (!(pendingResult instanceof PendingIntentRecord)) {
7347            return null;
7348        }
7349        try {
7350            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7351            synchronized (this) {
7352                return getTagForIntentSenderLocked(res, prefix);
7353            }
7354        } catch (ClassCastException e) {
7355        }
7356        return null;
7357    }
7358
7359    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7360        final Intent intent = res.key.requestIntent;
7361        if (intent != null) {
7362            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7363                    || res.lastTagPrefix.equals(prefix))) {
7364                return res.lastTag;
7365            }
7366            res.lastTagPrefix = prefix;
7367            final StringBuilder sb = new StringBuilder(128);
7368            if (prefix != null) {
7369                sb.append(prefix);
7370            }
7371            if (intent.getAction() != null) {
7372                sb.append(intent.getAction());
7373            } else if (intent.getComponent() != null) {
7374                intent.getComponent().appendShortString(sb);
7375            } else {
7376                sb.append("?");
7377            }
7378            return res.lastTag = sb.toString();
7379        }
7380        return null;
7381    }
7382
7383    @Override
7384    public void setProcessLimit(int max) {
7385        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7386                "setProcessLimit()");
7387        synchronized (this) {
7388            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7389            mProcessLimitOverride = max;
7390        }
7391        trimApplications();
7392    }
7393
7394    @Override
7395    public int getProcessLimit() {
7396        synchronized (this) {
7397            return mProcessLimitOverride;
7398        }
7399    }
7400
7401    void foregroundTokenDied(ForegroundToken token) {
7402        synchronized (ActivityManagerService.this) {
7403            synchronized (mPidsSelfLocked) {
7404                ForegroundToken cur
7405                    = mForegroundProcesses.get(token.pid);
7406                if (cur != token) {
7407                    return;
7408                }
7409                mForegroundProcesses.remove(token.pid);
7410                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7411                if (pr == null) {
7412                    return;
7413                }
7414                pr.forcingToForeground = null;
7415                updateProcessForegroundLocked(pr, false, false);
7416            }
7417            updateOomAdjLocked();
7418        }
7419    }
7420
7421    @Override
7422    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7423        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7424                "setProcessForeground()");
7425        synchronized(this) {
7426            boolean changed = false;
7427
7428            synchronized (mPidsSelfLocked) {
7429                ProcessRecord pr = mPidsSelfLocked.get(pid);
7430                if (pr == null && isForeground) {
7431                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7432                    return;
7433                }
7434                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7435                if (oldToken != null) {
7436                    oldToken.token.unlinkToDeath(oldToken, 0);
7437                    mForegroundProcesses.remove(pid);
7438                    if (pr != null) {
7439                        pr.forcingToForeground = null;
7440                    }
7441                    changed = true;
7442                }
7443                if (isForeground && token != null) {
7444                    ForegroundToken newToken = new ForegroundToken() {
7445                        @Override
7446                        public void binderDied() {
7447                            foregroundTokenDied(this);
7448                        }
7449                    };
7450                    newToken.pid = pid;
7451                    newToken.token = token;
7452                    try {
7453                        token.linkToDeath(newToken, 0);
7454                        mForegroundProcesses.put(pid, newToken);
7455                        pr.forcingToForeground = token;
7456                        changed = true;
7457                    } catch (RemoteException e) {
7458                        // If the process died while doing this, we will later
7459                        // do the cleanup with the process death link.
7460                    }
7461                }
7462            }
7463
7464            if (changed) {
7465                updateOomAdjLocked();
7466            }
7467        }
7468    }
7469
7470    @Override
7471    public boolean isAppForeground(int uid) throws RemoteException {
7472        synchronized (this) {
7473            UidRecord uidRec = mActiveUids.get(uid);
7474            if (uidRec == null || uidRec.idle) {
7475                return false;
7476            }
7477            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7478        }
7479    }
7480
7481    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7482    // be guarded by permission checking.
7483    int getUidState(int uid) {
7484        synchronized (this) {
7485            UidRecord uidRec = mActiveUids.get(uid);
7486            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7487        }
7488    }
7489
7490    @Override
7491    public boolean isInMultiWindowMode(IBinder token) {
7492        final long origId = Binder.clearCallingIdentity();
7493        try {
7494            synchronized(this) {
7495                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7496                if (r == null) {
7497                    return false;
7498                }
7499                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7500                return !r.task.mFullscreen;
7501            }
7502        } finally {
7503            Binder.restoreCallingIdentity(origId);
7504        }
7505    }
7506
7507    @Override
7508    public boolean isInPictureInPictureMode(IBinder token) {
7509        final long origId = Binder.clearCallingIdentity();
7510        try {
7511            synchronized(this) {
7512                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7513                if (stack == null) {
7514                    return false;
7515                }
7516                return stack.mStackId == PINNED_STACK_ID;
7517            }
7518        } finally {
7519            Binder.restoreCallingIdentity(origId);
7520        }
7521    }
7522
7523    @Override
7524    public void enterPictureInPictureMode(IBinder token) {
7525        final long origId = Binder.clearCallingIdentity();
7526        try {
7527            synchronized(this) {
7528                if (!mSupportsPictureInPicture) {
7529                    throw new IllegalStateException("enterPictureInPictureMode: "
7530                            + "Device doesn't support picture-in-picture mode.");
7531                }
7532
7533                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7534
7535                if (r == null) {
7536                    throw new IllegalStateException("enterPictureInPictureMode: "
7537                            + "Can't find activity for token=" + token);
7538                }
7539
7540                if (!r.supportsPictureInPicture()) {
7541                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7542                            + "Picture-In-Picture not supported for r=" + r);
7543                }
7544
7545                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7546                // current bounds.
7547                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7548                final Rect bounds = (pinnedStack != null)
7549                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7550
7551                mStackSupervisor.moveActivityToPinnedStackLocked(
7552                        r, "enterPictureInPictureMode", bounds);
7553            }
7554        } finally {
7555            Binder.restoreCallingIdentity(origId);
7556        }
7557    }
7558
7559    // =========================================================
7560    // PROCESS INFO
7561    // =========================================================
7562
7563    static class ProcessInfoService extends IProcessInfoService.Stub {
7564        final ActivityManagerService mActivityManagerService;
7565        ProcessInfoService(ActivityManagerService activityManagerService) {
7566            mActivityManagerService = activityManagerService;
7567        }
7568
7569        @Override
7570        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7571            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7572                    /*in*/ pids, /*out*/ states, null);
7573        }
7574
7575        @Override
7576        public void getProcessStatesAndOomScoresFromPids(
7577                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7578            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7579                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7580        }
7581    }
7582
7583    /**
7584     * For each PID in the given input array, write the current process state
7585     * for that process into the states array, or -1 to indicate that no
7586     * process with the given PID exists. If scores array is provided, write
7587     * the oom score for the process into the scores array, with INVALID_ADJ
7588     * indicating the PID doesn't exist.
7589     */
7590    public void getProcessStatesAndOomScoresForPIDs(
7591            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7592        if (scores != null) {
7593            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7594                    "getProcessStatesAndOomScoresForPIDs()");
7595        }
7596
7597        if (pids == null) {
7598            throw new NullPointerException("pids");
7599        } else if (states == null) {
7600            throw new NullPointerException("states");
7601        } else if (pids.length != states.length) {
7602            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7603        } else if (scores != null && pids.length != scores.length) {
7604            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7605        }
7606
7607        synchronized (mPidsSelfLocked) {
7608            for (int i = 0; i < pids.length; i++) {
7609                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7610                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7611                        pr.curProcState;
7612                if (scores != null) {
7613                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7614                }
7615            }
7616        }
7617    }
7618
7619    // =========================================================
7620    // PERMISSIONS
7621    // =========================================================
7622
7623    static class PermissionController extends IPermissionController.Stub {
7624        ActivityManagerService mActivityManagerService;
7625        PermissionController(ActivityManagerService activityManagerService) {
7626            mActivityManagerService = activityManagerService;
7627        }
7628
7629        @Override
7630        public boolean checkPermission(String permission, int pid, int uid) {
7631            return mActivityManagerService.checkPermission(permission, pid,
7632                    uid) == PackageManager.PERMISSION_GRANTED;
7633        }
7634
7635        @Override
7636        public String[] getPackagesForUid(int uid) {
7637            return mActivityManagerService.mContext.getPackageManager()
7638                    .getPackagesForUid(uid);
7639        }
7640
7641        @Override
7642        public boolean isRuntimePermission(String permission) {
7643            try {
7644                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7645                        .getPermissionInfo(permission, 0);
7646                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7647            } catch (NameNotFoundException nnfe) {
7648                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7649            }
7650            return false;
7651        }
7652    }
7653
7654    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7655        @Override
7656        public int checkComponentPermission(String permission, int pid, int uid,
7657                int owningUid, boolean exported) {
7658            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7659                    owningUid, exported);
7660        }
7661
7662        @Override
7663        public Object getAMSLock() {
7664            return ActivityManagerService.this;
7665        }
7666    }
7667
7668    /**
7669     * This can be called with or without the global lock held.
7670     */
7671    int checkComponentPermission(String permission, int pid, int uid,
7672            int owningUid, boolean exported) {
7673        if (pid == MY_PID) {
7674            return PackageManager.PERMISSION_GRANTED;
7675        }
7676        return ActivityManager.checkComponentPermission(permission, uid,
7677                owningUid, exported);
7678    }
7679
7680    /**
7681     * As the only public entry point for permissions checking, this method
7682     * can enforce the semantic that requesting a check on a null global
7683     * permission is automatically denied.  (Internally a null permission
7684     * string is used when calling {@link #checkComponentPermission} in cases
7685     * when only uid-based security is needed.)
7686     *
7687     * This can be called with or without the global lock held.
7688     */
7689    @Override
7690    public int checkPermission(String permission, int pid, int uid) {
7691        if (permission == null) {
7692            return PackageManager.PERMISSION_DENIED;
7693        }
7694        return checkComponentPermission(permission, pid, uid, -1, true);
7695    }
7696
7697    @Override
7698    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7699        if (permission == null) {
7700            return PackageManager.PERMISSION_DENIED;
7701        }
7702
7703        // We might be performing an operation on behalf of an indirect binder
7704        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7705        // client identity accordingly before proceeding.
7706        Identity tlsIdentity = sCallerIdentity.get();
7707        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7708            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7709                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7710            uid = tlsIdentity.uid;
7711            pid = tlsIdentity.pid;
7712        }
7713
7714        return checkComponentPermission(permission, pid, uid, -1, true);
7715    }
7716
7717    /**
7718     * Binder IPC calls go through the public entry point.
7719     * This can be called with or without the global lock held.
7720     */
7721    int checkCallingPermission(String permission) {
7722        return checkPermission(permission,
7723                Binder.getCallingPid(),
7724                UserHandle.getAppId(Binder.getCallingUid()));
7725    }
7726
7727    /**
7728     * This can be called with or without the global lock held.
7729     */
7730    void enforceCallingPermission(String permission, String func) {
7731        if (checkCallingPermission(permission)
7732                == PackageManager.PERMISSION_GRANTED) {
7733            return;
7734        }
7735
7736        String msg = "Permission Denial: " + func + " from pid="
7737                + Binder.getCallingPid()
7738                + ", uid=" + Binder.getCallingUid()
7739                + " requires " + permission;
7740        Slog.w(TAG, msg);
7741        throw new SecurityException(msg);
7742    }
7743
7744    /**
7745     * Determine if UID is holding permissions required to access {@link Uri} in
7746     * the given {@link ProviderInfo}. Final permission checking is always done
7747     * in {@link ContentProvider}.
7748     */
7749    private final boolean checkHoldingPermissionsLocked(
7750            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7751        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7752                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7753        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7754            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7755                    != PERMISSION_GRANTED) {
7756                return false;
7757            }
7758        }
7759        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7760    }
7761
7762    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7763            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7764        if (pi.applicationInfo.uid == uid) {
7765            return true;
7766        } else if (!pi.exported) {
7767            return false;
7768        }
7769
7770        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7771        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7772        try {
7773            // check if target holds top-level <provider> permissions
7774            if (!readMet && pi.readPermission != null && considerUidPermissions
7775                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7776                readMet = true;
7777            }
7778            if (!writeMet && pi.writePermission != null && considerUidPermissions
7779                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7780                writeMet = true;
7781            }
7782
7783            // track if unprotected read/write is allowed; any denied
7784            // <path-permission> below removes this ability
7785            boolean allowDefaultRead = pi.readPermission == null;
7786            boolean allowDefaultWrite = pi.writePermission == null;
7787
7788            // check if target holds any <path-permission> that match uri
7789            final PathPermission[] pps = pi.pathPermissions;
7790            if (pps != null) {
7791                final String path = grantUri.uri.getPath();
7792                int i = pps.length;
7793                while (i > 0 && (!readMet || !writeMet)) {
7794                    i--;
7795                    PathPermission pp = pps[i];
7796                    if (pp.match(path)) {
7797                        if (!readMet) {
7798                            final String pprperm = pp.getReadPermission();
7799                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7800                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7801                                    + ": match=" + pp.match(path)
7802                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7803                            if (pprperm != null) {
7804                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7805                                        == PERMISSION_GRANTED) {
7806                                    readMet = true;
7807                                } else {
7808                                    allowDefaultRead = false;
7809                                }
7810                            }
7811                        }
7812                        if (!writeMet) {
7813                            final String ppwperm = pp.getWritePermission();
7814                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7815                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7816                                    + ": match=" + pp.match(path)
7817                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7818                            if (ppwperm != null) {
7819                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7820                                        == PERMISSION_GRANTED) {
7821                                    writeMet = true;
7822                                } else {
7823                                    allowDefaultWrite = false;
7824                                }
7825                            }
7826                        }
7827                    }
7828                }
7829            }
7830
7831            // grant unprotected <provider> read/write, if not blocked by
7832            // <path-permission> above
7833            if (allowDefaultRead) readMet = true;
7834            if (allowDefaultWrite) writeMet = true;
7835
7836        } catch (RemoteException e) {
7837            return false;
7838        }
7839
7840        return readMet && writeMet;
7841    }
7842
7843    public int getAppStartMode(int uid, String packageName) {
7844        synchronized (this) {
7845            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7846        }
7847    }
7848
7849    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7850            boolean allowWhenForeground) {
7851        UidRecord uidRec = mActiveUids.get(uid);
7852        if (!mLenientBackgroundCheck) {
7853            if (!allowWhenForeground || uidRec == null
7854                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7855                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7856                        packageName) != AppOpsManager.MODE_ALLOWED) {
7857                    return ActivityManager.APP_START_MODE_DELAYED;
7858                }
7859            }
7860
7861        } else if (uidRec == null || uidRec.idle) {
7862            if (callingPid >= 0) {
7863                ProcessRecord proc;
7864                synchronized (mPidsSelfLocked) {
7865                    proc = mPidsSelfLocked.get(callingPid);
7866                }
7867                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7868                    // Whoever is instigating this is in the foreground, so we will allow it
7869                    // to go through.
7870                    return ActivityManager.APP_START_MODE_NORMAL;
7871                }
7872            }
7873            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7874                    != AppOpsManager.MODE_ALLOWED) {
7875                return ActivityManager.APP_START_MODE_DELAYED;
7876            }
7877        }
7878        return ActivityManager.APP_START_MODE_NORMAL;
7879    }
7880
7881    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7882        ProviderInfo pi = null;
7883        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7884        if (cpr != null) {
7885            pi = cpr.info;
7886        } else {
7887            try {
7888                pi = AppGlobals.getPackageManager().resolveContentProvider(
7889                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7890                        userHandle);
7891            } catch (RemoteException ex) {
7892            }
7893        }
7894        return pi;
7895    }
7896
7897    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7898        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7899        if (targetUris != null) {
7900            return targetUris.get(grantUri);
7901        }
7902        return null;
7903    }
7904
7905    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7906            String targetPkg, int targetUid, GrantUri grantUri) {
7907        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7908        if (targetUris == null) {
7909            targetUris = Maps.newArrayMap();
7910            mGrantedUriPermissions.put(targetUid, targetUris);
7911        }
7912
7913        UriPermission perm = targetUris.get(grantUri);
7914        if (perm == null) {
7915            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7916            targetUris.put(grantUri, perm);
7917        }
7918
7919        return perm;
7920    }
7921
7922    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7923            final int modeFlags) {
7924        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7925        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7926                : UriPermission.STRENGTH_OWNED;
7927
7928        // Root gets to do everything.
7929        if (uid == 0) {
7930            return true;
7931        }
7932
7933        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7934        if (perms == null) return false;
7935
7936        // First look for exact match
7937        final UriPermission exactPerm = perms.get(grantUri);
7938        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7939            return true;
7940        }
7941
7942        // No exact match, look for prefixes
7943        final int N = perms.size();
7944        for (int i = 0; i < N; i++) {
7945            final UriPermission perm = perms.valueAt(i);
7946            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7947                    && perm.getStrength(modeFlags) >= minStrength) {
7948                return true;
7949            }
7950        }
7951
7952        return false;
7953    }
7954
7955    /**
7956     * @param uri This uri must NOT contain an embedded userId.
7957     * @param userId The userId in which the uri is to be resolved.
7958     */
7959    @Override
7960    public int checkUriPermission(Uri uri, int pid, int uid,
7961            final int modeFlags, int userId, IBinder callerToken) {
7962        enforceNotIsolatedCaller("checkUriPermission");
7963
7964        // Another redirected-binder-call permissions check as in
7965        // {@link checkPermissionWithToken}.
7966        Identity tlsIdentity = sCallerIdentity.get();
7967        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7968            uid = tlsIdentity.uid;
7969            pid = tlsIdentity.pid;
7970        }
7971
7972        // Our own process gets to do everything.
7973        if (pid == MY_PID) {
7974            return PackageManager.PERMISSION_GRANTED;
7975        }
7976        synchronized (this) {
7977            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7978                    ? PackageManager.PERMISSION_GRANTED
7979                    : PackageManager.PERMISSION_DENIED;
7980        }
7981    }
7982
7983    /**
7984     * Check if the targetPkg can be granted permission to access uri by
7985     * the callingUid using the given modeFlags.  Throws a security exception
7986     * if callingUid is not allowed to do this.  Returns the uid of the target
7987     * if the URI permission grant should be performed; returns -1 if it is not
7988     * needed (for example targetPkg already has permission to access the URI).
7989     * If you already know the uid of the target, you can supply it in
7990     * lastTargetUid else set that to -1.
7991     */
7992    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7993            final int modeFlags, int lastTargetUid) {
7994        if (!Intent.isAccessUriMode(modeFlags)) {
7995            return -1;
7996        }
7997
7998        if (targetPkg != null) {
7999            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8000                    "Checking grant " + targetPkg + " permission to " + grantUri);
8001        }
8002
8003        final IPackageManager pm = AppGlobals.getPackageManager();
8004
8005        // If this is not a content: uri, we can't do anything with it.
8006        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8007            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8008                    "Can't grant URI permission for non-content URI: " + grantUri);
8009            return -1;
8010        }
8011
8012        final String authority = grantUri.uri.getAuthority();
8013        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8014                MATCH_DEBUG_TRIAGED_MISSING);
8015        if (pi == null) {
8016            Slog.w(TAG, "No content provider found for permission check: " +
8017                    grantUri.uri.toSafeString());
8018            return -1;
8019        }
8020
8021        int targetUid = lastTargetUid;
8022        if (targetUid < 0 && targetPkg != null) {
8023            try {
8024                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8025                        UserHandle.getUserId(callingUid));
8026                if (targetUid < 0) {
8027                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8028                            "Can't grant URI permission no uid for: " + targetPkg);
8029                    return -1;
8030                }
8031            } catch (RemoteException ex) {
8032                return -1;
8033            }
8034        }
8035
8036        if (targetUid >= 0) {
8037            // First...  does the target actually need this permission?
8038            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8039                // No need to grant the target this permission.
8040                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8041                        "Target " + targetPkg + " already has full permission to " + grantUri);
8042                return -1;
8043            }
8044        } else {
8045            // First...  there is no target package, so can anyone access it?
8046            boolean allowed = pi.exported;
8047            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8048                if (pi.readPermission != null) {
8049                    allowed = false;
8050                }
8051            }
8052            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8053                if (pi.writePermission != null) {
8054                    allowed = false;
8055                }
8056            }
8057            if (allowed) {
8058                return -1;
8059            }
8060        }
8061
8062        /* There is a special cross user grant if:
8063         * - The target is on another user.
8064         * - Apps on the current user can access the uri without any uid permissions.
8065         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8066         * grant uri permissions.
8067         */
8068        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8069                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8070                modeFlags, false /*without considering the uid permissions*/);
8071
8072        // Second...  is the provider allowing granting of URI permissions?
8073        if (!specialCrossUserGrant) {
8074            if (!pi.grantUriPermissions) {
8075                throw new SecurityException("Provider " + pi.packageName
8076                        + "/" + pi.name
8077                        + " does not allow granting of Uri permissions (uri "
8078                        + grantUri + ")");
8079            }
8080            if (pi.uriPermissionPatterns != null) {
8081                final int N = pi.uriPermissionPatterns.length;
8082                boolean allowed = false;
8083                for (int i=0; i<N; i++) {
8084                    if (pi.uriPermissionPatterns[i] != null
8085                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8086                        allowed = true;
8087                        break;
8088                    }
8089                }
8090                if (!allowed) {
8091                    throw new SecurityException("Provider " + pi.packageName
8092                            + "/" + pi.name
8093                            + " does not allow granting of permission to path of Uri "
8094                            + grantUri);
8095                }
8096            }
8097        }
8098
8099        // Third...  does the caller itself have permission to access
8100        // this uri?
8101        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8102            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8103                // Require they hold a strong enough Uri permission
8104                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8105                    throw new SecurityException("Uid " + callingUid
8106                            + " does not have permission to uri " + grantUri);
8107                }
8108            }
8109        }
8110        return targetUid;
8111    }
8112
8113    /**
8114     * @param uri This uri must NOT contain an embedded userId.
8115     * @param userId The userId in which the uri is to be resolved.
8116     */
8117    @Override
8118    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8119            final int modeFlags, int userId) {
8120        enforceNotIsolatedCaller("checkGrantUriPermission");
8121        synchronized(this) {
8122            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8123                    new GrantUri(userId, uri, false), modeFlags, -1);
8124        }
8125    }
8126
8127    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8128            final int modeFlags, UriPermissionOwner owner) {
8129        if (!Intent.isAccessUriMode(modeFlags)) {
8130            return;
8131        }
8132
8133        // So here we are: the caller has the assumed permission
8134        // to the uri, and the target doesn't.  Let's now give this to
8135        // the target.
8136
8137        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8138                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8139
8140        final String authority = grantUri.uri.getAuthority();
8141        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8142                MATCH_DEBUG_TRIAGED_MISSING);
8143        if (pi == null) {
8144            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8145            return;
8146        }
8147
8148        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8149            grantUri.prefix = true;
8150        }
8151        final UriPermission perm = findOrCreateUriPermissionLocked(
8152                pi.packageName, targetPkg, targetUid, grantUri);
8153        perm.grantModes(modeFlags, owner);
8154    }
8155
8156    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8157            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8158        if (targetPkg == null) {
8159            throw new NullPointerException("targetPkg");
8160        }
8161        int targetUid;
8162        final IPackageManager pm = AppGlobals.getPackageManager();
8163        try {
8164            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8165        } catch (RemoteException ex) {
8166            return;
8167        }
8168
8169        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8170                targetUid);
8171        if (targetUid < 0) {
8172            return;
8173        }
8174
8175        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8176                owner);
8177    }
8178
8179    static class NeededUriGrants extends ArrayList<GrantUri> {
8180        final String targetPkg;
8181        final int targetUid;
8182        final int flags;
8183
8184        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8185            this.targetPkg = targetPkg;
8186            this.targetUid = targetUid;
8187            this.flags = flags;
8188        }
8189    }
8190
8191    /**
8192     * Like checkGrantUriPermissionLocked, but takes an Intent.
8193     */
8194    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8195            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8196        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8197                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8198                + " clip=" + (intent != null ? intent.getClipData() : null)
8199                + " from " + intent + "; flags=0x"
8200                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8201
8202        if (targetPkg == null) {
8203            throw new NullPointerException("targetPkg");
8204        }
8205
8206        if (intent == null) {
8207            return null;
8208        }
8209        Uri data = intent.getData();
8210        ClipData clip = intent.getClipData();
8211        if (data == null && clip == null) {
8212            return null;
8213        }
8214        // Default userId for uris in the intent (if they don't specify it themselves)
8215        int contentUserHint = intent.getContentUserHint();
8216        if (contentUserHint == UserHandle.USER_CURRENT) {
8217            contentUserHint = UserHandle.getUserId(callingUid);
8218        }
8219        final IPackageManager pm = AppGlobals.getPackageManager();
8220        int targetUid;
8221        if (needed != null) {
8222            targetUid = needed.targetUid;
8223        } else {
8224            try {
8225                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8226                        targetUserId);
8227            } catch (RemoteException ex) {
8228                return null;
8229            }
8230            if (targetUid < 0) {
8231                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8232                        "Can't grant URI permission no uid for: " + targetPkg
8233                        + " on user " + targetUserId);
8234                return null;
8235            }
8236        }
8237        if (data != null) {
8238            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8239            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8240                    targetUid);
8241            if (targetUid > 0) {
8242                if (needed == null) {
8243                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8244                }
8245                needed.add(grantUri);
8246            }
8247        }
8248        if (clip != null) {
8249            for (int i=0; i<clip.getItemCount(); i++) {
8250                Uri uri = clip.getItemAt(i).getUri();
8251                if (uri != null) {
8252                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8253                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8254                            targetUid);
8255                    if (targetUid > 0) {
8256                        if (needed == null) {
8257                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8258                        }
8259                        needed.add(grantUri);
8260                    }
8261                } else {
8262                    Intent clipIntent = clip.getItemAt(i).getIntent();
8263                    if (clipIntent != null) {
8264                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8265                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8266                        if (newNeeded != null) {
8267                            needed = newNeeded;
8268                        }
8269                    }
8270                }
8271            }
8272        }
8273
8274        return needed;
8275    }
8276
8277    /**
8278     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8279     */
8280    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8281            UriPermissionOwner owner) {
8282        if (needed != null) {
8283            for (int i=0; i<needed.size(); i++) {
8284                GrantUri grantUri = needed.get(i);
8285                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8286                        grantUri, needed.flags, owner);
8287            }
8288        }
8289    }
8290
8291    void grantUriPermissionFromIntentLocked(int callingUid,
8292            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8293        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8294                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8295        if (needed == null) {
8296            return;
8297        }
8298
8299        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8300    }
8301
8302    /**
8303     * @param uri This uri must NOT contain an embedded userId.
8304     * @param userId The userId in which the uri is to be resolved.
8305     */
8306    @Override
8307    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8308            final int modeFlags, int userId) {
8309        enforceNotIsolatedCaller("grantUriPermission");
8310        GrantUri grantUri = new GrantUri(userId, uri, false);
8311        synchronized(this) {
8312            final ProcessRecord r = getRecordForAppLocked(caller);
8313            if (r == null) {
8314                throw new SecurityException("Unable to find app for caller "
8315                        + caller
8316                        + " when granting permission to uri " + grantUri);
8317            }
8318            if (targetPkg == null) {
8319                throw new IllegalArgumentException("null target");
8320            }
8321            if (grantUri == null) {
8322                throw new IllegalArgumentException("null uri");
8323            }
8324
8325            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8326                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8327                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8328                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8329
8330            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8331                    UserHandle.getUserId(r.uid));
8332        }
8333    }
8334
8335    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8336        if (perm.modeFlags == 0) {
8337            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8338                    perm.targetUid);
8339            if (perms != null) {
8340                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8341                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8342
8343                perms.remove(perm.uri);
8344                if (perms.isEmpty()) {
8345                    mGrantedUriPermissions.remove(perm.targetUid);
8346                }
8347            }
8348        }
8349    }
8350
8351    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8352        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8353                "Revoking all granted permissions to " + grantUri);
8354
8355        final IPackageManager pm = AppGlobals.getPackageManager();
8356        final String authority = grantUri.uri.getAuthority();
8357        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8358                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8359        if (pi == null) {
8360            Slog.w(TAG, "No content provider found for permission revoke: "
8361                    + grantUri.toSafeString());
8362            return;
8363        }
8364
8365        // Does the caller have this permission on the URI?
8366        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8367            // If they don't have direct access to the URI, then revoke any
8368            // ownerless URI permissions that have been granted to them.
8369            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8370            if (perms != null) {
8371                boolean persistChanged = false;
8372                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8373                    final UriPermission perm = it.next();
8374                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8375                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8376                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8377                                "Revoking non-owned " + perm.targetUid
8378                                + " permission to " + perm.uri);
8379                        persistChanged |= perm.revokeModes(
8380                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8381                        if (perm.modeFlags == 0) {
8382                            it.remove();
8383                        }
8384                    }
8385                }
8386                if (perms.isEmpty()) {
8387                    mGrantedUriPermissions.remove(callingUid);
8388                }
8389                if (persistChanged) {
8390                    schedulePersistUriGrants();
8391                }
8392            }
8393            return;
8394        }
8395
8396        boolean persistChanged = false;
8397
8398        // Go through all of the permissions and remove any that match.
8399        int N = mGrantedUriPermissions.size();
8400        for (int i = 0; i < N; i++) {
8401            final int targetUid = mGrantedUriPermissions.keyAt(i);
8402            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8403
8404            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8405                final UriPermission perm = it.next();
8406                if (perm.uri.sourceUserId == grantUri.sourceUserId
8407                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8408                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8409                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8410                    persistChanged |= perm.revokeModes(
8411                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8412                    if (perm.modeFlags == 0) {
8413                        it.remove();
8414                    }
8415                }
8416            }
8417
8418            if (perms.isEmpty()) {
8419                mGrantedUriPermissions.remove(targetUid);
8420                N--;
8421                i--;
8422            }
8423        }
8424
8425        if (persistChanged) {
8426            schedulePersistUriGrants();
8427        }
8428    }
8429
8430    /**
8431     * @param uri This uri must NOT contain an embedded userId.
8432     * @param userId The userId in which the uri is to be resolved.
8433     */
8434    @Override
8435    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8436            int userId) {
8437        enforceNotIsolatedCaller("revokeUriPermission");
8438        synchronized(this) {
8439            final ProcessRecord r = getRecordForAppLocked(caller);
8440            if (r == null) {
8441                throw new SecurityException("Unable to find app for caller "
8442                        + caller
8443                        + " when revoking permission to uri " + uri);
8444            }
8445            if (uri == null) {
8446                Slog.w(TAG, "revokeUriPermission: null uri");
8447                return;
8448            }
8449
8450            if (!Intent.isAccessUriMode(modeFlags)) {
8451                return;
8452            }
8453
8454            final String authority = uri.getAuthority();
8455            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8456                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8457            if (pi == null) {
8458                Slog.w(TAG, "No content provider found for permission revoke: "
8459                        + uri.toSafeString());
8460                return;
8461            }
8462
8463            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8464        }
8465    }
8466
8467    /**
8468     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8469     * given package.
8470     *
8471     * @param packageName Package name to match, or {@code null} to apply to all
8472     *            packages.
8473     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8474     *            to all users.
8475     * @param persistable If persistable grants should be removed.
8476     */
8477    private void removeUriPermissionsForPackageLocked(
8478            String packageName, int userHandle, boolean persistable) {
8479        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8480            throw new IllegalArgumentException("Must narrow by either package or user");
8481        }
8482
8483        boolean persistChanged = false;
8484
8485        int N = mGrantedUriPermissions.size();
8486        for (int i = 0; i < N; i++) {
8487            final int targetUid = mGrantedUriPermissions.keyAt(i);
8488            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8489
8490            // Only inspect grants matching user
8491            if (userHandle == UserHandle.USER_ALL
8492                    || userHandle == UserHandle.getUserId(targetUid)) {
8493                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8494                    final UriPermission perm = it.next();
8495
8496                    // Only inspect grants matching package
8497                    if (packageName == null || perm.sourcePkg.equals(packageName)
8498                            || perm.targetPkg.equals(packageName)) {
8499                        persistChanged |= perm.revokeModes(persistable
8500                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8501
8502                        // Only remove when no modes remain; any persisted grants
8503                        // will keep this alive.
8504                        if (perm.modeFlags == 0) {
8505                            it.remove();
8506                        }
8507                    }
8508                }
8509
8510                if (perms.isEmpty()) {
8511                    mGrantedUriPermissions.remove(targetUid);
8512                    N--;
8513                    i--;
8514                }
8515            }
8516        }
8517
8518        if (persistChanged) {
8519            schedulePersistUriGrants();
8520        }
8521    }
8522
8523    @Override
8524    public IBinder newUriPermissionOwner(String name) {
8525        enforceNotIsolatedCaller("newUriPermissionOwner");
8526        synchronized(this) {
8527            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8528            return owner.getExternalTokenLocked();
8529        }
8530    }
8531
8532    @Override
8533    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8534        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8535        synchronized(this) {
8536            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8537            if (r == null) {
8538                throw new IllegalArgumentException("Activity does not exist; token="
8539                        + activityToken);
8540            }
8541            return r.getUriPermissionsLocked().getExternalTokenLocked();
8542        }
8543    }
8544    /**
8545     * @param uri This uri must NOT contain an embedded userId.
8546     * @param sourceUserId The userId in which the uri is to be resolved.
8547     * @param targetUserId The userId of the app that receives the grant.
8548     */
8549    @Override
8550    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8551            final int modeFlags, int sourceUserId, int targetUserId) {
8552        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8553                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8554                "grantUriPermissionFromOwner", null);
8555        synchronized(this) {
8556            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8557            if (owner == null) {
8558                throw new IllegalArgumentException("Unknown owner: " + token);
8559            }
8560            if (fromUid != Binder.getCallingUid()) {
8561                if (Binder.getCallingUid() != Process.myUid()) {
8562                    // Only system code can grant URI permissions on behalf
8563                    // of other users.
8564                    throw new SecurityException("nice try");
8565                }
8566            }
8567            if (targetPkg == null) {
8568                throw new IllegalArgumentException("null target");
8569            }
8570            if (uri == null) {
8571                throw new IllegalArgumentException("null uri");
8572            }
8573
8574            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8575                    modeFlags, owner, targetUserId);
8576        }
8577    }
8578
8579    /**
8580     * @param uri This uri must NOT contain an embedded userId.
8581     * @param userId The userId in which the uri is to be resolved.
8582     */
8583    @Override
8584    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8585        synchronized(this) {
8586            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8587            if (owner == null) {
8588                throw new IllegalArgumentException("Unknown owner: " + token);
8589            }
8590
8591            if (uri == null) {
8592                owner.removeUriPermissionsLocked(mode);
8593            } else {
8594                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8595            }
8596        }
8597    }
8598
8599    private void schedulePersistUriGrants() {
8600        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8601            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8602                    10 * DateUtils.SECOND_IN_MILLIS);
8603        }
8604    }
8605
8606    private void writeGrantedUriPermissions() {
8607        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8608
8609        // Snapshot permissions so we can persist without lock
8610        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8611        synchronized (this) {
8612            final int size = mGrantedUriPermissions.size();
8613            for (int i = 0; i < size; i++) {
8614                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8615                for (UriPermission perm : perms.values()) {
8616                    if (perm.persistedModeFlags != 0) {
8617                        persist.add(perm.snapshot());
8618                    }
8619                }
8620            }
8621        }
8622
8623        FileOutputStream fos = null;
8624        try {
8625            fos = mGrantFile.startWrite();
8626
8627            XmlSerializer out = new FastXmlSerializer();
8628            out.setOutput(fos, StandardCharsets.UTF_8.name());
8629            out.startDocument(null, true);
8630            out.startTag(null, TAG_URI_GRANTS);
8631            for (UriPermission.Snapshot perm : persist) {
8632                out.startTag(null, TAG_URI_GRANT);
8633                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8634                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8635                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8636                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8637                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8638                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8639                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8640                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8641                out.endTag(null, TAG_URI_GRANT);
8642            }
8643            out.endTag(null, TAG_URI_GRANTS);
8644            out.endDocument();
8645
8646            mGrantFile.finishWrite(fos);
8647        } catch (IOException e) {
8648            if (fos != null) {
8649                mGrantFile.failWrite(fos);
8650            }
8651        }
8652    }
8653
8654    private void readGrantedUriPermissionsLocked() {
8655        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8656
8657        final long now = System.currentTimeMillis();
8658
8659        FileInputStream fis = null;
8660        try {
8661            fis = mGrantFile.openRead();
8662            final XmlPullParser in = Xml.newPullParser();
8663            in.setInput(fis, StandardCharsets.UTF_8.name());
8664
8665            int type;
8666            while ((type = in.next()) != END_DOCUMENT) {
8667                final String tag = in.getName();
8668                if (type == START_TAG) {
8669                    if (TAG_URI_GRANT.equals(tag)) {
8670                        final int sourceUserId;
8671                        final int targetUserId;
8672                        final int userHandle = readIntAttribute(in,
8673                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8674                        if (userHandle != UserHandle.USER_NULL) {
8675                            // For backwards compatibility.
8676                            sourceUserId = userHandle;
8677                            targetUserId = userHandle;
8678                        } else {
8679                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8680                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8681                        }
8682                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8683                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8684                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8685                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8686                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8687                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8688
8689                        // Sanity check that provider still belongs to source package
8690                        // Both direct boot aware and unaware packages are fine as we
8691                        // will do filtering at query time to avoid multiple parsing.
8692                        final ProviderInfo pi = getProviderInfoLocked(
8693                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8694                                        | MATCH_DIRECT_BOOT_UNAWARE);
8695                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8696                            int targetUid = -1;
8697                            try {
8698                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8699                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8700                            } catch (RemoteException e) {
8701                            }
8702                            if (targetUid != -1) {
8703                                final UriPermission perm = findOrCreateUriPermissionLocked(
8704                                        sourcePkg, targetPkg, targetUid,
8705                                        new GrantUri(sourceUserId, uri, prefix));
8706                                perm.initPersistedModes(modeFlags, createdTime);
8707                            }
8708                        } else {
8709                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8710                                    + " but instead found " + pi);
8711                        }
8712                    }
8713                }
8714            }
8715        } catch (FileNotFoundException e) {
8716            // Missing grants is okay
8717        } catch (IOException e) {
8718            Slog.wtf(TAG, "Failed reading Uri grants", e);
8719        } catch (XmlPullParserException e) {
8720            Slog.wtf(TAG, "Failed reading Uri grants", e);
8721        } finally {
8722            IoUtils.closeQuietly(fis);
8723        }
8724    }
8725
8726    /**
8727     * @param uri This uri must NOT contain an embedded userId.
8728     * @param userId The userId in which the uri is to be resolved.
8729     */
8730    @Override
8731    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8732        enforceNotIsolatedCaller("takePersistableUriPermission");
8733
8734        Preconditions.checkFlagsArgument(modeFlags,
8735                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8736
8737        synchronized (this) {
8738            final int callingUid = Binder.getCallingUid();
8739            boolean persistChanged = false;
8740            GrantUri grantUri = new GrantUri(userId, uri, false);
8741
8742            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8743                    new GrantUri(userId, uri, false));
8744            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8745                    new GrantUri(userId, uri, true));
8746
8747            final boolean exactValid = (exactPerm != null)
8748                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8749            final boolean prefixValid = (prefixPerm != null)
8750                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8751
8752            if (!(exactValid || prefixValid)) {
8753                throw new SecurityException("No persistable permission grants found for UID "
8754                        + callingUid + " and Uri " + grantUri.toSafeString());
8755            }
8756
8757            if (exactValid) {
8758                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8759            }
8760            if (prefixValid) {
8761                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8762            }
8763
8764            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8765
8766            if (persistChanged) {
8767                schedulePersistUriGrants();
8768            }
8769        }
8770    }
8771
8772    /**
8773     * @param uri This uri must NOT contain an embedded userId.
8774     * @param userId The userId in which the uri is to be resolved.
8775     */
8776    @Override
8777    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8778        enforceNotIsolatedCaller("releasePersistableUriPermission");
8779
8780        Preconditions.checkFlagsArgument(modeFlags,
8781                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8782
8783        synchronized (this) {
8784            final int callingUid = Binder.getCallingUid();
8785            boolean persistChanged = false;
8786
8787            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8788                    new GrantUri(userId, uri, false));
8789            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8790                    new GrantUri(userId, uri, true));
8791            if (exactPerm == null && prefixPerm == null) {
8792                throw new SecurityException("No permission grants found for UID " + callingUid
8793                        + " and Uri " + uri.toSafeString());
8794            }
8795
8796            if (exactPerm != null) {
8797                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8798                removeUriPermissionIfNeededLocked(exactPerm);
8799            }
8800            if (prefixPerm != null) {
8801                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8802                removeUriPermissionIfNeededLocked(prefixPerm);
8803            }
8804
8805            if (persistChanged) {
8806                schedulePersistUriGrants();
8807            }
8808        }
8809    }
8810
8811    /**
8812     * Prune any older {@link UriPermission} for the given UID until outstanding
8813     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8814     *
8815     * @return if any mutations occured that require persisting.
8816     */
8817    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8818        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8819        if (perms == null) return false;
8820        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8821
8822        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8823        for (UriPermission perm : perms.values()) {
8824            if (perm.persistedModeFlags != 0) {
8825                persisted.add(perm);
8826            }
8827        }
8828
8829        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8830        if (trimCount <= 0) return false;
8831
8832        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8833        for (int i = 0; i < trimCount; i++) {
8834            final UriPermission perm = persisted.get(i);
8835
8836            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8837                    "Trimming grant created at " + perm.persistedCreateTime);
8838
8839            perm.releasePersistableModes(~0);
8840            removeUriPermissionIfNeededLocked(perm);
8841        }
8842
8843        return true;
8844    }
8845
8846    @Override
8847    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8848            String packageName, boolean incoming) {
8849        enforceNotIsolatedCaller("getPersistedUriPermissions");
8850        Preconditions.checkNotNull(packageName, "packageName");
8851
8852        final int callingUid = Binder.getCallingUid();
8853        final int callingUserId = UserHandle.getUserId(callingUid);
8854        final IPackageManager pm = AppGlobals.getPackageManager();
8855        try {
8856            final int packageUid = pm.getPackageUid(packageName,
8857                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8858            if (packageUid != callingUid) {
8859                throw new SecurityException(
8860                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8861            }
8862        } catch (RemoteException e) {
8863            throw new SecurityException("Failed to verify package name ownership");
8864        }
8865
8866        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8867        synchronized (this) {
8868            if (incoming) {
8869                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8870                        callingUid);
8871                if (perms == null) {
8872                    Slog.w(TAG, "No permission grants found for " + packageName);
8873                } else {
8874                    for (UriPermission perm : perms.values()) {
8875                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8876                            result.add(perm.buildPersistedPublicApiObject());
8877                        }
8878                    }
8879                }
8880            } else {
8881                final int size = mGrantedUriPermissions.size();
8882                for (int i = 0; i < size; i++) {
8883                    final ArrayMap<GrantUri, UriPermission> perms =
8884                            mGrantedUriPermissions.valueAt(i);
8885                    for (UriPermission perm : perms.values()) {
8886                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8887                            result.add(perm.buildPersistedPublicApiObject());
8888                        }
8889                    }
8890                }
8891            }
8892        }
8893        return new ParceledListSlice<android.content.UriPermission>(result);
8894    }
8895
8896    @Override
8897    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8898            String packageName, int userId) {
8899        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8900                "getGrantedUriPermissions");
8901
8902        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8903        synchronized (this) {
8904            final int size = mGrantedUriPermissions.size();
8905            for (int i = 0; i < size; i++) {
8906                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8907                for (UriPermission perm : perms.values()) {
8908                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8909                            && perm.persistedModeFlags != 0) {
8910                        result.add(perm.buildPersistedPublicApiObject());
8911                    }
8912                }
8913            }
8914        }
8915        return new ParceledListSlice<android.content.UriPermission>(result);
8916    }
8917
8918    @Override
8919    public void clearGrantedUriPermissions(String packageName, int userId) {
8920        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8921                "clearGrantedUriPermissions");
8922        removeUriPermissionsForPackageLocked(packageName, userId, true);
8923    }
8924
8925    @Override
8926    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8927        synchronized (this) {
8928            ProcessRecord app =
8929                who != null ? getRecordForAppLocked(who) : null;
8930            if (app == null) return;
8931
8932            Message msg = Message.obtain();
8933            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8934            msg.obj = app;
8935            msg.arg1 = waiting ? 1 : 0;
8936            mUiHandler.sendMessage(msg);
8937        }
8938    }
8939
8940    @Override
8941    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8942        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8943        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8944        outInfo.availMem = Process.getFreeMemory();
8945        outInfo.totalMem = Process.getTotalMemory();
8946        outInfo.threshold = homeAppMem;
8947        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8948        outInfo.hiddenAppThreshold = cachedAppMem;
8949        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8950                ProcessList.SERVICE_ADJ);
8951        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8952                ProcessList.VISIBLE_APP_ADJ);
8953        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8954                ProcessList.FOREGROUND_APP_ADJ);
8955    }
8956
8957    // =========================================================
8958    // TASK MANAGEMENT
8959    // =========================================================
8960
8961    @Override
8962    public List<IAppTask> getAppTasks(String callingPackage) {
8963        int callingUid = Binder.getCallingUid();
8964        long ident = Binder.clearCallingIdentity();
8965
8966        synchronized(this) {
8967            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8968            try {
8969                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8970
8971                final int N = mRecentTasks.size();
8972                for (int i = 0; i < N; i++) {
8973                    TaskRecord tr = mRecentTasks.get(i);
8974                    // Skip tasks that do not match the caller.  We don't need to verify
8975                    // callingPackage, because we are also limiting to callingUid and know
8976                    // that will limit to the correct security sandbox.
8977                    if (tr.effectiveUid != callingUid) {
8978                        continue;
8979                    }
8980                    Intent intent = tr.getBaseIntent();
8981                    if (intent == null ||
8982                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8983                        continue;
8984                    }
8985                    ActivityManager.RecentTaskInfo taskInfo =
8986                            createRecentTaskInfoFromTaskRecord(tr);
8987                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8988                    list.add(taskImpl);
8989                }
8990            } finally {
8991                Binder.restoreCallingIdentity(ident);
8992            }
8993            return list;
8994        }
8995    }
8996
8997    @Override
8998    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8999        final int callingUid = Binder.getCallingUid();
9000        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9001
9002        synchronized(this) {
9003            if (DEBUG_ALL) Slog.v(
9004                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9005
9006            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9007                    callingUid);
9008
9009            // TODO: Improve with MRU list from all ActivityStacks.
9010            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9011        }
9012
9013        return list;
9014    }
9015
9016    /**
9017     * Creates a new RecentTaskInfo from a TaskRecord.
9018     */
9019    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9020        // Update the task description to reflect any changes in the task stack
9021        tr.updateTaskDescription();
9022
9023        // Compose the recent task info
9024        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9025        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9026        rti.persistentId = tr.taskId;
9027        rti.baseIntent = new Intent(tr.getBaseIntent());
9028        rti.origActivity = tr.origActivity;
9029        rti.realActivity = tr.realActivity;
9030        rti.description = tr.lastDescription;
9031        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9032        rti.userId = tr.userId;
9033        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9034        rti.firstActiveTime = tr.firstActiveTime;
9035        rti.lastActiveTime = tr.lastActiveTime;
9036        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9037        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9038        rti.numActivities = 0;
9039        if (tr.mBounds != null) {
9040            rti.bounds = new Rect(tr.mBounds);
9041        }
9042        rti.isDockable = tr.canGoInDockedStack();
9043        rti.resizeMode = tr.mResizeMode;
9044
9045        ActivityRecord base = null;
9046        ActivityRecord top = null;
9047        ActivityRecord tmp;
9048
9049        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9050            tmp = tr.mActivities.get(i);
9051            if (tmp.finishing) {
9052                continue;
9053            }
9054            base = tmp;
9055            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9056                top = base;
9057            }
9058            rti.numActivities++;
9059        }
9060
9061        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9062        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9063
9064        return rti;
9065    }
9066
9067    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9068        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9069                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9070        if (!allowed) {
9071            if (checkPermission(android.Manifest.permission.GET_TASKS,
9072                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9073                // Temporary compatibility: some existing apps on the system image may
9074                // still be requesting the old permission and not switched to the new
9075                // one; if so, we'll still allow them full access.  This means we need
9076                // to see if they are holding the old permission and are a system app.
9077                try {
9078                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9079                        allowed = true;
9080                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9081                                + " is using old GET_TASKS but privileged; allowing");
9082                    }
9083                } catch (RemoteException e) {
9084                }
9085            }
9086        }
9087        if (!allowed) {
9088            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9089                    + " does not hold REAL_GET_TASKS; limiting output");
9090        }
9091        return allowed;
9092    }
9093
9094    @Override
9095    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9096        final int callingUid = Binder.getCallingUid();
9097        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9098                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9099
9100        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9101        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9102        synchronized (this) {
9103            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9104                    callingUid);
9105            final boolean detailed = checkCallingPermission(
9106                    android.Manifest.permission.GET_DETAILED_TASKS)
9107                    == PackageManager.PERMISSION_GRANTED;
9108
9109            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9110                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9111                return Collections.emptyList();
9112            }
9113            mRecentTasks.loadUserRecentsLocked(userId);
9114
9115            final int recentsCount = mRecentTasks.size();
9116            ArrayList<ActivityManager.RecentTaskInfo> res =
9117                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9118
9119            final Set<Integer> includedUsers;
9120            if (includeProfiles) {
9121                includedUsers = mUserController.getProfileIds(userId);
9122            } else {
9123                includedUsers = new HashSet<>();
9124            }
9125            includedUsers.add(Integer.valueOf(userId));
9126
9127            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9128                TaskRecord tr = mRecentTasks.get(i);
9129                // Only add calling user or related users recent tasks
9130                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9131                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9132                    continue;
9133                }
9134
9135                if (tr.realActivitySuspended) {
9136                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9137                    continue;
9138                }
9139
9140                // Return the entry if desired by the caller.  We always return
9141                // the first entry, because callers always expect this to be the
9142                // foreground app.  We may filter others if the caller has
9143                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9144                // we should exclude the entry.
9145
9146                if (i == 0
9147                        || withExcluded
9148                        || (tr.intent == null)
9149                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9150                                == 0)) {
9151                    if (!allowed) {
9152                        // If the caller doesn't have the GET_TASKS permission, then only
9153                        // allow them to see a small subset of tasks -- their own and home.
9154                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9155                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9156                            continue;
9157                        }
9158                    }
9159                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9160                        if (tr.stack != null && tr.stack.isHomeStack()) {
9161                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9162                                    "Skipping, home stack task: " + tr);
9163                            continue;
9164                        }
9165                    }
9166                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9167                        final ActivityStack stack = tr.stack;
9168                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9169                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9170                                    "Skipping, top task in docked stack: " + tr);
9171                            continue;
9172                        }
9173                    }
9174                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9175                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9176                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9177                                    "Skipping, pinned stack task: " + tr);
9178                            continue;
9179                        }
9180                    }
9181                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9182                        // Don't include auto remove tasks that are finished or finishing.
9183                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9184                                "Skipping, auto-remove without activity: " + tr);
9185                        continue;
9186                    }
9187                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9188                            && !tr.isAvailable) {
9189                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9190                                "Skipping, unavail real act: " + tr);
9191                        continue;
9192                    }
9193
9194                    if (!tr.mUserSetupComplete) {
9195                        // Don't include task launched while user is not done setting-up.
9196                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9197                                "Skipping, user setup not complete: " + tr);
9198                        continue;
9199                    }
9200
9201                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9202                    if (!detailed) {
9203                        rti.baseIntent.replaceExtras((Bundle)null);
9204                    }
9205
9206                    res.add(rti);
9207                    maxNum--;
9208                }
9209            }
9210            return res;
9211        }
9212    }
9213
9214    @Override
9215    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9216        synchronized (this) {
9217            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9218                    "getTaskThumbnail()");
9219            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9220                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9221            if (tr != null) {
9222                return tr.getTaskThumbnailLocked();
9223            }
9224        }
9225        return null;
9226    }
9227
9228    @Override
9229    public int addAppTask(IBinder activityToken, Intent intent,
9230            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9231        final int callingUid = Binder.getCallingUid();
9232        final long callingIdent = Binder.clearCallingIdentity();
9233
9234        try {
9235            synchronized (this) {
9236                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9237                if (r == null) {
9238                    throw new IllegalArgumentException("Activity does not exist; token="
9239                            + activityToken);
9240                }
9241                ComponentName comp = intent.getComponent();
9242                if (comp == null) {
9243                    throw new IllegalArgumentException("Intent " + intent
9244                            + " must specify explicit component");
9245                }
9246                if (thumbnail.getWidth() != mThumbnailWidth
9247                        || thumbnail.getHeight() != mThumbnailHeight) {
9248                    throw new IllegalArgumentException("Bad thumbnail size: got "
9249                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9250                            + mThumbnailWidth + "x" + mThumbnailHeight);
9251                }
9252                if (intent.getSelector() != null) {
9253                    intent.setSelector(null);
9254                }
9255                if (intent.getSourceBounds() != null) {
9256                    intent.setSourceBounds(null);
9257                }
9258                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9259                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9260                        // The caller has added this as an auto-remove task...  that makes no
9261                        // sense, so turn off auto-remove.
9262                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9263                    }
9264                }
9265                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9266                    mLastAddedTaskActivity = null;
9267                }
9268                ActivityInfo ainfo = mLastAddedTaskActivity;
9269                if (ainfo == null) {
9270                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9271                            comp, 0, UserHandle.getUserId(callingUid));
9272                    if (ainfo.applicationInfo.uid != callingUid) {
9273                        throw new SecurityException(
9274                                "Can't add task for another application: target uid="
9275                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9276                    }
9277                }
9278
9279                // Use the full screen as the context for the task thumbnail
9280                final Point displaySize = new Point();
9281                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9282                r.task.stack.getDisplaySize(displaySize);
9283                thumbnailInfo.taskWidth = displaySize.x;
9284                thumbnailInfo.taskHeight = displaySize.y;
9285                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9286
9287                TaskRecord task = new TaskRecord(this,
9288                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9289                        ainfo, intent, description, thumbnailInfo);
9290
9291                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9292                if (trimIdx >= 0) {
9293                    // If this would have caused a trim, then we'll abort because that
9294                    // means it would be added at the end of the list but then just removed.
9295                    return INVALID_TASK_ID;
9296                }
9297
9298                final int N = mRecentTasks.size();
9299                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9300                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9301                    tr.removedFromRecents();
9302                }
9303
9304                task.inRecents = true;
9305                mRecentTasks.add(task);
9306                r.task.stack.addTask(task, false, "addAppTask");
9307
9308                task.setLastThumbnailLocked(thumbnail);
9309                task.freeLastThumbnail();
9310
9311                return task.taskId;
9312            }
9313        } finally {
9314            Binder.restoreCallingIdentity(callingIdent);
9315        }
9316    }
9317
9318    @Override
9319    public Point getAppTaskThumbnailSize() {
9320        synchronized (this) {
9321            return new Point(mThumbnailWidth,  mThumbnailHeight);
9322        }
9323    }
9324
9325    @Override
9326    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9327        synchronized (this) {
9328            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9329            if (r != null) {
9330                r.setTaskDescription(td);
9331                r.task.updateTaskDescription();
9332            }
9333        }
9334    }
9335
9336    @Override
9337    public void setTaskResizeable(int taskId, int resizeableMode) {
9338        synchronized (this) {
9339            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9340                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9341            if (task == null) {
9342                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9343                return;
9344            }
9345            if (task.mResizeMode != resizeableMode) {
9346                task.mResizeMode = resizeableMode;
9347                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9348                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9349                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9350            }
9351        }
9352    }
9353
9354    @Override
9355    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9356        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9357        long ident = Binder.clearCallingIdentity();
9358        try {
9359            synchronized (this) {
9360                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9361                if (task == null) {
9362                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9363                    return;
9364                }
9365                int stackId = task.stack.mStackId;
9366                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9367                // in crop windows resize mode or if the task size is affected by the docked stack
9368                // changing size. No need to update configuration.
9369                if (bounds != null && task.inCropWindowsResizeMode()
9370                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9371                    mWindowManager.scrollTask(task.taskId, bounds);
9372                    return;
9373                }
9374
9375                // Place the task in the right stack if it isn't there already based on
9376                // the requested bounds.
9377                // The stack transition logic is:
9378                // - a null bounds on a freeform task moves that task to fullscreen
9379                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9380                //   that task to freeform
9381                // - otherwise the task is not moved
9382                if (!StackId.isTaskResizeAllowed(stackId)) {
9383                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9384                }
9385                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9386                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9387                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9388                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9389                }
9390                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9391                if (stackId != task.stack.mStackId) {
9392                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9393                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9394                    preserveWindow = false;
9395                }
9396
9397                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9398                        false /* deferResume */);
9399            }
9400        } finally {
9401            Binder.restoreCallingIdentity(ident);
9402        }
9403    }
9404
9405    @Override
9406    public Rect getTaskBounds(int taskId) {
9407        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9408        long ident = Binder.clearCallingIdentity();
9409        Rect rect = new Rect();
9410        try {
9411            synchronized (this) {
9412                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9413                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9414                if (task == null) {
9415                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9416                    return rect;
9417                }
9418                if (task.stack != null) {
9419                    // Return the bounds from window manager since it will be adjusted for various
9420                    // things like the presense of a docked stack for tasks that aren't resizeable.
9421                    mWindowManager.getTaskBounds(task.taskId, rect);
9422                } else {
9423                    // Task isn't in window manager yet since it isn't associated with a stack.
9424                    // Return the persist value from activity manager
9425                    if (task.mBounds != null) {
9426                        rect.set(task.mBounds);
9427                    } else if (task.mLastNonFullscreenBounds != null) {
9428                        rect.set(task.mLastNonFullscreenBounds);
9429                    }
9430                }
9431            }
9432        } finally {
9433            Binder.restoreCallingIdentity(ident);
9434        }
9435        return rect;
9436    }
9437
9438    @Override
9439    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9440        if (userId != UserHandle.getCallingUserId()) {
9441            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9442                    "getTaskDescriptionIcon");
9443        }
9444        final File passedIconFile = new File(filePath);
9445        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9446                passedIconFile.getName());
9447        if (!legitIconFile.getPath().equals(filePath)
9448                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9449            throw new IllegalArgumentException("Bad file path: " + filePath
9450                    + " passed for userId " + userId);
9451        }
9452        return mRecentTasks.getTaskDescriptionIcon(filePath);
9453    }
9454
9455    @Override
9456    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9457            throws RemoteException {
9458        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9459                opts.getCustomInPlaceResId() == 0) {
9460            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9461                    "with valid animation");
9462        }
9463        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9464        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9465                opts.getCustomInPlaceResId());
9466        mWindowManager.executeAppTransition();
9467    }
9468
9469    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9470            boolean removeFromRecents) {
9471        if (removeFromRecents) {
9472            mRecentTasks.remove(tr);
9473            tr.removedFromRecents();
9474        }
9475        ComponentName component = tr.getBaseIntent().getComponent();
9476        if (component == null) {
9477            Slog.w(TAG, "No component for base intent of task: " + tr);
9478            return;
9479        }
9480
9481        // Find any running services associated with this app and stop if needed.
9482        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9483
9484        if (!killProcess) {
9485            return;
9486        }
9487
9488        // Determine if the process(es) for this task should be killed.
9489        final String pkg = component.getPackageName();
9490        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9491        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9492        for (int i = 0; i < pmap.size(); i++) {
9493
9494            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9495            for (int j = 0; j < uids.size(); j++) {
9496                ProcessRecord proc = uids.valueAt(j);
9497                if (proc.userId != tr.userId) {
9498                    // Don't kill process for a different user.
9499                    continue;
9500                }
9501                if (proc == mHomeProcess) {
9502                    // Don't kill the home process along with tasks from the same package.
9503                    continue;
9504                }
9505                if (!proc.pkgList.containsKey(pkg)) {
9506                    // Don't kill process that is not associated with this task.
9507                    continue;
9508                }
9509
9510                for (int k = 0; k < proc.activities.size(); k++) {
9511                    TaskRecord otherTask = proc.activities.get(k).task;
9512                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9513                        // Don't kill process(es) that has an activity in a different task that is
9514                        // also in recents.
9515                        return;
9516                    }
9517                }
9518
9519                if (proc.foregroundServices) {
9520                    // Don't kill process(es) with foreground service.
9521                    return;
9522                }
9523
9524                // Add process to kill list.
9525                procsToKill.add(proc);
9526            }
9527        }
9528
9529        // Kill the running processes.
9530        for (int i = 0; i < procsToKill.size(); i++) {
9531            ProcessRecord pr = procsToKill.get(i);
9532            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9533                    && pr.curReceiver == null) {
9534                pr.kill("remove task", true);
9535            } else {
9536                // We delay killing processes that are not in the background or running a receiver.
9537                pr.waitingToKill = "remove task";
9538            }
9539        }
9540    }
9541
9542    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9543        // Remove all tasks with activities in the specified package from the list of recent tasks
9544        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9545            TaskRecord tr = mRecentTasks.get(i);
9546            if (tr.userId != userId) continue;
9547
9548            ComponentName cn = tr.intent.getComponent();
9549            if (cn != null && cn.getPackageName().equals(packageName)) {
9550                // If the package name matches, remove the task.
9551                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9552            }
9553        }
9554    }
9555
9556    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9557            int userId) {
9558
9559        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9560            TaskRecord tr = mRecentTasks.get(i);
9561            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9562                continue;
9563            }
9564
9565            ComponentName cn = tr.intent.getComponent();
9566            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9567                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9568            if (sameComponent) {
9569                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9570            }
9571        }
9572    }
9573
9574    /**
9575     * Removes the task with the specified task id.
9576     *
9577     * @param taskId Identifier of the task to be removed.
9578     * @param killProcess Kill any process associated with the task if possible.
9579     * @param removeFromRecents Whether to also remove the task from recents.
9580     * @return Returns true if the given task was found and removed.
9581     */
9582    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9583            boolean removeFromRecents) {
9584        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9585                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9586        if (tr != null) {
9587            tr.removeTaskActivitiesLocked();
9588            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9589            if (tr.isPersistable) {
9590                notifyTaskPersisterLocked(null, true);
9591            }
9592            return true;
9593        }
9594        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9595        return false;
9596    }
9597
9598    @Override
9599    public void removeStack(int stackId) {
9600        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9601        if (stackId == HOME_STACK_ID) {
9602            throw new IllegalArgumentException("Removing home stack is not allowed.");
9603        }
9604
9605        synchronized (this) {
9606            final long ident = Binder.clearCallingIdentity();
9607            try {
9608                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9609                if (stack == null) {
9610                    return;
9611                }
9612                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9613                for (int i = tasks.size() - 1; i >= 0; i--) {
9614                    removeTaskByIdLocked(
9615                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9616                }
9617            } finally {
9618                Binder.restoreCallingIdentity(ident);
9619            }
9620        }
9621    }
9622
9623    @Override
9624    public boolean removeTask(int taskId) {
9625        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9626        synchronized (this) {
9627            final long ident = Binder.clearCallingIdentity();
9628            try {
9629                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9630            } finally {
9631                Binder.restoreCallingIdentity(ident);
9632            }
9633        }
9634    }
9635
9636    /**
9637     * TODO: Add mController hook
9638     */
9639    @Override
9640    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9641        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9642
9643        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9644        synchronized(this) {
9645            moveTaskToFrontLocked(taskId, flags, bOptions);
9646        }
9647    }
9648
9649    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9650        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9651
9652        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9653                Binder.getCallingUid(), -1, -1, "Task to front")) {
9654            ActivityOptions.abort(options);
9655            return;
9656        }
9657        final long origId = Binder.clearCallingIdentity();
9658        try {
9659            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9660            if (task == null) {
9661                Slog.d(TAG, "Could not find task for id: "+ taskId);
9662                return;
9663            }
9664            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9665                mStackSupervisor.showLockTaskToast();
9666                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9667                return;
9668            }
9669            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9670            if (prev != null && prev.isRecentsActivity()) {
9671                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9672            }
9673            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9674                    false /* forceNonResizable */);
9675        } finally {
9676            Binder.restoreCallingIdentity(origId);
9677        }
9678        ActivityOptions.abort(options);
9679    }
9680
9681    /**
9682     * Moves an activity, and all of the other activities within the same task, to the bottom
9683     * of the history stack.  The activity's order within the task is unchanged.
9684     *
9685     * @param token A reference to the activity we wish to move
9686     * @param nonRoot If false then this only works if the activity is the root
9687     *                of a task; if true it will work for any activity in a task.
9688     * @return Returns true if the move completed, false if not.
9689     */
9690    @Override
9691    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9692        enforceNotIsolatedCaller("moveActivityTaskToBack");
9693        synchronized(this) {
9694            final long origId = Binder.clearCallingIdentity();
9695            try {
9696                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9697                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9698                if (task != null) {
9699                    if (mStackSupervisor.isLockedTask(task)) {
9700                        mStackSupervisor.showLockTaskToast();
9701                        return false;
9702                    }
9703                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9704                }
9705            } finally {
9706                Binder.restoreCallingIdentity(origId);
9707            }
9708        }
9709        return false;
9710    }
9711
9712    @Override
9713    public void moveTaskBackwards(int task) {
9714        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9715                "moveTaskBackwards()");
9716
9717        synchronized(this) {
9718            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9719                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9720                return;
9721            }
9722            final long origId = Binder.clearCallingIdentity();
9723            moveTaskBackwardsLocked(task);
9724            Binder.restoreCallingIdentity(origId);
9725        }
9726    }
9727
9728    private final void moveTaskBackwardsLocked(int task) {
9729        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9730    }
9731
9732    @Override
9733    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9734            IActivityContainerCallback callback) throws RemoteException {
9735        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9736        synchronized (this) {
9737            if (parentActivityToken == null) {
9738                throw new IllegalArgumentException("parent token must not be null");
9739            }
9740            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9741            if (r == null) {
9742                return null;
9743            }
9744            if (callback == null) {
9745                throw new IllegalArgumentException("callback must not be null");
9746            }
9747            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9748        }
9749    }
9750
9751    @Override
9752    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9753        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9754        synchronized (this) {
9755            mStackSupervisor.deleteActivityContainer(container);
9756        }
9757    }
9758
9759    @Override
9760    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9761        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9762        synchronized (this) {
9763            final int stackId = mStackSupervisor.getNextStackId();
9764            final ActivityStack stack =
9765                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9766            if (stack == null) {
9767                return null;
9768            }
9769            return stack.mActivityContainer;
9770        }
9771    }
9772
9773    @Override
9774    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9775        synchronized (this) {
9776            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9777            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9778                return stack.mActivityContainer.getDisplayId();
9779            }
9780            return Display.DEFAULT_DISPLAY;
9781        }
9782    }
9783
9784    @Override
9785    public int getActivityStackId(IBinder token) throws RemoteException {
9786        synchronized (this) {
9787            ActivityStack stack = ActivityRecord.getStackLocked(token);
9788            if (stack == null) {
9789                return INVALID_STACK_ID;
9790            }
9791            return stack.mStackId;
9792        }
9793    }
9794
9795    @Override
9796    public void exitFreeformMode(IBinder token) throws RemoteException {
9797        synchronized (this) {
9798            long ident = Binder.clearCallingIdentity();
9799            try {
9800                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9801                if (r == null) {
9802                    throw new IllegalArgumentException(
9803                            "exitFreeformMode: No activity record matching token=" + token);
9804                }
9805                final ActivityStack stack = r.getStackLocked(token);
9806                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9807                    throw new IllegalStateException(
9808                            "exitFreeformMode: You can only go fullscreen from freeform.");
9809                }
9810                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9811                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9812                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9813            } finally {
9814                Binder.restoreCallingIdentity(ident);
9815            }
9816        }
9817    }
9818
9819    @Override
9820    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9821        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9822        if (stackId == HOME_STACK_ID) {
9823            throw new IllegalArgumentException(
9824                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9825        }
9826        synchronized (this) {
9827            long ident = Binder.clearCallingIdentity();
9828            try {
9829                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9830                        + " to stackId=" + stackId + " toTop=" + toTop);
9831                if (stackId == DOCKED_STACK_ID) {
9832                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9833                            null /* initialBounds */);
9834                }
9835                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9836                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9837                if (result && stackId == DOCKED_STACK_ID) {
9838                    // If task moved to docked stack - show recents if needed.
9839                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9840                            "moveTaskToDockedStack");
9841                }
9842            } finally {
9843                Binder.restoreCallingIdentity(ident);
9844            }
9845        }
9846    }
9847
9848    @Override
9849    public void swapDockedAndFullscreenStack() throws RemoteException {
9850        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9851        synchronized (this) {
9852            long ident = Binder.clearCallingIdentity();
9853            try {
9854                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9855                        FULLSCREEN_WORKSPACE_STACK_ID);
9856                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9857                        : null;
9858                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9859                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9860                        : null;
9861                if (topTask == null || tasks == null || tasks.size() == 0) {
9862                    Slog.w(TAG,
9863                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9864                    return;
9865                }
9866
9867                // TODO: App transition
9868                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9869
9870                // Defer the resume so resume/pausing while moving stacks is dangerous.
9871                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9872                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9873                        ANIMATE, true /* deferResume */);
9874                final int size = tasks.size();
9875                for (int i = 0; i < size; i++) {
9876                    final int id = tasks.get(i).taskId;
9877                    if (id == topTask.taskId) {
9878                        continue;
9879                    }
9880                    mStackSupervisor.moveTaskToStackLocked(id,
9881                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9882                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9883                }
9884
9885                // Because we deferred the resume, to avoid conflicts with stack switches while
9886                // resuming, we need to do it after all the tasks are moved.
9887                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9888                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9889
9890                mWindowManager.executeAppTransition();
9891            } finally {
9892                Binder.restoreCallingIdentity(ident);
9893            }
9894        }
9895    }
9896
9897    /**
9898     * Moves the input task to the docked stack.
9899     *
9900     * @param taskId Id of task to move.
9901     * @param createMode The mode the docked stack should be created in if it doesn't exist
9902     *                   already. See
9903     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9904     *                   and
9905     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9906     * @param toTop If the task and stack should be moved to the top.
9907     * @param animate Whether we should play an animation for the moving the task
9908     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9909     *                      docked stack. Pass {@code null} to use default bounds.
9910     */
9911    @Override
9912    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9913            Rect initialBounds, boolean moveHomeStackFront) {
9914        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9915        synchronized (this) {
9916            long ident = Binder.clearCallingIdentity();
9917            try {
9918                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9919                        + " to createMode=" + createMode + " toTop=" + toTop);
9920                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9921                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9922                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9923                        animate, DEFER_RESUME);
9924                if (moved) {
9925                    if (moveHomeStackFront) {
9926                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9927                    }
9928                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9929                }
9930                return moved;
9931            } finally {
9932                Binder.restoreCallingIdentity(ident);
9933            }
9934        }
9935    }
9936
9937    /**
9938     * Moves the top activity in the input stackId to the pinned stack.
9939     *
9940     * @param stackId Id of stack to move the top activity to pinned stack.
9941     * @param bounds Bounds to use for pinned stack.
9942     *
9943     * @return True if the top activity of the input stack was successfully moved to the pinned
9944     *          stack.
9945     */
9946    @Override
9947    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9948        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9949        synchronized (this) {
9950            if (!mSupportsPictureInPicture) {
9951                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9952                        + "Device doesn't support picture-in-pciture mode");
9953            }
9954
9955            long ident = Binder.clearCallingIdentity();
9956            try {
9957                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9958            } finally {
9959                Binder.restoreCallingIdentity(ident);
9960            }
9961        }
9962    }
9963
9964    @Override
9965    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9966            boolean preserveWindows, boolean animate, int animationDuration) {
9967        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9968        long ident = Binder.clearCallingIdentity();
9969        try {
9970            synchronized (this) {
9971                if (animate) {
9972                    if (stackId == PINNED_STACK_ID) {
9973                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9974                    } else {
9975                        throw new IllegalArgumentException("Stack: " + stackId
9976                                + " doesn't support animated resize.");
9977                    }
9978                } else {
9979                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9980                            null /* tempTaskInsetBounds */, preserveWindows,
9981                            allowResizeInDockedMode, !DEFER_RESUME);
9982                }
9983            }
9984        } finally {
9985            Binder.restoreCallingIdentity(ident);
9986        }
9987    }
9988
9989    @Override
9990    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9991            Rect tempDockedTaskInsetBounds,
9992            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9993        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9994                "resizeDockedStack()");
9995        long ident = Binder.clearCallingIdentity();
9996        try {
9997            synchronized (this) {
9998                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9999                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10000                        PRESERVE_WINDOWS);
10001            }
10002        } finally {
10003            Binder.restoreCallingIdentity(ident);
10004        }
10005    }
10006
10007    @Override
10008    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10009        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10010                "resizePinnedStack()");
10011        final long ident = Binder.clearCallingIdentity();
10012        try {
10013            synchronized (this) {
10014                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10015            }
10016        } finally {
10017            Binder.restoreCallingIdentity(ident);
10018        }
10019    }
10020
10021    @Override
10022    public void positionTaskInStack(int taskId, int stackId, int position) {
10023        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10024        if (stackId == HOME_STACK_ID) {
10025            throw new IllegalArgumentException(
10026                    "positionTaskInStack: Attempt to change the position of task "
10027                    + taskId + " in/to home stack");
10028        }
10029        synchronized (this) {
10030            long ident = Binder.clearCallingIdentity();
10031            try {
10032                if (DEBUG_STACK) Slog.d(TAG_STACK,
10033                        "positionTaskInStack: positioning task=" + taskId
10034                        + " in stackId=" + stackId + " at position=" + position);
10035                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10036            } finally {
10037                Binder.restoreCallingIdentity(ident);
10038            }
10039        }
10040    }
10041
10042    @Override
10043    public List<StackInfo> getAllStackInfos() {
10044        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10045        long ident = Binder.clearCallingIdentity();
10046        try {
10047            synchronized (this) {
10048                return mStackSupervisor.getAllStackInfosLocked();
10049            }
10050        } finally {
10051            Binder.restoreCallingIdentity(ident);
10052        }
10053    }
10054
10055    @Override
10056    public StackInfo getStackInfo(int stackId) {
10057        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10058        long ident = Binder.clearCallingIdentity();
10059        try {
10060            synchronized (this) {
10061                return mStackSupervisor.getStackInfoLocked(stackId);
10062            }
10063        } finally {
10064            Binder.restoreCallingIdentity(ident);
10065        }
10066    }
10067
10068    @Override
10069    public boolean isInHomeStack(int taskId) {
10070        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10071        long ident = Binder.clearCallingIdentity();
10072        try {
10073            synchronized (this) {
10074                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10075                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10076                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10077            }
10078        } finally {
10079            Binder.restoreCallingIdentity(ident);
10080        }
10081    }
10082
10083    @Override
10084    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10085        synchronized(this) {
10086            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10087        }
10088    }
10089
10090    @Override
10091    public void updateDeviceOwner(String packageName) {
10092        final int callingUid = Binder.getCallingUid();
10093        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10094            throw new SecurityException("updateDeviceOwner called from non-system process");
10095        }
10096        synchronized (this) {
10097            mDeviceOwnerName = packageName;
10098        }
10099    }
10100
10101    @Override
10102    public void updateLockTaskPackages(int userId, String[] packages) {
10103        final int callingUid = Binder.getCallingUid();
10104        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10105            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10106                    "updateLockTaskPackages()");
10107        }
10108        synchronized (this) {
10109            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10110                    Arrays.toString(packages));
10111            mLockTaskPackages.put(userId, packages);
10112            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10113        }
10114    }
10115
10116
10117    void startLockTaskModeLocked(TaskRecord task) {
10118        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10119        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10120            return;
10121        }
10122
10123        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10124        // is initiated by system after the pinning request was shown and locked mode is initiated
10125        // by an authorized app directly
10126        final int callingUid = Binder.getCallingUid();
10127        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10128        long ident = Binder.clearCallingIdentity();
10129        try {
10130            if (!isSystemInitiated) {
10131                task.mLockTaskUid = callingUid;
10132                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10133                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10134                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10135                    StatusBarManagerInternal statusBarManager =
10136                            LocalServices.getService(StatusBarManagerInternal.class);
10137                    if (statusBarManager != null) {
10138                        statusBarManager.showScreenPinningRequest(task.taskId);
10139                    }
10140                    return;
10141                }
10142
10143                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10144                if (stack == null || task != stack.topTask()) {
10145                    throw new IllegalArgumentException("Invalid task, not in foreground");
10146                }
10147            }
10148            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10149                    "Locking fully");
10150            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10151                    ActivityManager.LOCK_TASK_MODE_PINNED :
10152                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10153                    "startLockTask", true);
10154        } finally {
10155            Binder.restoreCallingIdentity(ident);
10156        }
10157    }
10158
10159    @Override
10160    public void startLockTaskMode(int taskId) {
10161        synchronized (this) {
10162            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10163            if (task != null) {
10164                startLockTaskModeLocked(task);
10165            }
10166        }
10167    }
10168
10169    @Override
10170    public void startLockTaskMode(IBinder token) {
10171        synchronized (this) {
10172            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10173            if (r == null) {
10174                return;
10175            }
10176            final TaskRecord task = r.task;
10177            if (task != null) {
10178                startLockTaskModeLocked(task);
10179            }
10180        }
10181    }
10182
10183    @Override
10184    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10185        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10186        // This makes inner call to look as if it was initiated by system.
10187        long ident = Binder.clearCallingIdentity();
10188        try {
10189            synchronized (this) {
10190                startLockTaskMode(taskId);
10191            }
10192        } finally {
10193            Binder.restoreCallingIdentity(ident);
10194        }
10195    }
10196
10197    @Override
10198    public void stopLockTaskMode() {
10199        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10200        if (lockTask == null) {
10201            // Our work here is done.
10202            return;
10203        }
10204
10205        final int callingUid = Binder.getCallingUid();
10206        final int lockTaskUid = lockTask.mLockTaskUid;
10207        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10208        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10209            // Done.
10210            return;
10211        } else {
10212            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10213            // It is possible lockTaskMode was started by the system process because
10214            // android:lockTaskMode is set to a locking value in the application manifest
10215            // instead of the app calling startLockTaskMode. In this case
10216            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10217            // {@link TaskRecord.effectiveUid} instead. Also caller with
10218            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10219            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10220                    && callingUid != lockTaskUid
10221                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10222                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10223                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10224            }
10225        }
10226        long ident = Binder.clearCallingIdentity();
10227        try {
10228            Log.d(TAG, "stopLockTaskMode");
10229            // Stop lock task
10230            synchronized (this) {
10231                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10232                        "stopLockTask", true);
10233            }
10234            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10235            if (tm != null) {
10236                tm.showInCallScreen(false);
10237            }
10238        } finally {
10239            Binder.restoreCallingIdentity(ident);
10240        }
10241    }
10242
10243    /**
10244     * This API should be called by SystemUI only when user perform certain action to dismiss
10245     * lock task mode. We should only dismiss pinned lock task mode in this case.
10246     */
10247    @Override
10248    public void stopSystemLockTaskMode() throws RemoteException {
10249        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10250            stopLockTaskMode();
10251        } else {
10252            mStackSupervisor.showLockTaskToast();
10253        }
10254    }
10255
10256    @Override
10257    public boolean isInLockTaskMode() {
10258        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10259    }
10260
10261    @Override
10262    public int getLockTaskModeState() {
10263        synchronized (this) {
10264            return mStackSupervisor.getLockTaskModeState();
10265        }
10266    }
10267
10268    @Override
10269    public void showLockTaskEscapeMessage(IBinder token) {
10270        synchronized (this) {
10271            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10272            if (r == null) {
10273                return;
10274            }
10275            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10276        }
10277    }
10278
10279    // =========================================================
10280    // CONTENT PROVIDERS
10281    // =========================================================
10282
10283    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10284        List<ProviderInfo> providers = null;
10285        try {
10286            providers = AppGlobals.getPackageManager()
10287                    .queryContentProviders(app.processName, app.uid,
10288                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10289                                    | MATCH_DEBUG_TRIAGED_MISSING)
10290                    .getList();
10291        } catch (RemoteException ex) {
10292        }
10293        if (DEBUG_MU) Slog.v(TAG_MU,
10294                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10295        int userId = app.userId;
10296        if (providers != null) {
10297            int N = providers.size();
10298            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10299            for (int i=0; i<N; i++) {
10300                // TODO: keep logic in sync with installEncryptionUnawareProviders
10301                ProviderInfo cpi =
10302                    (ProviderInfo)providers.get(i);
10303                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10304                        cpi.name, cpi.flags);
10305                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10306                    // This is a singleton provider, but a user besides the
10307                    // default user is asking to initialize a process it runs
10308                    // in...  well, no, it doesn't actually run in this process,
10309                    // it runs in the process of the default user.  Get rid of it.
10310                    providers.remove(i);
10311                    N--;
10312                    i--;
10313                    continue;
10314                }
10315
10316                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10317                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10318                if (cpr == null) {
10319                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10320                    mProviderMap.putProviderByClass(comp, cpr);
10321                }
10322                if (DEBUG_MU) Slog.v(TAG_MU,
10323                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10324                app.pubProviders.put(cpi.name, cpr);
10325                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10326                    // Don't add this if it is a platform component that is marked
10327                    // to run in multiple processes, because this is actually
10328                    // part of the framework so doesn't make sense to track as a
10329                    // separate apk in the process.
10330                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10331                            mProcessStats);
10332                }
10333                notifyPackageUse(cpi.applicationInfo.packageName,
10334                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10335            }
10336        }
10337        return providers;
10338    }
10339
10340    /**
10341     * Check if {@link ProcessRecord} has a possible chance at accessing the
10342     * given {@link ProviderInfo}. Final permission checking is always done
10343     * in {@link ContentProvider}.
10344     */
10345    private final String checkContentProviderPermissionLocked(
10346            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10347        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10348        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10349        boolean checkedGrants = false;
10350        if (checkUser) {
10351            // Looking for cross-user grants before enforcing the typical cross-users permissions
10352            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10353            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10354                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10355                    return null;
10356                }
10357                checkedGrants = true;
10358            }
10359            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10360                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10361            if (userId != tmpTargetUserId) {
10362                // When we actually went to determine the final targer user ID, this ended
10363                // up different than our initial check for the authority.  This is because
10364                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10365                // SELF.  So we need to re-check the grants again.
10366                checkedGrants = false;
10367            }
10368        }
10369        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10370                cpi.applicationInfo.uid, cpi.exported)
10371                == PackageManager.PERMISSION_GRANTED) {
10372            return null;
10373        }
10374        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10375                cpi.applicationInfo.uid, cpi.exported)
10376                == PackageManager.PERMISSION_GRANTED) {
10377            return null;
10378        }
10379
10380        PathPermission[] pps = cpi.pathPermissions;
10381        if (pps != null) {
10382            int i = pps.length;
10383            while (i > 0) {
10384                i--;
10385                PathPermission pp = pps[i];
10386                String pprperm = pp.getReadPermission();
10387                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10388                        cpi.applicationInfo.uid, cpi.exported)
10389                        == PackageManager.PERMISSION_GRANTED) {
10390                    return null;
10391                }
10392                String ppwperm = pp.getWritePermission();
10393                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10394                        cpi.applicationInfo.uid, cpi.exported)
10395                        == PackageManager.PERMISSION_GRANTED) {
10396                    return null;
10397                }
10398            }
10399        }
10400        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10401            return null;
10402        }
10403
10404        String msg;
10405        if (!cpi.exported) {
10406            msg = "Permission Denial: opening provider " + cpi.name
10407                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10408                    + ", uid=" + callingUid + ") that is not exported from uid "
10409                    + cpi.applicationInfo.uid;
10410        } else {
10411            msg = "Permission Denial: opening provider " + cpi.name
10412                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10413                    + ", uid=" + callingUid + ") requires "
10414                    + cpi.readPermission + " or " + cpi.writePermission;
10415        }
10416        Slog.w(TAG, msg);
10417        return msg;
10418    }
10419
10420    /**
10421     * Returns if the ContentProvider has granted a uri to callingUid
10422     */
10423    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10424        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10425        if (perms != null) {
10426            for (int i=perms.size()-1; i>=0; i--) {
10427                GrantUri grantUri = perms.keyAt(i);
10428                if (grantUri.sourceUserId == userId || !checkUser) {
10429                    if (matchesProvider(grantUri.uri, cpi)) {
10430                        return true;
10431                    }
10432                }
10433            }
10434        }
10435        return false;
10436    }
10437
10438    /**
10439     * Returns true if the uri authority is one of the authorities specified in the provider.
10440     */
10441    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10442        String uriAuth = uri.getAuthority();
10443        String cpiAuth = cpi.authority;
10444        if (cpiAuth.indexOf(';') == -1) {
10445            return cpiAuth.equals(uriAuth);
10446        }
10447        String[] cpiAuths = cpiAuth.split(";");
10448        int length = cpiAuths.length;
10449        for (int i = 0; i < length; i++) {
10450            if (cpiAuths[i].equals(uriAuth)) return true;
10451        }
10452        return false;
10453    }
10454
10455    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10456            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10457        if (r != null) {
10458            for (int i=0; i<r.conProviders.size(); i++) {
10459                ContentProviderConnection conn = r.conProviders.get(i);
10460                if (conn.provider == cpr) {
10461                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10462                            "Adding provider requested by "
10463                            + r.processName + " from process "
10464                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10465                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10466                    if (stable) {
10467                        conn.stableCount++;
10468                        conn.numStableIncs++;
10469                    } else {
10470                        conn.unstableCount++;
10471                        conn.numUnstableIncs++;
10472                    }
10473                    return conn;
10474                }
10475            }
10476            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10477            if (stable) {
10478                conn.stableCount = 1;
10479                conn.numStableIncs = 1;
10480            } else {
10481                conn.unstableCount = 1;
10482                conn.numUnstableIncs = 1;
10483            }
10484            cpr.connections.add(conn);
10485            r.conProviders.add(conn);
10486            startAssociationLocked(r.uid, r.processName, r.curProcState,
10487                    cpr.uid, cpr.name, cpr.info.processName);
10488            return conn;
10489        }
10490        cpr.addExternalProcessHandleLocked(externalProcessToken);
10491        return null;
10492    }
10493
10494    boolean decProviderCountLocked(ContentProviderConnection conn,
10495            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10496        if (conn != null) {
10497            cpr = conn.provider;
10498            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10499                    "Removing provider requested by "
10500                    + conn.client.processName + " from process "
10501                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10502                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10503            if (stable) {
10504                conn.stableCount--;
10505            } else {
10506                conn.unstableCount--;
10507            }
10508            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10509                cpr.connections.remove(conn);
10510                conn.client.conProviders.remove(conn);
10511                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10512                    // The client is more important than last activity -- note the time this
10513                    // is happening, so we keep the old provider process around a bit as last
10514                    // activity to avoid thrashing it.
10515                    if (cpr.proc != null) {
10516                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10517                    }
10518                }
10519                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10520                return true;
10521            }
10522            return false;
10523        }
10524        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10525        return false;
10526    }
10527
10528    private void checkTime(long startTime, String where) {
10529        long now = SystemClock.uptimeMillis();
10530        if ((now-startTime) > 50) {
10531            // If we are taking more than 50ms, log about it.
10532            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10533        }
10534    }
10535
10536    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10537            PROC_SPACE_TERM,
10538            PROC_SPACE_TERM|PROC_PARENS,
10539            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10540    };
10541
10542    private final long[] mProcessStateStatsLongs = new long[1];
10543
10544    boolean isProcessAliveLocked(ProcessRecord proc) {
10545        if (proc.procStatFile == null) {
10546            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10547        }
10548        mProcessStateStatsLongs[0] = 0;
10549        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10550                mProcessStateStatsLongs, null)) {
10551            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10552            return false;
10553        }
10554        final long state = mProcessStateStatsLongs[0];
10555        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10556                + (char)state);
10557        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10558    }
10559
10560    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10561            String name, IBinder token, boolean stable, int userId) {
10562        ContentProviderRecord cpr;
10563        ContentProviderConnection conn = null;
10564        ProviderInfo cpi = null;
10565
10566        synchronized(this) {
10567            long startTime = SystemClock.uptimeMillis();
10568
10569            ProcessRecord r = null;
10570            if (caller != null) {
10571                r = getRecordForAppLocked(caller);
10572                if (r == null) {
10573                    throw new SecurityException(
10574                            "Unable to find app for caller " + caller
10575                          + " (pid=" + Binder.getCallingPid()
10576                          + ") when getting content provider " + name);
10577                }
10578            }
10579
10580            boolean checkCrossUser = true;
10581
10582            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10583
10584            // First check if this content provider has been published...
10585            cpr = mProviderMap.getProviderByName(name, userId);
10586            // If that didn't work, check if it exists for user 0 and then
10587            // verify that it's a singleton provider before using it.
10588            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10589                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10590                if (cpr != null) {
10591                    cpi = cpr.info;
10592                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10593                            cpi.name, cpi.flags)
10594                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10595                        userId = UserHandle.USER_SYSTEM;
10596                        checkCrossUser = false;
10597                    } else {
10598                        cpr = null;
10599                        cpi = null;
10600                    }
10601                }
10602            }
10603
10604            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10605            if (providerRunning) {
10606                cpi = cpr.info;
10607                String msg;
10608                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10609                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10610                        != null) {
10611                    throw new SecurityException(msg);
10612                }
10613                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10614
10615                if (r != null && cpr.canRunHere(r)) {
10616                    // This provider has been published or is in the process
10617                    // of being published...  but it is also allowed to run
10618                    // in the caller's process, so don't make a connection
10619                    // and just let the caller instantiate its own instance.
10620                    ContentProviderHolder holder = cpr.newHolder(null);
10621                    // don't give caller the provider object, it needs
10622                    // to make its own.
10623                    holder.provider = null;
10624                    return holder;
10625                }
10626
10627                final long origId = Binder.clearCallingIdentity();
10628
10629                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10630
10631                // In this case the provider instance already exists, so we can
10632                // return it right away.
10633                conn = incProviderCountLocked(r, cpr, token, stable);
10634                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10635                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10636                        // If this is a perceptible app accessing the provider,
10637                        // make sure to count it as being accessed and thus
10638                        // back up on the LRU list.  This is good because
10639                        // content providers are often expensive to start.
10640                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10641                        updateLruProcessLocked(cpr.proc, false, null);
10642                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10643                    }
10644                }
10645
10646                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10647                final int verifiedAdj = cpr.proc.verifiedAdj;
10648                boolean success = updateOomAdjLocked(cpr.proc);
10649                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10650                // if the process has been successfully adjusted.  So to reduce races with
10651                // it, we will check whether the process still exists.  Note that this doesn't
10652                // completely get rid of races with LMK killing the process, but should make
10653                // them much smaller.
10654                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10655                    success = false;
10656                }
10657                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10658                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10659                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10660                // NOTE: there is still a race here where a signal could be
10661                // pending on the process even though we managed to update its
10662                // adj level.  Not sure what to do about this, but at least
10663                // the race is now smaller.
10664                if (!success) {
10665                    // Uh oh...  it looks like the provider's process
10666                    // has been killed on us.  We need to wait for a new
10667                    // process to be started, and make sure its death
10668                    // doesn't kill our process.
10669                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10670                            + " is crashing; detaching " + r);
10671                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10672                    checkTime(startTime, "getContentProviderImpl: before appDied");
10673                    appDiedLocked(cpr.proc);
10674                    checkTime(startTime, "getContentProviderImpl: after appDied");
10675                    if (!lastRef) {
10676                        // This wasn't the last ref our process had on
10677                        // the provider...  we have now been killed, bail.
10678                        return null;
10679                    }
10680                    providerRunning = false;
10681                    conn = null;
10682                } else {
10683                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10684                }
10685
10686                Binder.restoreCallingIdentity(origId);
10687            }
10688
10689            if (!providerRunning) {
10690                try {
10691                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10692                    cpi = AppGlobals.getPackageManager().
10693                        resolveContentProvider(name,
10694                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10695                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10696                } catch (RemoteException ex) {
10697                }
10698                if (cpi == null) {
10699                    return null;
10700                }
10701                // If the provider is a singleton AND
10702                // (it's a call within the same user || the provider is a
10703                // privileged app)
10704                // Then allow connecting to the singleton provider
10705                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10706                        cpi.name, cpi.flags)
10707                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10708                if (singleton) {
10709                    userId = UserHandle.USER_SYSTEM;
10710                }
10711                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10712                checkTime(startTime, "getContentProviderImpl: got app info for user");
10713
10714                String msg;
10715                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10716                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10717                        != null) {
10718                    throw new SecurityException(msg);
10719                }
10720                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10721
10722                if (!mProcessesReady
10723                        && !cpi.processName.equals("system")) {
10724                    // If this content provider does not run in the system
10725                    // process, and the system is not yet ready to run other
10726                    // processes, then fail fast instead of hanging.
10727                    throw new IllegalArgumentException(
10728                            "Attempt to launch content provider before system ready");
10729                }
10730
10731                // Make sure that the user who owns this provider is running.  If not,
10732                // we don't want to allow it to run.
10733                if (!mUserController.isUserRunningLocked(userId, 0)) {
10734                    Slog.w(TAG, "Unable to launch app "
10735                            + cpi.applicationInfo.packageName + "/"
10736                            + cpi.applicationInfo.uid + " for provider "
10737                            + name + ": user " + userId + " is stopped");
10738                    return null;
10739                }
10740
10741                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10742                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10743                cpr = mProviderMap.getProviderByClass(comp, userId);
10744                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10745                final boolean firstClass = cpr == null;
10746                if (firstClass) {
10747                    final long ident = Binder.clearCallingIdentity();
10748
10749                    // If permissions need a review before any of the app components can run,
10750                    // we return no provider and launch a review activity if the calling app
10751                    // is in the foreground.
10752                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10753                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10754                            return null;
10755                        }
10756                    }
10757
10758                    try {
10759                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10760                        ApplicationInfo ai =
10761                            AppGlobals.getPackageManager().
10762                                getApplicationInfo(
10763                                        cpi.applicationInfo.packageName,
10764                                        STOCK_PM_FLAGS, userId);
10765                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10766                        if (ai == null) {
10767                            Slog.w(TAG, "No package info for content provider "
10768                                    + cpi.name);
10769                            return null;
10770                        }
10771                        ai = getAppInfoForUser(ai, userId);
10772                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10773                    } catch (RemoteException ex) {
10774                        // pm is in same process, this will never happen.
10775                    } finally {
10776                        Binder.restoreCallingIdentity(ident);
10777                    }
10778                }
10779
10780                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10781
10782                if (r != null && cpr.canRunHere(r)) {
10783                    // If this is a multiprocess provider, then just return its
10784                    // info and allow the caller to instantiate it.  Only do
10785                    // this if the provider is the same user as the caller's
10786                    // process, or can run as root (so can be in any process).
10787                    return cpr.newHolder(null);
10788                }
10789
10790                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10791                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10792                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10793
10794                // This is single process, and our app is now connecting to it.
10795                // See if we are already in the process of launching this
10796                // provider.
10797                final int N = mLaunchingProviders.size();
10798                int i;
10799                for (i = 0; i < N; i++) {
10800                    if (mLaunchingProviders.get(i) == cpr) {
10801                        break;
10802                    }
10803                }
10804
10805                // If the provider is not already being launched, then get it
10806                // started.
10807                if (i >= N) {
10808                    final long origId = Binder.clearCallingIdentity();
10809
10810                    try {
10811                        // Content provider is now in use, its package can't be stopped.
10812                        try {
10813                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10814                            AppGlobals.getPackageManager().setPackageStoppedState(
10815                                    cpr.appInfo.packageName, false, userId);
10816                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10817                        } catch (RemoteException e) {
10818                        } catch (IllegalArgumentException e) {
10819                            Slog.w(TAG, "Failed trying to unstop package "
10820                                    + cpr.appInfo.packageName + ": " + e);
10821                        }
10822
10823                        // Use existing process if already started
10824                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10825                        ProcessRecord proc = getProcessRecordLocked(
10826                                cpi.processName, cpr.appInfo.uid, false);
10827                        if (proc != null && proc.thread != null && !proc.killed) {
10828                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10829                                    "Installing in existing process " + proc);
10830                            if (!proc.pubProviders.containsKey(cpi.name)) {
10831                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10832                                proc.pubProviders.put(cpi.name, cpr);
10833                                try {
10834                                    proc.thread.scheduleInstallProvider(cpi);
10835                                } catch (RemoteException e) {
10836                                }
10837                            }
10838                        } else {
10839                            checkTime(startTime, "getContentProviderImpl: before start process");
10840                            proc = startProcessLocked(cpi.processName,
10841                                    cpr.appInfo, false, 0, "content provider",
10842                                    new ComponentName(cpi.applicationInfo.packageName,
10843                                            cpi.name), false, false, false);
10844                            checkTime(startTime, "getContentProviderImpl: after start process");
10845                            if (proc == null) {
10846                                Slog.w(TAG, "Unable to launch app "
10847                                        + cpi.applicationInfo.packageName + "/"
10848                                        + cpi.applicationInfo.uid + " for provider "
10849                                        + name + ": process is bad");
10850                                return null;
10851                            }
10852                        }
10853                        cpr.launchingApp = proc;
10854                        mLaunchingProviders.add(cpr);
10855                    } finally {
10856                        Binder.restoreCallingIdentity(origId);
10857                    }
10858                }
10859
10860                checkTime(startTime, "getContentProviderImpl: updating data structures");
10861
10862                // Make sure the provider is published (the same provider class
10863                // may be published under multiple names).
10864                if (firstClass) {
10865                    mProviderMap.putProviderByClass(comp, cpr);
10866                }
10867
10868                mProviderMap.putProviderByName(name, cpr);
10869                conn = incProviderCountLocked(r, cpr, token, stable);
10870                if (conn != null) {
10871                    conn.waiting = true;
10872                }
10873            }
10874            checkTime(startTime, "getContentProviderImpl: done!");
10875        }
10876
10877        // Wait for the provider to be published...
10878        synchronized (cpr) {
10879            while (cpr.provider == null) {
10880                if (cpr.launchingApp == null) {
10881                    Slog.w(TAG, "Unable to launch app "
10882                            + cpi.applicationInfo.packageName + "/"
10883                            + cpi.applicationInfo.uid + " for provider "
10884                            + name + ": launching app became null");
10885                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10886                            UserHandle.getUserId(cpi.applicationInfo.uid),
10887                            cpi.applicationInfo.packageName,
10888                            cpi.applicationInfo.uid, name);
10889                    return null;
10890                }
10891                try {
10892                    if (DEBUG_MU) Slog.v(TAG_MU,
10893                            "Waiting to start provider " + cpr
10894                            + " launchingApp=" + cpr.launchingApp);
10895                    if (conn != null) {
10896                        conn.waiting = true;
10897                    }
10898                    cpr.wait();
10899                } catch (InterruptedException ex) {
10900                } finally {
10901                    if (conn != null) {
10902                        conn.waiting = false;
10903                    }
10904                }
10905            }
10906        }
10907        return cpr != null ? cpr.newHolder(conn) : null;
10908    }
10909
10910    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10911            ProcessRecord r, final int userId) {
10912        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10913                cpi.packageName, userId)) {
10914
10915            final boolean callerForeground = r == null || r.setSchedGroup
10916                    != ProcessList.SCHED_GROUP_BACKGROUND;
10917
10918            // Show a permission review UI only for starting from a foreground app
10919            if (!callerForeground) {
10920                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10921                        + cpi.packageName + " requires a permissions review");
10922                return false;
10923            }
10924
10925            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10926            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10927                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10928            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10929
10930            if (DEBUG_PERMISSIONS_REVIEW) {
10931                Slog.i(TAG, "u" + userId + " Launching permission review "
10932                        + "for package " + cpi.packageName);
10933            }
10934
10935            final UserHandle userHandle = new UserHandle(userId);
10936            mHandler.post(new Runnable() {
10937                @Override
10938                public void run() {
10939                    mContext.startActivityAsUser(intent, userHandle);
10940                }
10941            });
10942
10943            return false;
10944        }
10945
10946        return true;
10947    }
10948
10949    PackageManagerInternal getPackageManagerInternalLocked() {
10950        if (mPackageManagerInt == null) {
10951            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10952        }
10953        return mPackageManagerInt;
10954    }
10955
10956    @Override
10957    public final ContentProviderHolder getContentProvider(
10958            IApplicationThread caller, String name, int userId, boolean stable) {
10959        enforceNotIsolatedCaller("getContentProvider");
10960        if (caller == null) {
10961            String msg = "null IApplicationThread when getting content provider "
10962                    + name;
10963            Slog.w(TAG, msg);
10964            throw new SecurityException(msg);
10965        }
10966        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10967        // with cross-user grant.
10968        return getContentProviderImpl(caller, name, null, stable, userId);
10969    }
10970
10971    public ContentProviderHolder getContentProviderExternal(
10972            String name, int userId, IBinder token) {
10973        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10974            "Do not have permission in call getContentProviderExternal()");
10975        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10976                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10977        return getContentProviderExternalUnchecked(name, token, userId);
10978    }
10979
10980    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10981            IBinder token, int userId) {
10982        return getContentProviderImpl(null, name, token, true, userId);
10983    }
10984
10985    /**
10986     * Drop a content provider from a ProcessRecord's bookkeeping
10987     */
10988    public void removeContentProvider(IBinder connection, boolean stable) {
10989        enforceNotIsolatedCaller("removeContentProvider");
10990        long ident = Binder.clearCallingIdentity();
10991        try {
10992            synchronized (this) {
10993                ContentProviderConnection conn;
10994                try {
10995                    conn = (ContentProviderConnection)connection;
10996                } catch (ClassCastException e) {
10997                    String msg ="removeContentProvider: " + connection
10998                            + " not a ContentProviderConnection";
10999                    Slog.w(TAG, msg);
11000                    throw new IllegalArgumentException(msg);
11001                }
11002                if (conn == null) {
11003                    throw new NullPointerException("connection is null");
11004                }
11005                if (decProviderCountLocked(conn, null, null, stable)) {
11006                    updateOomAdjLocked();
11007                }
11008            }
11009        } finally {
11010            Binder.restoreCallingIdentity(ident);
11011        }
11012    }
11013
11014    public void removeContentProviderExternal(String name, IBinder token) {
11015        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11016            "Do not have permission in call removeContentProviderExternal()");
11017        int userId = UserHandle.getCallingUserId();
11018        long ident = Binder.clearCallingIdentity();
11019        try {
11020            removeContentProviderExternalUnchecked(name, token, userId);
11021        } finally {
11022            Binder.restoreCallingIdentity(ident);
11023        }
11024    }
11025
11026    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11027        synchronized (this) {
11028            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11029            if(cpr == null) {
11030                //remove from mProvidersByClass
11031                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11032                return;
11033            }
11034
11035            //update content provider record entry info
11036            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11037            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11038            if (localCpr.hasExternalProcessHandles()) {
11039                if (localCpr.removeExternalProcessHandleLocked(token)) {
11040                    updateOomAdjLocked();
11041                } else {
11042                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11043                            + " with no external reference for token: "
11044                            + token + ".");
11045                }
11046            } else {
11047                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11048                        + " with no external references.");
11049            }
11050        }
11051    }
11052
11053    public final void publishContentProviders(IApplicationThread caller,
11054            List<ContentProviderHolder> providers) {
11055        if (providers == null) {
11056            return;
11057        }
11058
11059        enforceNotIsolatedCaller("publishContentProviders");
11060        synchronized (this) {
11061            final ProcessRecord r = getRecordForAppLocked(caller);
11062            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11063            if (r == null) {
11064                throw new SecurityException(
11065                        "Unable to find app for caller " + caller
11066                      + " (pid=" + Binder.getCallingPid()
11067                      + ") when publishing content providers");
11068            }
11069
11070            final long origId = Binder.clearCallingIdentity();
11071
11072            final int N = providers.size();
11073            for (int i = 0; i < N; i++) {
11074                ContentProviderHolder src = providers.get(i);
11075                if (src == null || src.info == null || src.provider == null) {
11076                    continue;
11077                }
11078                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11079                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11080                if (dst != null) {
11081                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11082                    mProviderMap.putProviderByClass(comp, dst);
11083                    String names[] = dst.info.authority.split(";");
11084                    for (int j = 0; j < names.length; j++) {
11085                        mProviderMap.putProviderByName(names[j], dst);
11086                    }
11087
11088                    int launchingCount = mLaunchingProviders.size();
11089                    int j;
11090                    boolean wasInLaunchingProviders = false;
11091                    for (j = 0; j < launchingCount; j++) {
11092                        if (mLaunchingProviders.get(j) == dst) {
11093                            mLaunchingProviders.remove(j);
11094                            wasInLaunchingProviders = true;
11095                            j--;
11096                            launchingCount--;
11097                        }
11098                    }
11099                    if (wasInLaunchingProviders) {
11100                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11101                    }
11102                    synchronized (dst) {
11103                        dst.provider = src.provider;
11104                        dst.proc = r;
11105                        dst.notifyAll();
11106                    }
11107                    updateOomAdjLocked(r);
11108                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11109                            src.info.authority);
11110                }
11111            }
11112
11113            Binder.restoreCallingIdentity(origId);
11114        }
11115    }
11116
11117    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11118        ContentProviderConnection conn;
11119        try {
11120            conn = (ContentProviderConnection)connection;
11121        } catch (ClassCastException e) {
11122            String msg ="refContentProvider: " + connection
11123                    + " not a ContentProviderConnection";
11124            Slog.w(TAG, msg);
11125            throw new IllegalArgumentException(msg);
11126        }
11127        if (conn == null) {
11128            throw new NullPointerException("connection is null");
11129        }
11130
11131        synchronized (this) {
11132            if (stable > 0) {
11133                conn.numStableIncs += stable;
11134            }
11135            stable = conn.stableCount + stable;
11136            if (stable < 0) {
11137                throw new IllegalStateException("stableCount < 0: " + stable);
11138            }
11139
11140            if (unstable > 0) {
11141                conn.numUnstableIncs += unstable;
11142            }
11143            unstable = conn.unstableCount + unstable;
11144            if (unstable < 0) {
11145                throw new IllegalStateException("unstableCount < 0: " + unstable);
11146            }
11147
11148            if ((stable+unstable) <= 0) {
11149                throw new IllegalStateException("ref counts can't go to zero here: stable="
11150                        + stable + " unstable=" + unstable);
11151            }
11152            conn.stableCount = stable;
11153            conn.unstableCount = unstable;
11154            return !conn.dead;
11155        }
11156    }
11157
11158    public void unstableProviderDied(IBinder connection) {
11159        ContentProviderConnection conn;
11160        try {
11161            conn = (ContentProviderConnection)connection;
11162        } catch (ClassCastException e) {
11163            String msg ="refContentProvider: " + connection
11164                    + " not a ContentProviderConnection";
11165            Slog.w(TAG, msg);
11166            throw new IllegalArgumentException(msg);
11167        }
11168        if (conn == null) {
11169            throw new NullPointerException("connection is null");
11170        }
11171
11172        // Safely retrieve the content provider associated with the connection.
11173        IContentProvider provider;
11174        synchronized (this) {
11175            provider = conn.provider.provider;
11176        }
11177
11178        if (provider == null) {
11179            // Um, yeah, we're way ahead of you.
11180            return;
11181        }
11182
11183        // Make sure the caller is being honest with us.
11184        if (provider.asBinder().pingBinder()) {
11185            // Er, no, still looks good to us.
11186            synchronized (this) {
11187                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11188                        + " says " + conn + " died, but we don't agree");
11189                return;
11190            }
11191        }
11192
11193        // Well look at that!  It's dead!
11194        synchronized (this) {
11195            if (conn.provider.provider != provider) {
11196                // But something changed...  good enough.
11197                return;
11198            }
11199
11200            ProcessRecord proc = conn.provider.proc;
11201            if (proc == null || proc.thread == null) {
11202                // Seems like the process is already cleaned up.
11203                return;
11204            }
11205
11206            // As far as we're concerned, this is just like receiving a
11207            // death notification...  just a bit prematurely.
11208            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11209                    + ") early provider death");
11210            final long ident = Binder.clearCallingIdentity();
11211            try {
11212                appDiedLocked(proc);
11213            } finally {
11214                Binder.restoreCallingIdentity(ident);
11215            }
11216        }
11217    }
11218
11219    @Override
11220    public void appNotRespondingViaProvider(IBinder connection) {
11221        enforceCallingPermission(
11222                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11223
11224        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11225        if (conn == null) {
11226            Slog.w(TAG, "ContentProviderConnection is null");
11227            return;
11228        }
11229
11230        final ProcessRecord host = conn.provider.proc;
11231        if (host == null) {
11232            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11233            return;
11234        }
11235
11236        mHandler.post(new Runnable() {
11237            @Override
11238            public void run() {
11239                mAppErrors.appNotResponding(host, null, null, false,
11240                        "ContentProvider not responding");
11241            }
11242        });
11243    }
11244
11245    public final void installSystemProviders() {
11246        List<ProviderInfo> providers;
11247        synchronized (this) {
11248            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11249            providers = generateApplicationProvidersLocked(app);
11250            if (providers != null) {
11251                for (int i=providers.size()-1; i>=0; i--) {
11252                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11253                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11254                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11255                                + ": not system .apk");
11256                        providers.remove(i);
11257                    }
11258                }
11259            }
11260        }
11261        if (providers != null) {
11262            mSystemThread.installSystemProviders(providers);
11263        }
11264
11265        mCoreSettingsObserver = new CoreSettingsObserver(this);
11266        mFontScaleSettingObserver = new FontScaleSettingObserver();
11267
11268        //mUsageStatsService.monitorPackages();
11269    }
11270
11271    private void startPersistentApps(int matchFlags) {
11272        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11273
11274        synchronized (this) {
11275            try {
11276                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11277                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11278                for (ApplicationInfo app : apps) {
11279                    if (!"android".equals(app.packageName)) {
11280                        addAppLocked(app, false, null /* ABI override */);
11281                    }
11282                }
11283            } catch (RemoteException ex) {
11284            }
11285        }
11286    }
11287
11288    /**
11289     * When a user is unlocked, we need to install encryption-unaware providers
11290     * belonging to any running apps.
11291     */
11292    private void installEncryptionUnawareProviders(int userId) {
11293        // We're only interested in providers that are encryption unaware, and
11294        // we don't care about uninstalled apps, since there's no way they're
11295        // running at this point.
11296        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11297
11298        synchronized (this) {
11299            final int NP = mProcessNames.getMap().size();
11300            for (int ip = 0; ip < NP; ip++) {
11301                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11302                final int NA = apps.size();
11303                for (int ia = 0; ia < NA; ia++) {
11304                    final ProcessRecord app = apps.valueAt(ia);
11305                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11306
11307                    final int NG = app.pkgList.size();
11308                    for (int ig = 0; ig < NG; ig++) {
11309                        try {
11310                            final String pkgName = app.pkgList.keyAt(ig);
11311                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11312                                    .getPackageInfo(pkgName, matchFlags, userId);
11313                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11314                                for (ProviderInfo pi : pkgInfo.providers) {
11315                                    // TODO: keep in sync with generateApplicationProvidersLocked
11316                                    final boolean processMatch = Objects.equals(pi.processName,
11317                                            app.processName) || pi.multiprocess;
11318                                    final boolean userMatch = isSingleton(pi.processName,
11319                                            pi.applicationInfo, pi.name, pi.flags)
11320                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11321                                    if (processMatch && userMatch) {
11322                                        Log.v(TAG, "Installing " + pi);
11323                                        app.thread.scheduleInstallProvider(pi);
11324                                    } else {
11325                                        Log.v(TAG, "Skipping " + pi);
11326                                    }
11327                                }
11328                            }
11329                        } catch (RemoteException ignored) {
11330                        }
11331                    }
11332                }
11333            }
11334        }
11335    }
11336
11337    /**
11338     * Allows apps to retrieve the MIME type of a URI.
11339     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11340     * users, then it does not need permission to access the ContentProvider.
11341     * Either, it needs cross-user uri grants.
11342     *
11343     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11344     *
11345     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11346     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11347     */
11348    public String getProviderMimeType(Uri uri, int userId) {
11349        enforceNotIsolatedCaller("getProviderMimeType");
11350        final String name = uri.getAuthority();
11351        int callingUid = Binder.getCallingUid();
11352        int callingPid = Binder.getCallingPid();
11353        long ident = 0;
11354        boolean clearedIdentity = false;
11355        synchronized (this) {
11356            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11357        }
11358        if (canClearIdentity(callingPid, callingUid, userId)) {
11359            clearedIdentity = true;
11360            ident = Binder.clearCallingIdentity();
11361        }
11362        ContentProviderHolder holder = null;
11363        try {
11364            holder = getContentProviderExternalUnchecked(name, null, userId);
11365            if (holder != null) {
11366                return holder.provider.getType(uri);
11367            }
11368        } catch (RemoteException e) {
11369            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11370            return null;
11371        } catch (Exception e) {
11372            Log.w(TAG, "Exception while determining type of " + uri, e);
11373            return null;
11374        } finally {
11375            // We need to clear the identity to call removeContentProviderExternalUnchecked
11376            if (!clearedIdentity) {
11377                ident = Binder.clearCallingIdentity();
11378            }
11379            try {
11380                if (holder != null) {
11381                    removeContentProviderExternalUnchecked(name, null, userId);
11382                }
11383            } finally {
11384                Binder.restoreCallingIdentity(ident);
11385            }
11386        }
11387
11388        return null;
11389    }
11390
11391    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11392        if (UserHandle.getUserId(callingUid) == userId) {
11393            return true;
11394        }
11395        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11396                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11397                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11398                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11399                return true;
11400        }
11401        return false;
11402    }
11403
11404    // =========================================================
11405    // GLOBAL MANAGEMENT
11406    // =========================================================
11407
11408    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11409            boolean isolated, int isolatedUid) {
11410        String proc = customProcess != null ? customProcess : info.processName;
11411        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11412        final int userId = UserHandle.getUserId(info.uid);
11413        int uid = info.uid;
11414        if (isolated) {
11415            if (isolatedUid == 0) {
11416                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11417                while (true) {
11418                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11419                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11420                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11421                    }
11422                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11423                    mNextIsolatedProcessUid++;
11424                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11425                        // No process for this uid, use it.
11426                        break;
11427                    }
11428                    stepsLeft--;
11429                    if (stepsLeft <= 0) {
11430                        return null;
11431                    }
11432                }
11433            } else {
11434                // Special case for startIsolatedProcess (internal only), where
11435                // the uid of the isolated process is specified by the caller.
11436                uid = isolatedUid;
11437            }
11438        }
11439        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11440        if (!mBooted && !mBooting
11441                && userId == UserHandle.USER_SYSTEM
11442                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11443            r.persistent = true;
11444        }
11445        addProcessNameLocked(r);
11446        return r;
11447    }
11448
11449    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11450            String abiOverride) {
11451        ProcessRecord app;
11452        if (!isolated) {
11453            app = getProcessRecordLocked(info.processName, info.uid, true);
11454        } else {
11455            app = null;
11456        }
11457
11458        if (app == null) {
11459            app = newProcessRecordLocked(info, null, isolated, 0);
11460            updateLruProcessLocked(app, false, null);
11461            updateOomAdjLocked();
11462        }
11463
11464        // This package really, really can not be stopped.
11465        try {
11466            AppGlobals.getPackageManager().setPackageStoppedState(
11467                    info.packageName, false, UserHandle.getUserId(app.uid));
11468        } catch (RemoteException e) {
11469        } catch (IllegalArgumentException e) {
11470            Slog.w(TAG, "Failed trying to unstop package "
11471                    + info.packageName + ": " + e);
11472        }
11473
11474        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11475            app.persistent = true;
11476            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11477        }
11478        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11479            mPersistentStartingProcesses.add(app);
11480            startProcessLocked(app, "added application", app.processName, abiOverride,
11481                    null /* entryPoint */, null /* entryPointArgs */);
11482        }
11483
11484        return app;
11485    }
11486
11487    public void unhandledBack() {
11488        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11489                "unhandledBack()");
11490
11491        synchronized(this) {
11492            final long origId = Binder.clearCallingIdentity();
11493            try {
11494                getFocusedStack().unhandledBackLocked();
11495            } finally {
11496                Binder.restoreCallingIdentity(origId);
11497            }
11498        }
11499    }
11500
11501    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11502        enforceNotIsolatedCaller("openContentUri");
11503        final int userId = UserHandle.getCallingUserId();
11504        String name = uri.getAuthority();
11505        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11506        ParcelFileDescriptor pfd = null;
11507        if (cph != null) {
11508            // We record the binder invoker's uid in thread-local storage before
11509            // going to the content provider to open the file.  Later, in the code
11510            // that handles all permissions checks, we look for this uid and use
11511            // that rather than the Activity Manager's own uid.  The effect is that
11512            // we do the check against the caller's permissions even though it looks
11513            // to the content provider like the Activity Manager itself is making
11514            // the request.
11515            Binder token = new Binder();
11516            sCallerIdentity.set(new Identity(
11517                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11518            try {
11519                pfd = cph.provider.openFile(null, uri, "r", null, token);
11520            } catch (FileNotFoundException e) {
11521                // do nothing; pfd will be returned null
11522            } finally {
11523                // Ensure that whatever happens, we clean up the identity state
11524                sCallerIdentity.remove();
11525                // Ensure we're done with the provider.
11526                removeContentProviderExternalUnchecked(name, null, userId);
11527            }
11528        } else {
11529            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11530        }
11531        return pfd;
11532    }
11533
11534    // Actually is sleeping or shutting down or whatever else in the future
11535    // is an inactive state.
11536    boolean isSleepingOrShuttingDownLocked() {
11537        return isSleepingLocked() || mShuttingDown;
11538    }
11539
11540    boolean isShuttingDownLocked() {
11541        return mShuttingDown;
11542    }
11543
11544    boolean isSleepingLocked() {
11545        return mSleeping;
11546    }
11547
11548    void onWakefulnessChanged(int wakefulness) {
11549        synchronized(this) {
11550            mWakefulness = wakefulness;
11551            updateSleepIfNeededLocked();
11552        }
11553    }
11554
11555    void finishRunningVoiceLocked() {
11556        if (mRunningVoice != null) {
11557            mRunningVoice = null;
11558            mVoiceWakeLock.release();
11559            updateSleepIfNeededLocked();
11560        }
11561    }
11562
11563    void startTimeTrackingFocusedActivityLocked() {
11564        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11565            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11566        }
11567    }
11568
11569    void updateSleepIfNeededLocked() {
11570        if (mSleeping && !shouldSleepLocked()) {
11571            mSleeping = false;
11572            startTimeTrackingFocusedActivityLocked();
11573            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11574            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11575            updateOomAdjLocked();
11576        } else if (!mSleeping && shouldSleepLocked()) {
11577            mSleeping = true;
11578            if (mCurAppTimeTracker != null) {
11579                mCurAppTimeTracker.stop();
11580            }
11581            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11582            mStackSupervisor.goingToSleepLocked();
11583            updateOomAdjLocked();
11584
11585            // Initialize the wake times of all processes.
11586            checkExcessivePowerUsageLocked(false);
11587            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11588            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11589            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11590        }
11591    }
11592
11593    private boolean shouldSleepLocked() {
11594        // Resume applications while running a voice interactor.
11595        if (mRunningVoice != null) {
11596            return false;
11597        }
11598
11599        // TODO: Transform the lock screen state into a sleep token instead.
11600        switch (mWakefulness) {
11601            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11602            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11603            case PowerManagerInternal.WAKEFULNESS_DOZING:
11604                // Pause applications whenever the lock screen is shown or any sleep
11605                // tokens have been acquired.
11606                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11607            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11608            default:
11609                // If we're asleep then pause applications unconditionally.
11610                return true;
11611        }
11612    }
11613
11614    /** Pokes the task persister. */
11615    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11616        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11617    }
11618
11619    /** Notifies all listeners when the task stack has changed. */
11620    void notifyTaskStackChangedLocked() {
11621        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11622        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11623        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11624        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11625    }
11626
11627    /** Notifies all listeners when an Activity is pinned. */
11628    void notifyActivityPinnedLocked() {
11629        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11630        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11631    }
11632
11633    /**
11634     * Notifies all listeners when an attempt was made to start an an activity that is already
11635     * running in the pinned stack and the activity was not actually started, but the task is
11636     * either brought to the front or a new Intent is delivered to it.
11637     */
11638    void notifyPinnedActivityRestartAttemptLocked() {
11639        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11640        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11641    }
11642
11643    /** Notifies all listeners when the pinned stack animation ends. */
11644    @Override
11645    public void notifyPinnedStackAnimationEnded() {
11646        synchronized (this) {
11647            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11648            mHandler.obtainMessage(
11649                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11650        }
11651    }
11652
11653    @Override
11654    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11655        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11656    }
11657
11658    @Override
11659    public boolean shutdown(int timeout) {
11660        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11661                != PackageManager.PERMISSION_GRANTED) {
11662            throw new SecurityException("Requires permission "
11663                    + android.Manifest.permission.SHUTDOWN);
11664        }
11665
11666        boolean timedout = false;
11667
11668        synchronized(this) {
11669            mShuttingDown = true;
11670            updateEventDispatchingLocked();
11671            timedout = mStackSupervisor.shutdownLocked(timeout);
11672        }
11673
11674        mAppOpsService.shutdown();
11675        if (mUsageStatsService != null) {
11676            mUsageStatsService.prepareShutdown();
11677        }
11678        mBatteryStatsService.shutdown();
11679        synchronized (this) {
11680            mProcessStats.shutdownLocked();
11681            notifyTaskPersisterLocked(null, true);
11682        }
11683
11684        return timedout;
11685    }
11686
11687    public final void activitySlept(IBinder token) {
11688        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11689
11690        final long origId = Binder.clearCallingIdentity();
11691
11692        synchronized (this) {
11693            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11694            if (r != null) {
11695                mStackSupervisor.activitySleptLocked(r);
11696            }
11697        }
11698
11699        Binder.restoreCallingIdentity(origId);
11700    }
11701
11702    private String lockScreenShownToString() {
11703        switch (mLockScreenShown) {
11704            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11705            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11706            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11707            default: return "Unknown=" + mLockScreenShown;
11708        }
11709    }
11710
11711    void logLockScreen(String msg) {
11712        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11713                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11714                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11715                + " mSleeping=" + mSleeping);
11716    }
11717
11718    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11719        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11720        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11721        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11722            boolean wasRunningVoice = mRunningVoice != null;
11723            mRunningVoice = session;
11724            if (!wasRunningVoice) {
11725                mVoiceWakeLock.acquire();
11726                updateSleepIfNeededLocked();
11727            }
11728        }
11729    }
11730
11731    private void updateEventDispatchingLocked() {
11732        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11733    }
11734
11735    public void setLockScreenShown(boolean showing, boolean occluded) {
11736        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11737                != PackageManager.PERMISSION_GRANTED) {
11738            throw new SecurityException("Requires permission "
11739                    + android.Manifest.permission.DEVICE_POWER);
11740        }
11741
11742        synchronized(this) {
11743            long ident = Binder.clearCallingIdentity();
11744            try {
11745                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11746                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11747                if (showing && occluded) {
11748                    // The lock screen is currently showing, but is occluded by a window that can
11749                    // show on top of the lock screen. In this can we want to dismiss the docked
11750                    // stack since it will be complicated/risky to try to put the activity on top
11751                    // of the lock screen in the right fullscreen configuration.
11752                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11753                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11754                }
11755
11756                updateSleepIfNeededLocked();
11757            } finally {
11758                Binder.restoreCallingIdentity(ident);
11759            }
11760        }
11761    }
11762
11763    @Override
11764    public void notifyLockedProfile(@UserIdInt int userId) {
11765        try {
11766            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11767                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11768            }
11769        } catch (RemoteException ex) {
11770            throw new SecurityException("Fail to check is caller a privileged app", ex);
11771        }
11772
11773        synchronized (this) {
11774            if (mStackSupervisor.isUserLockedProfile(userId)) {
11775                final long ident = Binder.clearCallingIdentity();
11776                try {
11777                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11778                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11779                        // If there is no device lock, we will show the profile's credential page.
11780                        mActivityStarter.showConfirmDeviceCredential(userId);
11781                    } else {
11782                        // Showing launcher to avoid user entering credential twice.
11783                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11784                    }
11785                } finally {
11786                    Binder.restoreCallingIdentity(ident);
11787                }
11788            }
11789        }
11790    }
11791
11792    @Override
11793    public void startConfirmDeviceCredentialIntent(Intent intent) {
11794        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11795        synchronized (this) {
11796            final long ident = Binder.clearCallingIdentity();
11797            try {
11798                mActivityStarter.startConfirmCredentialIntent(intent);
11799            } finally {
11800                Binder.restoreCallingIdentity(ident);
11801            }
11802        }
11803    }
11804
11805    @Override
11806    public void stopAppSwitches() {
11807        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11808                != PackageManager.PERMISSION_GRANTED) {
11809            throw new SecurityException("viewquires permission "
11810                    + android.Manifest.permission.STOP_APP_SWITCHES);
11811        }
11812
11813        synchronized(this) {
11814            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11815                    + APP_SWITCH_DELAY_TIME;
11816            mDidAppSwitch = false;
11817            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11818            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11819            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11820        }
11821    }
11822
11823    public void resumeAppSwitches() {
11824        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11825                != PackageManager.PERMISSION_GRANTED) {
11826            throw new SecurityException("Requires permission "
11827                    + android.Manifest.permission.STOP_APP_SWITCHES);
11828        }
11829
11830        synchronized(this) {
11831            // Note that we don't execute any pending app switches... we will
11832            // let those wait until either the timeout, or the next start
11833            // activity request.
11834            mAppSwitchesAllowedTime = 0;
11835        }
11836    }
11837
11838    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11839            int callingPid, int callingUid, String name) {
11840        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11841            return true;
11842        }
11843
11844        int perm = checkComponentPermission(
11845                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11846                sourceUid, -1, true);
11847        if (perm == PackageManager.PERMISSION_GRANTED) {
11848            return true;
11849        }
11850
11851        // If the actual IPC caller is different from the logical source, then
11852        // also see if they are allowed to control app switches.
11853        if (callingUid != -1 && callingUid != sourceUid) {
11854            perm = checkComponentPermission(
11855                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11856                    callingUid, -1, true);
11857            if (perm == PackageManager.PERMISSION_GRANTED) {
11858                return true;
11859            }
11860        }
11861
11862        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11863        return false;
11864    }
11865
11866    public void setDebugApp(String packageName, boolean waitForDebugger,
11867            boolean persistent) {
11868        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11869                "setDebugApp()");
11870
11871        long ident = Binder.clearCallingIdentity();
11872        try {
11873            // Note that this is not really thread safe if there are multiple
11874            // callers into it at the same time, but that's not a situation we
11875            // care about.
11876            if (persistent) {
11877                final ContentResolver resolver = mContext.getContentResolver();
11878                Settings.Global.putString(
11879                    resolver, Settings.Global.DEBUG_APP,
11880                    packageName);
11881                Settings.Global.putInt(
11882                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11883                    waitForDebugger ? 1 : 0);
11884            }
11885
11886            synchronized (this) {
11887                if (!persistent) {
11888                    mOrigDebugApp = mDebugApp;
11889                    mOrigWaitForDebugger = mWaitForDebugger;
11890                }
11891                mDebugApp = packageName;
11892                mWaitForDebugger = waitForDebugger;
11893                mDebugTransient = !persistent;
11894                if (packageName != null) {
11895                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11896                            false, UserHandle.USER_ALL, "set debug app");
11897                }
11898            }
11899        } finally {
11900            Binder.restoreCallingIdentity(ident);
11901        }
11902    }
11903
11904    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11905        synchronized (this) {
11906            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11907            if (!isDebuggable) {
11908                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11909                    throw new SecurityException("Process not debuggable: " + app.packageName);
11910                }
11911            }
11912
11913            mTrackAllocationApp = processName;
11914        }
11915    }
11916
11917    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11918        synchronized (this) {
11919            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11920            if (!isDebuggable) {
11921                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11922                    throw new SecurityException("Process not debuggable: " + app.packageName);
11923                }
11924            }
11925            mProfileApp = processName;
11926            mProfileFile = profilerInfo.profileFile;
11927            if (mProfileFd != null) {
11928                try {
11929                    mProfileFd.close();
11930                } catch (IOException e) {
11931                }
11932                mProfileFd = null;
11933            }
11934            mProfileFd = profilerInfo.profileFd;
11935            mSamplingInterval = profilerInfo.samplingInterval;
11936            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11937            mProfileType = 0;
11938        }
11939    }
11940
11941    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11942        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11943        if (!isDebuggable) {
11944            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11945                throw new SecurityException("Process not debuggable: " + app.packageName);
11946            }
11947        }
11948        mNativeDebuggingApp = processName;
11949    }
11950
11951    @Override
11952    public void setAlwaysFinish(boolean enabled) {
11953        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11954                "setAlwaysFinish()");
11955
11956        long ident = Binder.clearCallingIdentity();
11957        try {
11958            Settings.Global.putInt(
11959                    mContext.getContentResolver(),
11960                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11961
11962            synchronized (this) {
11963                mAlwaysFinishActivities = enabled;
11964            }
11965        } finally {
11966            Binder.restoreCallingIdentity(ident);
11967        }
11968    }
11969
11970    @Override
11971    public void setLenientBackgroundCheck(boolean enabled) {
11972        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11973                "setLenientBackgroundCheck()");
11974
11975        long ident = Binder.clearCallingIdentity();
11976        try {
11977            Settings.Global.putInt(
11978                    mContext.getContentResolver(),
11979                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11980
11981            synchronized (this) {
11982                mLenientBackgroundCheck = enabled;
11983            }
11984        } finally {
11985            Binder.restoreCallingIdentity(ident);
11986        }
11987    }
11988
11989    @Override
11990    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11991        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11992                "setActivityController()");
11993        synchronized (this) {
11994            mController = controller;
11995            mControllerIsAMonkey = imAMonkey;
11996            Watchdog.getInstance().setActivityController(controller);
11997        }
11998    }
11999
12000    @Override
12001    public void setUserIsMonkey(boolean userIsMonkey) {
12002        synchronized (this) {
12003            synchronized (mPidsSelfLocked) {
12004                final int callingPid = Binder.getCallingPid();
12005                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12006                if (precessRecord == null) {
12007                    throw new SecurityException("Unknown process: " + callingPid);
12008                }
12009                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12010                    throw new SecurityException("Only an instrumentation process "
12011                            + "with a UiAutomation can call setUserIsMonkey");
12012                }
12013            }
12014            mUserIsMonkey = userIsMonkey;
12015        }
12016    }
12017
12018    @Override
12019    public boolean isUserAMonkey() {
12020        synchronized (this) {
12021            // If there is a controller also implies the user is a monkey.
12022            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12023        }
12024    }
12025
12026    public void requestBugReport(int bugreportType) {
12027        String service = null;
12028        switch (bugreportType) {
12029            case ActivityManager.BUGREPORT_OPTION_FULL:
12030                service = "bugreport";
12031                break;
12032            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12033                service = "bugreportplus";
12034                break;
12035            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12036                service = "bugreportremote";
12037                break;
12038        }
12039        if (service == null) {
12040            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12041                    + bugreportType);
12042        }
12043        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12044        SystemProperties.set("ctl.start", service);
12045    }
12046
12047    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12048        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12049    }
12050
12051    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12052        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12053            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12054        }
12055        return KEY_DISPATCHING_TIMEOUT;
12056    }
12057
12058    @Override
12059    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12060        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12061                != PackageManager.PERMISSION_GRANTED) {
12062            throw new SecurityException("Requires permission "
12063                    + android.Manifest.permission.FILTER_EVENTS);
12064        }
12065        ProcessRecord proc;
12066        long timeout;
12067        synchronized (this) {
12068            synchronized (mPidsSelfLocked) {
12069                proc = mPidsSelfLocked.get(pid);
12070            }
12071            timeout = getInputDispatchingTimeoutLocked(proc);
12072        }
12073
12074        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12075            return -1;
12076        }
12077
12078        return timeout;
12079    }
12080
12081    /**
12082     * Handle input dispatching timeouts.
12083     * Returns whether input dispatching should be aborted or not.
12084     */
12085    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12086            final ActivityRecord activity, final ActivityRecord parent,
12087            final boolean aboveSystem, String reason) {
12088        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12089                != PackageManager.PERMISSION_GRANTED) {
12090            throw new SecurityException("Requires permission "
12091                    + android.Manifest.permission.FILTER_EVENTS);
12092        }
12093
12094        final String annotation;
12095        if (reason == null) {
12096            annotation = "Input dispatching timed out";
12097        } else {
12098            annotation = "Input dispatching timed out (" + reason + ")";
12099        }
12100
12101        if (proc != null) {
12102            synchronized (this) {
12103                if (proc.debugging) {
12104                    return false;
12105                }
12106
12107                if (mDidDexOpt) {
12108                    // Give more time since we were dexopting.
12109                    mDidDexOpt = false;
12110                    return false;
12111                }
12112
12113                if (proc.instrumentationClass != null) {
12114                    Bundle info = new Bundle();
12115                    info.putString("shortMsg", "keyDispatchingTimedOut");
12116                    info.putString("longMsg", annotation);
12117                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12118                    return true;
12119                }
12120            }
12121            mHandler.post(new Runnable() {
12122                @Override
12123                public void run() {
12124                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12125                }
12126            });
12127        }
12128
12129        return true;
12130    }
12131
12132    @Override
12133    public Bundle getAssistContextExtras(int requestType) {
12134        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12135                null, null, true /* focused */, true /* newSessionId */,
12136                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12137        if (pae == null) {
12138            return null;
12139        }
12140        synchronized (pae) {
12141            while (!pae.haveResult) {
12142                try {
12143                    pae.wait();
12144                } catch (InterruptedException e) {
12145                }
12146            }
12147        }
12148        synchronized (this) {
12149            buildAssistBundleLocked(pae, pae.result);
12150            mPendingAssistExtras.remove(pae);
12151            mUiHandler.removeCallbacks(pae);
12152        }
12153        return pae.extras;
12154    }
12155
12156    @Override
12157    public boolean isAssistDataAllowedOnCurrentActivity() {
12158        int userId;
12159        synchronized (this) {
12160            userId = mUserController.getCurrentUserIdLocked();
12161            ActivityRecord activity = getFocusedStack().topActivity();
12162            if (activity == null) {
12163                return false;
12164            }
12165            userId = activity.userId;
12166        }
12167        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12168                Context.DEVICE_POLICY_SERVICE);
12169        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12170    }
12171
12172    @Override
12173    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12174        long ident = Binder.clearCallingIdentity();
12175        try {
12176            synchronized (this) {
12177                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12178                ActivityRecord top = getFocusedStack().topActivity();
12179                if (top != caller) {
12180                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12181                            + " is not current top " + top);
12182                    return false;
12183                }
12184                if (!top.nowVisible) {
12185                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12186                            + " is not visible");
12187                    return false;
12188                }
12189            }
12190            AssistUtils utils = new AssistUtils(mContext);
12191            return utils.showSessionForActiveService(args,
12192                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12193        } finally {
12194            Binder.restoreCallingIdentity(ident);
12195        }
12196    }
12197
12198    @Override
12199    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12200            Bundle receiverExtras,
12201            IBinder activityToken, boolean focused, boolean newSessionId) {
12202        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12203                activityToken, focused, newSessionId,
12204                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12205                != null;
12206    }
12207
12208    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12209            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12210            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12211        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12212                "enqueueAssistContext()");
12213        synchronized (this) {
12214            ActivityRecord activity = getFocusedStack().topActivity();
12215            if (activity == null) {
12216                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12217                return null;
12218            }
12219            if (activity.app == null || activity.app.thread == null) {
12220                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12221                return null;
12222            }
12223            if (focused) {
12224                if (activityToken != null) {
12225                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12226                    if (activity != caller) {
12227                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12228                                + " is not current top " + activity);
12229                        return null;
12230                    }
12231                }
12232            } else {
12233                activity = ActivityRecord.forTokenLocked(activityToken);
12234                if (activity == null) {
12235                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12236                            + " couldn't be found");
12237                    return null;
12238                }
12239            }
12240
12241            PendingAssistExtras pae;
12242            Bundle extras = new Bundle();
12243            if (args != null) {
12244                extras.putAll(args);
12245            }
12246            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12247            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12248            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12249                    userHandle);
12250            // Increment the sessionId if necessary
12251            if (newSessionId) {
12252                mViSessionId++;
12253            }
12254            try {
12255                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12256                        requestType, mViSessionId);
12257                mPendingAssistExtras.add(pae);
12258                mUiHandler.postDelayed(pae, timeout);
12259            } catch (RemoteException e) {
12260                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12261                return null;
12262            }
12263            return pae;
12264        }
12265    }
12266
12267    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12268        IResultReceiver receiver;
12269        synchronized (this) {
12270            mPendingAssistExtras.remove(pae);
12271            receiver = pae.receiver;
12272        }
12273        if (receiver != null) {
12274            // Caller wants result sent back to them.
12275            Bundle sendBundle = new Bundle();
12276            // At least return the receiver extras
12277            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12278                    pae.receiverExtras);
12279            try {
12280                pae.receiver.send(0, sendBundle);
12281            } catch (RemoteException e) {
12282            }
12283        }
12284    }
12285
12286    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12287        if (result != null) {
12288            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12289        }
12290        if (pae.hint != null) {
12291            pae.extras.putBoolean(pae.hint, true);
12292        }
12293    }
12294
12295    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12296            AssistContent content, Uri referrer) {
12297        PendingAssistExtras pae = (PendingAssistExtras)token;
12298        synchronized (pae) {
12299            pae.result = extras;
12300            pae.structure = structure;
12301            pae.content = content;
12302            if (referrer != null) {
12303                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12304            }
12305            pae.haveResult = true;
12306            pae.notifyAll();
12307            if (pae.intent == null && pae.receiver == null) {
12308                // Caller is just waiting for the result.
12309                return;
12310            }
12311        }
12312
12313        // We are now ready to launch the assist activity.
12314        IResultReceiver sendReceiver = null;
12315        Bundle sendBundle = null;
12316        synchronized (this) {
12317            buildAssistBundleLocked(pae, extras);
12318            boolean exists = mPendingAssistExtras.remove(pae);
12319            mUiHandler.removeCallbacks(pae);
12320            if (!exists) {
12321                // Timed out.
12322                return;
12323            }
12324            if ((sendReceiver=pae.receiver) != null) {
12325                // Caller wants result sent back to them.
12326                sendBundle = new Bundle();
12327                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12328                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12329                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12330                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12331                        pae.receiverExtras);
12332            }
12333        }
12334        if (sendReceiver != null) {
12335            try {
12336                sendReceiver.send(0, sendBundle);
12337            } catch (RemoteException e) {
12338            }
12339            return;
12340        }
12341
12342        long ident = Binder.clearCallingIdentity();
12343        try {
12344            pae.intent.replaceExtras(pae.extras);
12345            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12346                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12347                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12348            closeSystemDialogs("assist");
12349            try {
12350                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12351            } catch (ActivityNotFoundException e) {
12352                Slog.w(TAG, "No activity to handle assist action.", e);
12353            }
12354        } finally {
12355            Binder.restoreCallingIdentity(ident);
12356        }
12357    }
12358
12359    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12360            Bundle args) {
12361        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12362                true /* focused */, true /* newSessionId */,
12363                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12364    }
12365
12366    public void registerProcessObserver(IProcessObserver observer) {
12367        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12368                "registerProcessObserver()");
12369        synchronized (this) {
12370            mProcessObservers.register(observer);
12371        }
12372    }
12373
12374    @Override
12375    public void unregisterProcessObserver(IProcessObserver observer) {
12376        synchronized (this) {
12377            mProcessObservers.unregister(observer);
12378        }
12379    }
12380
12381    @Override
12382    public void registerUidObserver(IUidObserver observer, int which) {
12383        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12384                "registerUidObserver()");
12385        synchronized (this) {
12386            mUidObservers.register(observer, which);
12387        }
12388    }
12389
12390    @Override
12391    public void unregisterUidObserver(IUidObserver observer) {
12392        synchronized (this) {
12393            mUidObservers.unregister(observer);
12394        }
12395    }
12396
12397    @Override
12398    public boolean convertFromTranslucent(IBinder token) {
12399        final long origId = Binder.clearCallingIdentity();
12400        try {
12401            synchronized (this) {
12402                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12403                if (r == null) {
12404                    return false;
12405                }
12406                final boolean translucentChanged = r.changeWindowTranslucency(true);
12407                if (translucentChanged) {
12408                    r.task.stack.releaseBackgroundResources(r);
12409                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12410                }
12411                mWindowManager.setAppFullscreen(token, true);
12412                return translucentChanged;
12413            }
12414        } finally {
12415            Binder.restoreCallingIdentity(origId);
12416        }
12417    }
12418
12419    @Override
12420    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12421        final long origId = Binder.clearCallingIdentity();
12422        try {
12423            synchronized (this) {
12424                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12425                if (r == null) {
12426                    return false;
12427                }
12428                int index = r.task.mActivities.lastIndexOf(r);
12429                if (index > 0) {
12430                    ActivityRecord under = r.task.mActivities.get(index - 1);
12431                    under.returningOptions = options;
12432                }
12433                final boolean translucentChanged = r.changeWindowTranslucency(false);
12434                if (translucentChanged) {
12435                    r.task.stack.convertActivityToTranslucent(r);
12436                }
12437                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12438                mWindowManager.setAppFullscreen(token, false);
12439                return translucentChanged;
12440            }
12441        } finally {
12442            Binder.restoreCallingIdentity(origId);
12443        }
12444    }
12445
12446    @Override
12447    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12448        final long origId = Binder.clearCallingIdentity();
12449        try {
12450            synchronized (this) {
12451                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12452                if (r != null) {
12453                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12454                }
12455            }
12456            return false;
12457        } finally {
12458            Binder.restoreCallingIdentity(origId);
12459        }
12460    }
12461
12462    @Override
12463    public boolean isBackgroundVisibleBehind(IBinder token) {
12464        final long origId = Binder.clearCallingIdentity();
12465        try {
12466            synchronized (this) {
12467                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12468                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12469                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12470                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12471                return visible;
12472            }
12473        } finally {
12474            Binder.restoreCallingIdentity(origId);
12475        }
12476    }
12477
12478    @Override
12479    public ActivityOptions getActivityOptions(IBinder token) {
12480        final long origId = Binder.clearCallingIdentity();
12481        try {
12482            synchronized (this) {
12483                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12484                if (r != null) {
12485                    final ActivityOptions activityOptions = r.pendingOptions;
12486                    r.pendingOptions = null;
12487                    return activityOptions;
12488                }
12489                return null;
12490            }
12491        } finally {
12492            Binder.restoreCallingIdentity(origId);
12493        }
12494    }
12495
12496    @Override
12497    public void setImmersive(IBinder token, boolean immersive) {
12498        synchronized(this) {
12499            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12500            if (r == null) {
12501                throw new IllegalArgumentException();
12502            }
12503            r.immersive = immersive;
12504
12505            // update associated state if we're frontmost
12506            if (r == mFocusedActivity) {
12507                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12508                applyUpdateLockStateLocked(r);
12509            }
12510        }
12511    }
12512
12513    @Override
12514    public boolean isImmersive(IBinder token) {
12515        synchronized (this) {
12516            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12517            if (r == null) {
12518                throw new IllegalArgumentException();
12519            }
12520            return r.immersive;
12521        }
12522    }
12523
12524    public void setVrThread(int tid) {
12525        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12526            throw new UnsupportedOperationException("VR mode not supported on this device!");
12527        }
12528
12529        synchronized (this) {
12530            ProcessRecord proc;
12531            synchronized (mPidsSelfLocked) {
12532                final int pid = Binder.getCallingPid();
12533                proc = mPidsSelfLocked.get(pid);
12534                if (proc != null && mInVrMode && tid >= 0) {
12535                    // reset existing VR thread to CFS
12536                    if (proc.vrThreadTid != 0) {
12537                        Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12538                    }
12539                    // add check to guarantee that tid belongs to pid?
12540                    proc.vrThreadTid = tid;
12541                    // promote to FIFO now if the tid is non-zero
12542                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && proc.vrThreadTid > 0) {
12543                        Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12544                    }
12545                } else {
12546                    //Slog.e("VR_FIFO", "Didn't set thread from setVrThread?");
12547                }
12548            }
12549        }
12550    }
12551
12552    @Override
12553    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12554        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12555            throw new UnsupportedOperationException("VR mode not supported on this device!");
12556        }
12557
12558        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12559
12560        ActivityRecord r;
12561        synchronized (this) {
12562            r = ActivityRecord.isInStackLocked(token);
12563        }
12564
12565        if (r == null) {
12566            throw new IllegalArgumentException();
12567        }
12568
12569        int err;
12570        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12571                VrManagerInternal.NO_ERROR) {
12572            return err;
12573        }
12574
12575        synchronized(this) {
12576            r.requestedVrComponent = (enabled) ? packageName : null;
12577
12578            // Update associated state if this activity is currently focused
12579            if (r == mFocusedActivity) {
12580                applyUpdateVrModeLocked(r);
12581            }
12582            return 0;
12583        }
12584    }
12585
12586    @Override
12587    public boolean isVrModePackageEnabled(ComponentName packageName) {
12588        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12589            throw new UnsupportedOperationException("VR mode not supported on this device!");
12590        }
12591
12592        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12593
12594        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12595                VrManagerInternal.NO_ERROR;
12596    }
12597
12598    public boolean isTopActivityImmersive() {
12599        enforceNotIsolatedCaller("startActivity");
12600        synchronized (this) {
12601            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12602            return (r != null) ? r.immersive : false;
12603        }
12604    }
12605
12606    @Override
12607    public boolean isTopOfTask(IBinder token) {
12608        synchronized (this) {
12609            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12610            if (r == null) {
12611                throw new IllegalArgumentException();
12612            }
12613            return r.task.getTopActivity() == r;
12614        }
12615    }
12616
12617    public final void enterSafeMode() {
12618        synchronized(this) {
12619            // It only makes sense to do this before the system is ready
12620            // and started launching other packages.
12621            if (!mSystemReady) {
12622                try {
12623                    AppGlobals.getPackageManager().enterSafeMode();
12624                } catch (RemoteException e) {
12625                }
12626            }
12627
12628            mSafeMode = true;
12629        }
12630    }
12631
12632    public final void showSafeModeOverlay() {
12633        View v = LayoutInflater.from(mContext).inflate(
12634                com.android.internal.R.layout.safe_mode, null);
12635        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12636        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12637        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12638        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12639        lp.gravity = Gravity.BOTTOM | Gravity.START;
12640        lp.format = v.getBackground().getOpacity();
12641        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12642                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12643        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12644        ((WindowManager)mContext.getSystemService(
12645                Context.WINDOW_SERVICE)).addView(v, lp);
12646    }
12647
12648    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12649        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12650            return;
12651        }
12652        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12653        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12654        synchronized (stats) {
12655            if (mBatteryStatsService.isOnBattery()) {
12656                mBatteryStatsService.enforceCallingPermission();
12657                int MY_UID = Binder.getCallingUid();
12658                final int uid;
12659                if (sender == null) {
12660                    uid = sourceUid;
12661                } else {
12662                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12663                }
12664                BatteryStatsImpl.Uid.Pkg pkg =
12665                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12666                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12667                pkg.noteWakeupAlarmLocked(tag);
12668            }
12669        }
12670    }
12671
12672    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12673        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12674            return;
12675        }
12676        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12677        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12678        synchronized (stats) {
12679            mBatteryStatsService.enforceCallingPermission();
12680            int MY_UID = Binder.getCallingUid();
12681            final int uid;
12682            if (sender == null) {
12683                uid = sourceUid;
12684            } else {
12685                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12686            }
12687            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12688        }
12689    }
12690
12691    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12692        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12693            return;
12694        }
12695        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12696        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12697        synchronized (stats) {
12698            mBatteryStatsService.enforceCallingPermission();
12699            int MY_UID = Binder.getCallingUid();
12700            final int uid;
12701            if (sender == null) {
12702                uid = sourceUid;
12703            } else {
12704                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12705            }
12706            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12707        }
12708    }
12709
12710    public boolean killPids(int[] pids, String pReason, boolean secure) {
12711        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12712            throw new SecurityException("killPids only available to the system");
12713        }
12714        String reason = (pReason == null) ? "Unknown" : pReason;
12715        // XXX Note: don't acquire main activity lock here, because the window
12716        // manager calls in with its locks held.
12717
12718        boolean killed = false;
12719        synchronized (mPidsSelfLocked) {
12720            int worstType = 0;
12721            for (int i=0; i<pids.length; i++) {
12722                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12723                if (proc != null) {
12724                    int type = proc.setAdj;
12725                    if (type > worstType) {
12726                        worstType = type;
12727                    }
12728                }
12729            }
12730
12731            // If the worst oom_adj is somewhere in the cached proc LRU range,
12732            // then constrain it so we will kill all cached procs.
12733            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12734                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12735                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12736            }
12737
12738            // If this is not a secure call, don't let it kill processes that
12739            // are important.
12740            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12741                worstType = ProcessList.SERVICE_ADJ;
12742            }
12743
12744            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12745            for (int i=0; i<pids.length; i++) {
12746                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12747                if (proc == null) {
12748                    continue;
12749                }
12750                int adj = proc.setAdj;
12751                if (adj >= worstType && !proc.killedByAm) {
12752                    proc.kill(reason, true);
12753                    killed = true;
12754                }
12755            }
12756        }
12757        return killed;
12758    }
12759
12760    @Override
12761    public void killUid(int appId, int userId, String reason) {
12762        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12763        synchronized (this) {
12764            final long identity = Binder.clearCallingIdentity();
12765            try {
12766                killPackageProcessesLocked(null, appId, userId,
12767                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12768                        reason != null ? reason : "kill uid");
12769            } finally {
12770                Binder.restoreCallingIdentity(identity);
12771            }
12772        }
12773    }
12774
12775    @Override
12776    public boolean killProcessesBelowForeground(String reason) {
12777        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12778            throw new SecurityException("killProcessesBelowForeground() only available to system");
12779        }
12780
12781        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12782    }
12783
12784    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12785        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12786            throw new SecurityException("killProcessesBelowAdj() only available to system");
12787        }
12788
12789        boolean killed = false;
12790        synchronized (mPidsSelfLocked) {
12791            final int size = mPidsSelfLocked.size();
12792            for (int i = 0; i < size; i++) {
12793                final int pid = mPidsSelfLocked.keyAt(i);
12794                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12795                if (proc == null) continue;
12796
12797                final int adj = proc.setAdj;
12798                if (adj > belowAdj && !proc.killedByAm) {
12799                    proc.kill(reason, true);
12800                    killed = true;
12801                }
12802            }
12803        }
12804        return killed;
12805    }
12806
12807    @Override
12808    public void hang(final IBinder who, boolean allowRestart) {
12809        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12810                != PackageManager.PERMISSION_GRANTED) {
12811            throw new SecurityException("Requires permission "
12812                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12813        }
12814
12815        final IBinder.DeathRecipient death = new DeathRecipient() {
12816            @Override
12817            public void binderDied() {
12818                synchronized (this) {
12819                    notifyAll();
12820                }
12821            }
12822        };
12823
12824        try {
12825            who.linkToDeath(death, 0);
12826        } catch (RemoteException e) {
12827            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12828            return;
12829        }
12830
12831        synchronized (this) {
12832            Watchdog.getInstance().setAllowRestart(allowRestart);
12833            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12834            synchronized (death) {
12835                while (who.isBinderAlive()) {
12836                    try {
12837                        death.wait();
12838                    } catch (InterruptedException e) {
12839                    }
12840                }
12841            }
12842            Watchdog.getInstance().setAllowRestart(true);
12843        }
12844    }
12845
12846    @Override
12847    public void restart() {
12848        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12849                != PackageManager.PERMISSION_GRANTED) {
12850            throw new SecurityException("Requires permission "
12851                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12852        }
12853
12854        Log.i(TAG, "Sending shutdown broadcast...");
12855
12856        BroadcastReceiver br = new BroadcastReceiver() {
12857            @Override public void onReceive(Context context, Intent intent) {
12858                // Now the broadcast is done, finish up the low-level shutdown.
12859                Log.i(TAG, "Shutting down activity manager...");
12860                shutdown(10000);
12861                Log.i(TAG, "Shutdown complete, restarting!");
12862                Process.killProcess(Process.myPid());
12863                System.exit(10);
12864            }
12865        };
12866
12867        // First send the high-level shut down broadcast.
12868        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12869        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12870        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12871        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12872        mContext.sendOrderedBroadcastAsUser(intent,
12873                UserHandle.ALL, null, br, mHandler, 0, null, null);
12874        */
12875        br.onReceive(mContext, intent);
12876    }
12877
12878    private long getLowRamTimeSinceIdle(long now) {
12879        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12880    }
12881
12882    @Override
12883    public void performIdleMaintenance() {
12884        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12885                != PackageManager.PERMISSION_GRANTED) {
12886            throw new SecurityException("Requires permission "
12887                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12888        }
12889
12890        synchronized (this) {
12891            final long now = SystemClock.uptimeMillis();
12892            final long timeSinceLastIdle = now - mLastIdleTime;
12893            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12894            mLastIdleTime = now;
12895            mLowRamTimeSinceLastIdle = 0;
12896            if (mLowRamStartTime != 0) {
12897                mLowRamStartTime = now;
12898            }
12899
12900            StringBuilder sb = new StringBuilder(128);
12901            sb.append("Idle maintenance over ");
12902            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12903            sb.append(" low RAM for ");
12904            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12905            Slog.i(TAG, sb.toString());
12906
12907            // If at least 1/3 of our time since the last idle period has been spent
12908            // with RAM low, then we want to kill processes.
12909            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12910
12911            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12912                ProcessRecord proc = mLruProcesses.get(i);
12913                if (proc.notCachedSinceIdle) {
12914                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12915                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12916                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12917                        if (doKilling && proc.initialIdlePss != 0
12918                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12919                            sb = new StringBuilder(128);
12920                            sb.append("Kill");
12921                            sb.append(proc.processName);
12922                            sb.append(" in idle maint: pss=");
12923                            sb.append(proc.lastPss);
12924                            sb.append(", swapPss=");
12925                            sb.append(proc.lastSwapPss);
12926                            sb.append(", initialPss=");
12927                            sb.append(proc.initialIdlePss);
12928                            sb.append(", period=");
12929                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12930                            sb.append(", lowRamPeriod=");
12931                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12932                            Slog.wtfQuiet(TAG, sb.toString());
12933                            proc.kill("idle maint (pss " + proc.lastPss
12934                                    + " from " + proc.initialIdlePss + ")", true);
12935                        }
12936                    }
12937                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12938                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12939                    proc.notCachedSinceIdle = true;
12940                    proc.initialIdlePss = 0;
12941                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12942                            mTestPssMode, isSleepingLocked(), now);
12943                }
12944            }
12945
12946            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12947            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12948        }
12949    }
12950
12951    @Override
12952    public void sendIdleJobTrigger() {
12953        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12954                != PackageManager.PERMISSION_GRANTED) {
12955            throw new SecurityException("Requires permission "
12956                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12957        }
12958
12959        final long ident = Binder.clearCallingIdentity();
12960        try {
12961            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12962                    .setPackage("android")
12963                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12964            broadcastIntent(null, intent, null, null, 0, null, null, null,
12965                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12966        } finally {
12967            Binder.restoreCallingIdentity(ident);
12968        }
12969    }
12970
12971    private void retrieveSettings() {
12972        final ContentResolver resolver = mContext.getContentResolver();
12973        final boolean freeformWindowManagement =
12974                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12975                        || Settings.Global.getInt(
12976                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12977        final boolean supportsPictureInPicture =
12978                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12979
12980        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12981        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12982        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12983        final boolean alwaysFinishActivities =
12984                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12985        final boolean lenientBackgroundCheck =
12986                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12987        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12988        final boolean forceResizable = Settings.Global.getInt(
12989                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12990        final boolean supportsLeanbackOnly =
12991                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12992
12993        // Transfer any global setting for forcing RTL layout, into a System Property
12994        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12995
12996        final Configuration configuration = new Configuration();
12997        Settings.System.getConfiguration(resolver, configuration);
12998        if (forceRtl) {
12999            // This will take care of setting the correct layout direction flags
13000            configuration.setLayoutDirection(configuration.locale);
13001        }
13002
13003        synchronized (this) {
13004            mDebugApp = mOrigDebugApp = debugApp;
13005            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13006            mAlwaysFinishActivities = alwaysFinishActivities;
13007            mLenientBackgroundCheck = lenientBackgroundCheck;
13008            mSupportsLeanbackOnly = supportsLeanbackOnly;
13009            mForceResizableActivities = forceResizable;
13010            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13011            if (supportsMultiWindow || forceResizable) {
13012                mSupportsMultiWindow = true;
13013                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13014                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13015            } else {
13016                mSupportsMultiWindow = false;
13017                mSupportsFreeformWindowManagement = false;
13018                mSupportsPictureInPicture = false;
13019            }
13020            // This happens before any activities are started, so we can
13021            // change mConfiguration in-place.
13022            updateConfigurationLocked(configuration, null, true);
13023            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13024                    "Initial config: " + mConfiguration);
13025
13026            // Load resources only after the current configuration has been set.
13027            final Resources res = mContext.getResources();
13028            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13029            mThumbnailWidth = res.getDimensionPixelSize(
13030                    com.android.internal.R.dimen.thumbnail_width);
13031            mThumbnailHeight = res.getDimensionPixelSize(
13032                    com.android.internal.R.dimen.thumbnail_height);
13033            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13034                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13035            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13036                    com.android.internal.R.string.config_appsNotReportingCrashes));
13037            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13038                mFullscreenThumbnailScale = (float) res
13039                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13040                    (float) mConfiguration.screenWidthDp;
13041            } else {
13042                mFullscreenThumbnailScale = res.getFraction(
13043                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13044            }
13045        }
13046    }
13047
13048    public boolean testIsSystemReady() {
13049        // no need to synchronize(this) just to read & return the value
13050        return mSystemReady;
13051    }
13052
13053    public void systemReady(final Runnable goingCallback) {
13054        synchronized(this) {
13055            if (mSystemReady) {
13056                // If we're done calling all the receivers, run the next "boot phase" passed in
13057                // by the SystemServer
13058                if (goingCallback != null) {
13059                    goingCallback.run();
13060                }
13061                return;
13062            }
13063
13064            mLocalDeviceIdleController
13065                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13066
13067            // Make sure we have the current profile info, since it is needed for security checks.
13068            mUserController.onSystemReady();
13069            mRecentTasks.onSystemReadyLocked();
13070            mAppOpsService.systemReady();
13071            mSystemReady = true;
13072        }
13073
13074        ArrayList<ProcessRecord> procsToKill = null;
13075        synchronized(mPidsSelfLocked) {
13076            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13077                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13078                if (!isAllowedWhileBooting(proc.info)){
13079                    if (procsToKill == null) {
13080                        procsToKill = new ArrayList<ProcessRecord>();
13081                    }
13082                    procsToKill.add(proc);
13083                }
13084            }
13085        }
13086
13087        synchronized(this) {
13088            if (procsToKill != null) {
13089                for (int i=procsToKill.size()-1; i>=0; i--) {
13090                    ProcessRecord proc = procsToKill.get(i);
13091                    Slog.i(TAG, "Removing system update proc: " + proc);
13092                    removeProcessLocked(proc, true, false, "system update done");
13093                }
13094            }
13095
13096            // Now that we have cleaned up any update processes, we
13097            // are ready to start launching real processes and know that
13098            // we won't trample on them any more.
13099            mProcessesReady = true;
13100        }
13101
13102        Slog.i(TAG, "System now ready");
13103        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13104            SystemClock.uptimeMillis());
13105
13106        synchronized(this) {
13107            // Make sure we have no pre-ready processes sitting around.
13108
13109            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13110                ResolveInfo ri = mContext.getPackageManager()
13111                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13112                                STOCK_PM_FLAGS);
13113                CharSequence errorMsg = null;
13114                if (ri != null) {
13115                    ActivityInfo ai = ri.activityInfo;
13116                    ApplicationInfo app = ai.applicationInfo;
13117                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13118                        mTopAction = Intent.ACTION_FACTORY_TEST;
13119                        mTopData = null;
13120                        mTopComponent = new ComponentName(app.packageName,
13121                                ai.name);
13122                    } else {
13123                        errorMsg = mContext.getResources().getText(
13124                                com.android.internal.R.string.factorytest_not_system);
13125                    }
13126                } else {
13127                    errorMsg = mContext.getResources().getText(
13128                            com.android.internal.R.string.factorytest_no_action);
13129                }
13130                if (errorMsg != null) {
13131                    mTopAction = null;
13132                    mTopData = null;
13133                    mTopComponent = null;
13134                    Message msg = Message.obtain();
13135                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13136                    msg.getData().putCharSequence("msg", errorMsg);
13137                    mUiHandler.sendMessage(msg);
13138                }
13139            }
13140        }
13141
13142        retrieveSettings();
13143        final int currentUserId;
13144        synchronized (this) {
13145            currentUserId = mUserController.getCurrentUserIdLocked();
13146            readGrantedUriPermissionsLocked();
13147        }
13148
13149        if (goingCallback != null) goingCallback.run();
13150
13151        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13152                Integer.toString(currentUserId), currentUserId);
13153        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13154                Integer.toString(currentUserId), currentUserId);
13155        mSystemServiceManager.startUser(currentUserId);
13156
13157        synchronized (this) {
13158            // Only start up encryption-aware persistent apps; once user is
13159            // unlocked we'll come back around and start unaware apps
13160            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13161
13162            // Start up initial activity.
13163            mBooting = true;
13164            // Enable home activity for system user, so that the system can always boot
13165            if (UserManager.isSplitSystemUser()) {
13166                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13167                try {
13168                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13169                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13170                            UserHandle.USER_SYSTEM);
13171                } catch (RemoteException e) {
13172                    throw e.rethrowAsRuntimeException();
13173                }
13174            }
13175            startHomeActivityLocked(currentUserId, "systemReady");
13176
13177            try {
13178                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13179                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13180                            + " data partition or your device will be unstable.");
13181                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13182                }
13183            } catch (RemoteException e) {
13184            }
13185
13186            if (!Build.isBuildConsistent()) {
13187                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13188                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13189            }
13190
13191            long ident = Binder.clearCallingIdentity();
13192            try {
13193                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13194                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13195                        | Intent.FLAG_RECEIVER_FOREGROUND);
13196                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13197                broadcastIntentLocked(null, null, intent,
13198                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13199                        null, false, false, MY_PID, Process.SYSTEM_UID,
13200                        currentUserId);
13201                intent = new Intent(Intent.ACTION_USER_STARTING);
13202                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13203                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13204                broadcastIntentLocked(null, null, intent,
13205                        null, new IIntentReceiver.Stub() {
13206                            @Override
13207                            public void performReceive(Intent intent, int resultCode, String data,
13208                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13209                                    throws RemoteException {
13210                            }
13211                        }, 0, null, null,
13212                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13213                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13214            } catch (Throwable t) {
13215                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13216            } finally {
13217                Binder.restoreCallingIdentity(ident);
13218            }
13219            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13220            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13221        }
13222    }
13223
13224    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13225        synchronized (this) {
13226            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13227        }
13228    }
13229
13230    void skipCurrentReceiverLocked(ProcessRecord app) {
13231        for (BroadcastQueue queue : mBroadcastQueues) {
13232            queue.skipCurrentReceiverLocked(app);
13233        }
13234    }
13235
13236    /**
13237     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13238     * The application process will exit immediately after this call returns.
13239     * @param app object of the crashing app, null for the system server
13240     * @param crashInfo describing the exception
13241     */
13242    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13243        ProcessRecord r = findAppProcess(app, "Crash");
13244        final String processName = app == null ? "system_server"
13245                : (r == null ? "unknown" : r.processName);
13246
13247        handleApplicationCrashInner("crash", r, processName, crashInfo);
13248    }
13249
13250    /* Native crash reporting uses this inner version because it needs to be somewhat
13251     * decoupled from the AM-managed cleanup lifecycle
13252     */
13253    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13254            ApplicationErrorReport.CrashInfo crashInfo) {
13255        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13256                UserHandle.getUserId(Binder.getCallingUid()), processName,
13257                r == null ? -1 : r.info.flags,
13258                crashInfo.exceptionClassName,
13259                crashInfo.exceptionMessage,
13260                crashInfo.throwFileName,
13261                crashInfo.throwLineNumber);
13262
13263        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13264
13265        mAppErrors.crashApplication(r, crashInfo);
13266    }
13267
13268    public void handleApplicationStrictModeViolation(
13269            IBinder app,
13270            int violationMask,
13271            StrictMode.ViolationInfo info) {
13272        ProcessRecord r = findAppProcess(app, "StrictMode");
13273        if (r == null) {
13274            return;
13275        }
13276
13277        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13278            Integer stackFingerprint = info.hashCode();
13279            boolean logIt = true;
13280            synchronized (mAlreadyLoggedViolatedStacks) {
13281                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13282                    logIt = false;
13283                    // TODO: sub-sample into EventLog for these, with
13284                    // the info.durationMillis?  Then we'd get
13285                    // the relative pain numbers, without logging all
13286                    // the stack traces repeatedly.  We'd want to do
13287                    // likewise in the client code, which also does
13288                    // dup suppression, before the Binder call.
13289                } else {
13290                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13291                        mAlreadyLoggedViolatedStacks.clear();
13292                    }
13293                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13294                }
13295            }
13296            if (logIt) {
13297                logStrictModeViolationToDropBox(r, info);
13298            }
13299        }
13300
13301        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13302            AppErrorResult result = new AppErrorResult();
13303            synchronized (this) {
13304                final long origId = Binder.clearCallingIdentity();
13305
13306                Message msg = Message.obtain();
13307                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13308                HashMap<String, Object> data = new HashMap<String, Object>();
13309                data.put("result", result);
13310                data.put("app", r);
13311                data.put("violationMask", violationMask);
13312                data.put("info", info);
13313                msg.obj = data;
13314                mUiHandler.sendMessage(msg);
13315
13316                Binder.restoreCallingIdentity(origId);
13317            }
13318            int res = result.get();
13319            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13320        }
13321    }
13322
13323    // Depending on the policy in effect, there could be a bunch of
13324    // these in quick succession so we try to batch these together to
13325    // minimize disk writes, number of dropbox entries, and maximize
13326    // compression, by having more fewer, larger records.
13327    private void logStrictModeViolationToDropBox(
13328            ProcessRecord process,
13329            StrictMode.ViolationInfo info) {
13330        if (info == null) {
13331            return;
13332        }
13333        final boolean isSystemApp = process == null ||
13334                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13335                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13336        final String processName = process == null ? "unknown" : process.processName;
13337        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13338        final DropBoxManager dbox = (DropBoxManager)
13339                mContext.getSystemService(Context.DROPBOX_SERVICE);
13340
13341        // Exit early if the dropbox isn't configured to accept this report type.
13342        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13343
13344        boolean bufferWasEmpty;
13345        boolean needsFlush;
13346        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13347        synchronized (sb) {
13348            bufferWasEmpty = sb.length() == 0;
13349            appendDropBoxProcessHeaders(process, processName, sb);
13350            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13351            sb.append("System-App: ").append(isSystemApp).append("\n");
13352            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13353            if (info.violationNumThisLoop != 0) {
13354                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13355            }
13356            if (info.numAnimationsRunning != 0) {
13357                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13358            }
13359            if (info.broadcastIntentAction != null) {
13360                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13361            }
13362            if (info.durationMillis != -1) {
13363                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13364            }
13365            if (info.numInstances != -1) {
13366                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13367            }
13368            if (info.tags != null) {
13369                for (String tag : info.tags) {
13370                    sb.append("Span-Tag: ").append(tag).append("\n");
13371                }
13372            }
13373            sb.append("\n");
13374            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13375                sb.append(info.crashInfo.stackTrace);
13376                sb.append("\n");
13377            }
13378            if (info.message != null) {
13379                sb.append(info.message);
13380                sb.append("\n");
13381            }
13382
13383            // Only buffer up to ~64k.  Various logging bits truncate
13384            // things at 128k.
13385            needsFlush = (sb.length() > 64 * 1024);
13386        }
13387
13388        // Flush immediately if the buffer's grown too large, or this
13389        // is a non-system app.  Non-system apps are isolated with a
13390        // different tag & policy and not batched.
13391        //
13392        // Batching is useful during internal testing with
13393        // StrictMode settings turned up high.  Without batching,
13394        // thousands of separate files could be created on boot.
13395        if (!isSystemApp || needsFlush) {
13396            new Thread("Error dump: " + dropboxTag) {
13397                @Override
13398                public void run() {
13399                    String report;
13400                    synchronized (sb) {
13401                        report = sb.toString();
13402                        sb.delete(0, sb.length());
13403                        sb.trimToSize();
13404                    }
13405                    if (report.length() != 0) {
13406                        dbox.addText(dropboxTag, report);
13407                    }
13408                }
13409            }.start();
13410            return;
13411        }
13412
13413        // System app batching:
13414        if (!bufferWasEmpty) {
13415            // An existing dropbox-writing thread is outstanding, so
13416            // we don't need to start it up.  The existing thread will
13417            // catch the buffer appends we just did.
13418            return;
13419        }
13420
13421        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13422        // (After this point, we shouldn't access AMS internal data structures.)
13423        new Thread("Error dump: " + dropboxTag) {
13424            @Override
13425            public void run() {
13426                // 5 second sleep to let stacks arrive and be batched together
13427                try {
13428                    Thread.sleep(5000);  // 5 seconds
13429                } catch (InterruptedException e) {}
13430
13431                String errorReport;
13432                synchronized (mStrictModeBuffer) {
13433                    errorReport = mStrictModeBuffer.toString();
13434                    if (errorReport.length() == 0) {
13435                        return;
13436                    }
13437                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13438                    mStrictModeBuffer.trimToSize();
13439                }
13440                dbox.addText(dropboxTag, errorReport);
13441            }
13442        }.start();
13443    }
13444
13445    /**
13446     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13447     * @param app object of the crashing app, null for the system server
13448     * @param tag reported by the caller
13449     * @param system whether this wtf is coming from the system
13450     * @param crashInfo describing the context of the error
13451     * @return true if the process should exit immediately (WTF is fatal)
13452     */
13453    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13454            final ApplicationErrorReport.CrashInfo crashInfo) {
13455        final int callingUid = Binder.getCallingUid();
13456        final int callingPid = Binder.getCallingPid();
13457
13458        if (system) {
13459            // If this is coming from the system, we could very well have low-level
13460            // system locks held, so we want to do this all asynchronously.  And we
13461            // never want this to become fatal, so there is that too.
13462            mHandler.post(new Runnable() {
13463                @Override public void run() {
13464                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13465                }
13466            });
13467            return false;
13468        }
13469
13470        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13471                crashInfo);
13472
13473        if (r != null && r.pid != Process.myPid() &&
13474                Settings.Global.getInt(mContext.getContentResolver(),
13475                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13476            mAppErrors.crashApplication(r, crashInfo);
13477            return true;
13478        } else {
13479            return false;
13480        }
13481    }
13482
13483    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13484            final ApplicationErrorReport.CrashInfo crashInfo) {
13485        final ProcessRecord r = findAppProcess(app, "WTF");
13486        final String processName = app == null ? "system_server"
13487                : (r == null ? "unknown" : r.processName);
13488
13489        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13490                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13491
13492        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13493
13494        return r;
13495    }
13496
13497    /**
13498     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13499     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13500     */
13501    private ProcessRecord findAppProcess(IBinder app, String reason) {
13502        if (app == null) {
13503            return null;
13504        }
13505
13506        synchronized (this) {
13507            final int NP = mProcessNames.getMap().size();
13508            for (int ip=0; ip<NP; ip++) {
13509                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13510                final int NA = apps.size();
13511                for (int ia=0; ia<NA; ia++) {
13512                    ProcessRecord p = apps.valueAt(ia);
13513                    if (p.thread != null && p.thread.asBinder() == app) {
13514                        return p;
13515                    }
13516                }
13517            }
13518
13519            Slog.w(TAG, "Can't find mystery application for " + reason
13520                    + " from pid=" + Binder.getCallingPid()
13521                    + " uid=" + Binder.getCallingUid() + ": " + app);
13522            return null;
13523        }
13524    }
13525
13526    /**
13527     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13528     * to append various headers to the dropbox log text.
13529     */
13530    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13531            StringBuilder sb) {
13532        // Watchdog thread ends up invoking this function (with
13533        // a null ProcessRecord) to add the stack file to dropbox.
13534        // Do not acquire a lock on this (am) in such cases, as it
13535        // could cause a potential deadlock, if and when watchdog
13536        // is invoked due to unavailability of lock on am and it
13537        // would prevent watchdog from killing system_server.
13538        if (process == null) {
13539            sb.append("Process: ").append(processName).append("\n");
13540            return;
13541        }
13542        // Note: ProcessRecord 'process' is guarded by the service
13543        // instance.  (notably process.pkgList, which could otherwise change
13544        // concurrently during execution of this method)
13545        synchronized (this) {
13546            sb.append("Process: ").append(processName).append("\n");
13547            int flags = process.info.flags;
13548            IPackageManager pm = AppGlobals.getPackageManager();
13549            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13550            for (int ip=0; ip<process.pkgList.size(); ip++) {
13551                String pkg = process.pkgList.keyAt(ip);
13552                sb.append("Package: ").append(pkg);
13553                try {
13554                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13555                    if (pi != null) {
13556                        sb.append(" v").append(pi.versionCode);
13557                        if (pi.versionName != null) {
13558                            sb.append(" (").append(pi.versionName).append(")");
13559                        }
13560                    }
13561                } catch (RemoteException e) {
13562                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13563                }
13564                sb.append("\n");
13565            }
13566        }
13567    }
13568
13569    private static String processClass(ProcessRecord process) {
13570        if (process == null || process.pid == MY_PID) {
13571            return "system_server";
13572        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13573            return "system_app";
13574        } else {
13575            return "data_app";
13576        }
13577    }
13578
13579    private volatile long mWtfClusterStart;
13580    private volatile int mWtfClusterCount;
13581
13582    /**
13583     * Write a description of an error (crash, WTF, ANR) to the drop box.
13584     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13585     * @param process which caused the error, null means the system server
13586     * @param activity which triggered the error, null if unknown
13587     * @param parent activity related to the error, null if unknown
13588     * @param subject line related to the error, null if absent
13589     * @param report in long form describing the error, null if absent
13590     * @param dataFile text file to include in the report, null if none
13591     * @param crashInfo giving an application stack trace, null if absent
13592     */
13593    public void addErrorToDropBox(String eventType,
13594            ProcessRecord process, String processName, ActivityRecord activity,
13595            ActivityRecord parent, String subject,
13596            final String report, final File dataFile,
13597            final ApplicationErrorReport.CrashInfo crashInfo) {
13598        // NOTE -- this must never acquire the ActivityManagerService lock,
13599        // otherwise the watchdog may be prevented from resetting the system.
13600
13601        final String dropboxTag = processClass(process) + "_" + eventType;
13602        final DropBoxManager dbox = (DropBoxManager)
13603                mContext.getSystemService(Context.DROPBOX_SERVICE);
13604
13605        // Exit early if the dropbox isn't configured to accept this report type.
13606        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13607
13608        // Rate-limit how often we're willing to do the heavy lifting below to
13609        // collect and record logs; currently 5 logs per 10 second period.
13610        final long now = SystemClock.elapsedRealtime();
13611        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13612            mWtfClusterStart = now;
13613            mWtfClusterCount = 1;
13614        } else {
13615            if (mWtfClusterCount++ >= 5) return;
13616        }
13617
13618        final StringBuilder sb = new StringBuilder(1024);
13619        appendDropBoxProcessHeaders(process, processName, sb);
13620        if (process != null) {
13621            sb.append("Foreground: ")
13622                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13623                    .append("\n");
13624        }
13625        if (activity != null) {
13626            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13627        }
13628        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13629            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13630        }
13631        if (parent != null && parent != activity) {
13632            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13633        }
13634        if (subject != null) {
13635            sb.append("Subject: ").append(subject).append("\n");
13636        }
13637        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13638        if (Debug.isDebuggerConnected()) {
13639            sb.append("Debugger: Connected\n");
13640        }
13641        sb.append("\n");
13642
13643        // Do the rest in a worker thread to avoid blocking the caller on I/O
13644        // (After this point, we shouldn't access AMS internal data structures.)
13645        Thread worker = new Thread("Error dump: " + dropboxTag) {
13646            @Override
13647            public void run() {
13648                if (report != null) {
13649                    sb.append(report);
13650                }
13651
13652                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13653                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13654                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13655                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13656
13657                if (dataFile != null && maxDataFileSize > 0) {
13658                    try {
13659                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13660                                    "\n\n[[TRUNCATED]]"));
13661                    } catch (IOException e) {
13662                        Slog.e(TAG, "Error reading " + dataFile, e);
13663                    }
13664                }
13665                if (crashInfo != null && crashInfo.stackTrace != null) {
13666                    sb.append(crashInfo.stackTrace);
13667                }
13668
13669                if (lines > 0) {
13670                    sb.append("\n");
13671
13672                    // Merge several logcat streams, and take the last N lines
13673                    InputStreamReader input = null;
13674                    try {
13675                        java.lang.Process logcat = new ProcessBuilder(
13676                                "/system/bin/timeout", "-k", "15s", "10s",
13677                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13678                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13679                                        .redirectErrorStream(true).start();
13680
13681                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13682                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13683                        input = new InputStreamReader(logcat.getInputStream());
13684
13685                        int num;
13686                        char[] buf = new char[8192];
13687                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13688                    } catch (IOException e) {
13689                        Slog.e(TAG, "Error running logcat", e);
13690                    } finally {
13691                        if (input != null) try { input.close(); } catch (IOException e) {}
13692                    }
13693                }
13694
13695                dbox.addText(dropboxTag, sb.toString());
13696            }
13697        };
13698
13699        if (process == null) {
13700            // If process is null, we are being called from some internal code
13701            // and may be about to die -- run this synchronously.
13702            worker.run();
13703        } else {
13704            worker.start();
13705        }
13706    }
13707
13708    @Override
13709    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13710        enforceNotIsolatedCaller("getProcessesInErrorState");
13711        // assume our apps are happy - lazy create the list
13712        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13713
13714        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13715                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13716        int userId = UserHandle.getUserId(Binder.getCallingUid());
13717
13718        synchronized (this) {
13719
13720            // iterate across all processes
13721            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13722                ProcessRecord app = mLruProcesses.get(i);
13723                if (!allUsers && app.userId != userId) {
13724                    continue;
13725                }
13726                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13727                    // This one's in trouble, so we'll generate a report for it
13728                    // crashes are higher priority (in case there's a crash *and* an anr)
13729                    ActivityManager.ProcessErrorStateInfo report = null;
13730                    if (app.crashing) {
13731                        report = app.crashingReport;
13732                    } else if (app.notResponding) {
13733                        report = app.notRespondingReport;
13734                    }
13735
13736                    if (report != null) {
13737                        if (errList == null) {
13738                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13739                        }
13740                        errList.add(report);
13741                    } else {
13742                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13743                                " crashing = " + app.crashing +
13744                                " notResponding = " + app.notResponding);
13745                    }
13746                }
13747            }
13748        }
13749
13750        return errList;
13751    }
13752
13753    static int procStateToImportance(int procState, int memAdj,
13754            ActivityManager.RunningAppProcessInfo currApp) {
13755        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13756        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13757            currApp.lru = memAdj;
13758        } else {
13759            currApp.lru = 0;
13760        }
13761        return imp;
13762    }
13763
13764    private void fillInProcMemInfo(ProcessRecord app,
13765            ActivityManager.RunningAppProcessInfo outInfo) {
13766        outInfo.pid = app.pid;
13767        outInfo.uid = app.info.uid;
13768        if (mHeavyWeightProcess == app) {
13769            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13770        }
13771        if (app.persistent) {
13772            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13773        }
13774        if (app.activities.size() > 0) {
13775            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13776        }
13777        outInfo.lastTrimLevel = app.trimMemoryLevel;
13778        int adj = app.curAdj;
13779        int procState = app.curProcState;
13780        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13781        outInfo.importanceReasonCode = app.adjTypeCode;
13782        outInfo.processState = app.curProcState;
13783    }
13784
13785    @Override
13786    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13787        enforceNotIsolatedCaller("getRunningAppProcesses");
13788
13789        final int callingUid = Binder.getCallingUid();
13790
13791        // Lazy instantiation of list
13792        List<ActivityManager.RunningAppProcessInfo> runList = null;
13793        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13794                callingUid) == PackageManager.PERMISSION_GRANTED;
13795        final int userId = UserHandle.getUserId(callingUid);
13796        final boolean allUids = isGetTasksAllowed(
13797                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13798
13799        synchronized (this) {
13800            // Iterate across all processes
13801            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13802                ProcessRecord app = mLruProcesses.get(i);
13803                if ((!allUsers && app.userId != userId)
13804                        || (!allUids && app.uid != callingUid)) {
13805                    continue;
13806                }
13807                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13808                    // Generate process state info for running application
13809                    ActivityManager.RunningAppProcessInfo currApp =
13810                        new ActivityManager.RunningAppProcessInfo(app.processName,
13811                                app.pid, app.getPackageList());
13812                    fillInProcMemInfo(app, currApp);
13813                    if (app.adjSource instanceof ProcessRecord) {
13814                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13815                        currApp.importanceReasonImportance =
13816                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13817                                        app.adjSourceProcState);
13818                    } else if (app.adjSource instanceof ActivityRecord) {
13819                        ActivityRecord r = (ActivityRecord)app.adjSource;
13820                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13821                    }
13822                    if (app.adjTarget instanceof ComponentName) {
13823                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13824                    }
13825                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13826                    //        + " lru=" + currApp.lru);
13827                    if (runList == null) {
13828                        runList = new ArrayList<>();
13829                    }
13830                    runList.add(currApp);
13831                }
13832            }
13833        }
13834        return runList;
13835    }
13836
13837    @Override
13838    public List<ApplicationInfo> getRunningExternalApplications() {
13839        enforceNotIsolatedCaller("getRunningExternalApplications");
13840        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13841        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13842        if (runningApps != null && runningApps.size() > 0) {
13843            Set<String> extList = new HashSet<String>();
13844            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13845                if (app.pkgList != null) {
13846                    for (String pkg : app.pkgList) {
13847                        extList.add(pkg);
13848                    }
13849                }
13850            }
13851            IPackageManager pm = AppGlobals.getPackageManager();
13852            for (String pkg : extList) {
13853                try {
13854                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13855                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13856                        retList.add(info);
13857                    }
13858                } catch (RemoteException e) {
13859                }
13860            }
13861        }
13862        return retList;
13863    }
13864
13865    @Override
13866    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13867        enforceNotIsolatedCaller("getMyMemoryState");
13868        synchronized (this) {
13869            ProcessRecord proc;
13870            synchronized (mPidsSelfLocked) {
13871                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13872            }
13873            fillInProcMemInfo(proc, outInfo);
13874        }
13875    }
13876
13877    @Override
13878    public int getMemoryTrimLevel() {
13879        enforceNotIsolatedCaller("getMyMemoryState");
13880        synchronized (this) {
13881            return mLastMemoryLevel;
13882        }
13883    }
13884
13885    @Override
13886    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13887            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13888        (new ActivityManagerShellCommand(this, false)).exec(
13889                this, in, out, err, args, resultReceiver);
13890    }
13891
13892    @Override
13893    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13894        if (checkCallingPermission(android.Manifest.permission.DUMP)
13895                != PackageManager.PERMISSION_GRANTED) {
13896            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13897                    + Binder.getCallingPid()
13898                    + ", uid=" + Binder.getCallingUid()
13899                    + " without permission "
13900                    + android.Manifest.permission.DUMP);
13901            return;
13902        }
13903
13904        boolean dumpAll = false;
13905        boolean dumpClient = false;
13906        boolean dumpCheckin = false;
13907        boolean dumpCheckinFormat = false;
13908        String dumpPackage = null;
13909
13910        int opti = 0;
13911        while (opti < args.length) {
13912            String opt = args[opti];
13913            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13914                break;
13915            }
13916            opti++;
13917            if ("-a".equals(opt)) {
13918                dumpAll = true;
13919            } else if ("-c".equals(opt)) {
13920                dumpClient = true;
13921            } else if ("-p".equals(opt)) {
13922                if (opti < args.length) {
13923                    dumpPackage = args[opti];
13924                    opti++;
13925                } else {
13926                    pw.println("Error: -p option requires package argument");
13927                    return;
13928                }
13929                dumpClient = true;
13930            } else if ("--checkin".equals(opt)) {
13931                dumpCheckin = dumpCheckinFormat = true;
13932            } else if ("-C".equals(opt)) {
13933                dumpCheckinFormat = true;
13934            } else if ("-h".equals(opt)) {
13935                ActivityManagerShellCommand.dumpHelp(pw, true);
13936                return;
13937            } else {
13938                pw.println("Unknown argument: " + opt + "; use -h for help");
13939            }
13940        }
13941
13942        long origId = Binder.clearCallingIdentity();
13943        boolean more = false;
13944        // Is the caller requesting to dump a particular piece of data?
13945        if (opti < args.length) {
13946            String cmd = args[opti];
13947            opti++;
13948            if ("activities".equals(cmd) || "a".equals(cmd)) {
13949                synchronized (this) {
13950                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13951                }
13952            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13953                synchronized (this) {
13954                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13955                }
13956            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13957                String[] newArgs;
13958                String name;
13959                if (opti >= args.length) {
13960                    name = null;
13961                    newArgs = EMPTY_STRING_ARRAY;
13962                } else {
13963                    dumpPackage = args[opti];
13964                    opti++;
13965                    newArgs = new String[args.length - opti];
13966                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13967                            args.length - opti);
13968                }
13969                synchronized (this) {
13970                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13971                }
13972            } else if ("broadcast-stats".equals(cmd)) {
13973                String[] newArgs;
13974                String name;
13975                if (opti >= args.length) {
13976                    name = null;
13977                    newArgs = EMPTY_STRING_ARRAY;
13978                } else {
13979                    dumpPackage = args[opti];
13980                    opti++;
13981                    newArgs = new String[args.length - opti];
13982                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13983                            args.length - opti);
13984                }
13985                synchronized (this) {
13986                    if (dumpCheckinFormat) {
13987                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13988                                dumpPackage);
13989                    } else {
13990                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13991                    }
13992                }
13993            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13994                String[] newArgs;
13995                String name;
13996                if (opti >= args.length) {
13997                    name = null;
13998                    newArgs = EMPTY_STRING_ARRAY;
13999                } else {
14000                    dumpPackage = args[opti];
14001                    opti++;
14002                    newArgs = new String[args.length - opti];
14003                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14004                            args.length - opti);
14005                }
14006                synchronized (this) {
14007                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14008                }
14009            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14010                String[] newArgs;
14011                String name;
14012                if (opti >= args.length) {
14013                    name = null;
14014                    newArgs = EMPTY_STRING_ARRAY;
14015                } else {
14016                    dumpPackage = args[opti];
14017                    opti++;
14018                    newArgs = new String[args.length - opti];
14019                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14020                            args.length - opti);
14021                }
14022                synchronized (this) {
14023                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14024                }
14025            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14026                synchronized (this) {
14027                    dumpOomLocked(fd, pw, args, opti, true);
14028                }
14029            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14030                synchronized (this) {
14031                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14032                }
14033            } else if ("provider".equals(cmd)) {
14034                String[] newArgs;
14035                String name;
14036                if (opti >= args.length) {
14037                    name = null;
14038                    newArgs = EMPTY_STRING_ARRAY;
14039                } else {
14040                    name = args[opti];
14041                    opti++;
14042                    newArgs = new String[args.length - opti];
14043                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14044                }
14045                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14046                    pw.println("No providers match: " + name);
14047                    pw.println("Use -h for help.");
14048                }
14049            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14050                synchronized (this) {
14051                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14052                }
14053            } else if ("service".equals(cmd)) {
14054                String[] newArgs;
14055                String name;
14056                if (opti >= args.length) {
14057                    name = null;
14058                    newArgs = EMPTY_STRING_ARRAY;
14059                } else {
14060                    name = args[opti];
14061                    opti++;
14062                    newArgs = new String[args.length - opti];
14063                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14064                            args.length - opti);
14065                }
14066                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14067                    pw.println("No services match: " + name);
14068                    pw.println("Use -h for help.");
14069                }
14070            } else if ("package".equals(cmd)) {
14071                String[] newArgs;
14072                if (opti >= args.length) {
14073                    pw.println("package: no package name specified");
14074                    pw.println("Use -h for help.");
14075                } else {
14076                    dumpPackage = args[opti];
14077                    opti++;
14078                    newArgs = new String[args.length - opti];
14079                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14080                            args.length - opti);
14081                    args = newArgs;
14082                    opti = 0;
14083                    more = true;
14084                }
14085            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14086                synchronized (this) {
14087                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14088                }
14089            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14090                if (dumpClient) {
14091                    ActiveServices.ServiceDumper dumper;
14092                    synchronized (this) {
14093                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14094                                dumpPackage);
14095                    }
14096                    dumper.dumpWithClient();
14097                } else {
14098                    synchronized (this) {
14099                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14100                                dumpPackage).dumpLocked();
14101                    }
14102                }
14103            } else if ("locks".equals(cmd)) {
14104                LockGuard.dump(fd, pw, args);
14105            } else {
14106                // Dumping a single activity?
14107                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14108                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14109                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14110                    if (res < 0) {
14111                        pw.println("Bad activity command, or no activities match: " + cmd);
14112                        pw.println("Use -h for help.");
14113                    }
14114                }
14115            }
14116            if (!more) {
14117                Binder.restoreCallingIdentity(origId);
14118                return;
14119            }
14120        }
14121
14122        // No piece of data specified, dump everything.
14123        if (dumpCheckinFormat) {
14124            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14125        } else if (dumpClient) {
14126            ActiveServices.ServiceDumper sdumper;
14127            synchronized (this) {
14128                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14129                pw.println();
14130                if (dumpAll) {
14131                    pw.println("-------------------------------------------------------------------------------");
14132                }
14133                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14134                pw.println();
14135                if (dumpAll) {
14136                    pw.println("-------------------------------------------------------------------------------");
14137                }
14138                if (dumpAll || dumpPackage != null) {
14139                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14140                    pw.println();
14141                    if (dumpAll) {
14142                        pw.println("-------------------------------------------------------------------------------");
14143                    }
14144                }
14145                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14146                pw.println();
14147                if (dumpAll) {
14148                    pw.println("-------------------------------------------------------------------------------");
14149                }
14150                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14151                pw.println();
14152                if (dumpAll) {
14153                    pw.println("-------------------------------------------------------------------------------");
14154                }
14155                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14156                        dumpPackage);
14157            }
14158            sdumper.dumpWithClient();
14159            pw.println();
14160            synchronized (this) {
14161                if (dumpAll) {
14162                    pw.println("-------------------------------------------------------------------------------");
14163                }
14164                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14165                pw.println();
14166                if (dumpAll) {
14167                    pw.println("-------------------------------------------------------------------------------");
14168                }
14169                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14170                if (mAssociations.size() > 0) {
14171                    pw.println();
14172                    if (dumpAll) {
14173                        pw.println("-------------------------------------------------------------------------------");
14174                    }
14175                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14176                }
14177                pw.println();
14178                if (dumpAll) {
14179                    pw.println("-------------------------------------------------------------------------------");
14180                }
14181                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14182            }
14183
14184        } else {
14185            synchronized (this) {
14186                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14187                pw.println();
14188                if (dumpAll) {
14189                    pw.println("-------------------------------------------------------------------------------");
14190                }
14191                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14192                pw.println();
14193                if (dumpAll) {
14194                    pw.println("-------------------------------------------------------------------------------");
14195                }
14196                if (dumpAll || dumpPackage != null) {
14197                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14198                    pw.println();
14199                    if (dumpAll) {
14200                        pw.println("-------------------------------------------------------------------------------");
14201                    }
14202                }
14203                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14204                pw.println();
14205                if (dumpAll) {
14206                    pw.println("-------------------------------------------------------------------------------");
14207                }
14208                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14209                pw.println();
14210                if (dumpAll) {
14211                    pw.println("-------------------------------------------------------------------------------");
14212                }
14213                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14214                        .dumpLocked();
14215                pw.println();
14216                if (dumpAll) {
14217                    pw.println("-------------------------------------------------------------------------------");
14218                }
14219                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14220                pw.println();
14221                if (dumpAll) {
14222                    pw.println("-------------------------------------------------------------------------------");
14223                }
14224                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14225                if (mAssociations.size() > 0) {
14226                    pw.println();
14227                    if (dumpAll) {
14228                        pw.println("-------------------------------------------------------------------------------");
14229                    }
14230                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14231                }
14232                pw.println();
14233                if (dumpAll) {
14234                    pw.println("-------------------------------------------------------------------------------");
14235                }
14236                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14237            }
14238        }
14239        Binder.restoreCallingIdentity(origId);
14240    }
14241
14242    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14243            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14244        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14245
14246        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14247                dumpPackage);
14248        boolean needSep = printedAnything;
14249
14250        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14251                dumpPackage, needSep, "  mFocusedActivity: ");
14252        if (printed) {
14253            printedAnything = true;
14254            needSep = false;
14255        }
14256
14257        if (dumpPackage == null) {
14258            if (needSep) {
14259                pw.println();
14260            }
14261            needSep = true;
14262            printedAnything = true;
14263            mStackSupervisor.dump(pw, "  ");
14264        }
14265
14266        if (!printedAnything) {
14267            pw.println("  (nothing)");
14268        }
14269    }
14270
14271    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14272            int opti, boolean dumpAll, String dumpPackage) {
14273        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14274
14275        boolean printedAnything = false;
14276
14277        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14278            boolean printedHeader = false;
14279
14280            final int N = mRecentTasks.size();
14281            for (int i=0; i<N; i++) {
14282                TaskRecord tr = mRecentTasks.get(i);
14283                if (dumpPackage != null) {
14284                    if (tr.realActivity == null ||
14285                            !dumpPackage.equals(tr.realActivity)) {
14286                        continue;
14287                    }
14288                }
14289                if (!printedHeader) {
14290                    pw.println("  Recent tasks:");
14291                    printedHeader = true;
14292                    printedAnything = true;
14293                }
14294                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14295                        pw.println(tr);
14296                if (dumpAll) {
14297                    mRecentTasks.get(i).dump(pw, "    ");
14298                }
14299            }
14300        }
14301
14302        if (!printedAnything) {
14303            pw.println("  (nothing)");
14304        }
14305    }
14306
14307    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14308            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14309        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14310
14311        int dumpUid = 0;
14312        if (dumpPackage != null) {
14313            IPackageManager pm = AppGlobals.getPackageManager();
14314            try {
14315                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14316            } catch (RemoteException e) {
14317            }
14318        }
14319
14320        boolean printedAnything = false;
14321
14322        final long now = SystemClock.uptimeMillis();
14323
14324        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14325            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14326                    = mAssociations.valueAt(i1);
14327            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14328                SparseArray<ArrayMap<String, Association>> sourceUids
14329                        = targetComponents.valueAt(i2);
14330                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14331                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14332                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14333                        Association ass = sourceProcesses.valueAt(i4);
14334                        if (dumpPackage != null) {
14335                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14336                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14337                                continue;
14338                            }
14339                        }
14340                        printedAnything = true;
14341                        pw.print("  ");
14342                        pw.print(ass.mTargetProcess);
14343                        pw.print("/");
14344                        UserHandle.formatUid(pw, ass.mTargetUid);
14345                        pw.print(" <- ");
14346                        pw.print(ass.mSourceProcess);
14347                        pw.print("/");
14348                        UserHandle.formatUid(pw, ass.mSourceUid);
14349                        pw.println();
14350                        pw.print("    via ");
14351                        pw.print(ass.mTargetComponent.flattenToShortString());
14352                        pw.println();
14353                        pw.print("    ");
14354                        long dur = ass.mTime;
14355                        if (ass.mNesting > 0) {
14356                            dur += now - ass.mStartTime;
14357                        }
14358                        TimeUtils.formatDuration(dur, pw);
14359                        pw.print(" (");
14360                        pw.print(ass.mCount);
14361                        pw.print(" times)");
14362                        pw.print("  ");
14363                        for (int i=0; i<ass.mStateTimes.length; i++) {
14364                            long amt = ass.mStateTimes[i];
14365                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14366                                amt += now - ass.mLastStateUptime;
14367                            }
14368                            if (amt != 0) {
14369                                pw.print(" ");
14370                                pw.print(ProcessList.makeProcStateString(
14371                                            i + ActivityManager.MIN_PROCESS_STATE));
14372                                pw.print("=");
14373                                TimeUtils.formatDuration(amt, pw);
14374                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14375                                    pw.print("*");
14376                                }
14377                            }
14378                        }
14379                        pw.println();
14380                        if (ass.mNesting > 0) {
14381                            pw.print("    Currently active: ");
14382                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14383                            pw.println();
14384                        }
14385                    }
14386                }
14387            }
14388
14389        }
14390
14391        if (!printedAnything) {
14392            pw.println("  (nothing)");
14393        }
14394    }
14395
14396    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14397            String header, boolean needSep) {
14398        boolean printed = false;
14399        int whichAppId = -1;
14400        if (dumpPackage != null) {
14401            try {
14402                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14403                        dumpPackage, 0);
14404                whichAppId = UserHandle.getAppId(info.uid);
14405            } catch (NameNotFoundException e) {
14406                e.printStackTrace();
14407            }
14408        }
14409        for (int i=0; i<uids.size(); i++) {
14410            UidRecord uidRec = uids.valueAt(i);
14411            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14412                continue;
14413            }
14414            if (!printed) {
14415                printed = true;
14416                if (needSep) {
14417                    pw.println();
14418                }
14419                pw.print("  ");
14420                pw.println(header);
14421                needSep = true;
14422            }
14423            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14424            pw.print(": "); pw.println(uidRec);
14425        }
14426        return printed;
14427    }
14428
14429    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14430            int opti, boolean dumpAll, String dumpPackage) {
14431        boolean needSep = false;
14432        boolean printedAnything = false;
14433        int numPers = 0;
14434
14435        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14436
14437        if (dumpAll) {
14438            final int NP = mProcessNames.getMap().size();
14439            for (int ip=0; ip<NP; ip++) {
14440                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14441                final int NA = procs.size();
14442                for (int ia=0; ia<NA; ia++) {
14443                    ProcessRecord r = procs.valueAt(ia);
14444                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14445                        continue;
14446                    }
14447                    if (!needSep) {
14448                        pw.println("  All known processes:");
14449                        needSep = true;
14450                        printedAnything = true;
14451                    }
14452                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14453                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14454                        pw.print(" "); pw.println(r);
14455                    r.dump(pw, "    ");
14456                    if (r.persistent) {
14457                        numPers++;
14458                    }
14459                }
14460            }
14461        }
14462
14463        if (mIsolatedProcesses.size() > 0) {
14464            boolean printed = false;
14465            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14466                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14467                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14468                    continue;
14469                }
14470                if (!printed) {
14471                    if (needSep) {
14472                        pw.println();
14473                    }
14474                    pw.println("  Isolated process list (sorted by uid):");
14475                    printedAnything = true;
14476                    printed = true;
14477                    needSep = true;
14478                }
14479                pw.println(String.format("%sIsolated #%2d: %s",
14480                        "    ", i, r.toString()));
14481            }
14482        }
14483
14484        if (mActiveUids.size() > 0) {
14485            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14486                printedAnything = needSep = true;
14487            }
14488        }
14489        if (mValidateUids.size() > 0) {
14490            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14491                printedAnything = needSep = true;
14492            }
14493        }
14494
14495        if (mLruProcesses.size() > 0) {
14496            if (needSep) {
14497                pw.println();
14498            }
14499            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14500                    pw.print(" total, non-act at ");
14501                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14502                    pw.print(", non-svc at ");
14503                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14504                    pw.println("):");
14505            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14506            needSep = true;
14507            printedAnything = true;
14508        }
14509
14510        if (dumpAll || dumpPackage != null) {
14511            synchronized (mPidsSelfLocked) {
14512                boolean printed = false;
14513                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14514                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14515                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14516                        continue;
14517                    }
14518                    if (!printed) {
14519                        if (needSep) pw.println();
14520                        needSep = true;
14521                        pw.println("  PID mappings:");
14522                        printed = true;
14523                        printedAnything = true;
14524                    }
14525                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14526                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14527                }
14528            }
14529        }
14530
14531        if (mForegroundProcesses.size() > 0) {
14532            synchronized (mPidsSelfLocked) {
14533                boolean printed = false;
14534                for (int i=0; i<mForegroundProcesses.size(); i++) {
14535                    ProcessRecord r = mPidsSelfLocked.get(
14536                            mForegroundProcesses.valueAt(i).pid);
14537                    if (dumpPackage != null && (r == null
14538                            || !r.pkgList.containsKey(dumpPackage))) {
14539                        continue;
14540                    }
14541                    if (!printed) {
14542                        if (needSep) pw.println();
14543                        needSep = true;
14544                        pw.println("  Foreground Processes:");
14545                        printed = true;
14546                        printedAnything = true;
14547                    }
14548                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14549                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14550                }
14551            }
14552        }
14553
14554        if (mPersistentStartingProcesses.size() > 0) {
14555            if (needSep) pw.println();
14556            needSep = true;
14557            printedAnything = true;
14558            pw.println("  Persisent processes that are starting:");
14559            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14560                    "Starting Norm", "Restarting PERS", dumpPackage);
14561        }
14562
14563        if (mRemovedProcesses.size() > 0) {
14564            if (needSep) pw.println();
14565            needSep = true;
14566            printedAnything = true;
14567            pw.println("  Processes that are being removed:");
14568            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14569                    "Removed Norm", "Removed PERS", dumpPackage);
14570        }
14571
14572        if (mProcessesOnHold.size() > 0) {
14573            if (needSep) pw.println();
14574            needSep = true;
14575            printedAnything = true;
14576            pw.println("  Processes that are on old until the system is ready:");
14577            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14578                    "OnHold Norm", "OnHold PERS", dumpPackage);
14579        }
14580
14581        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14582
14583        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14584        if (needSep) {
14585            printedAnything = true;
14586        }
14587
14588        if (dumpPackage == null) {
14589            pw.println();
14590            needSep = false;
14591            mUserController.dump(pw, dumpAll);
14592        }
14593        if (mHomeProcess != null && (dumpPackage == null
14594                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14595            if (needSep) {
14596                pw.println();
14597                needSep = false;
14598            }
14599            pw.println("  mHomeProcess: " + mHomeProcess);
14600        }
14601        if (mPreviousProcess != null && (dumpPackage == null
14602                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14603            if (needSep) {
14604                pw.println();
14605                needSep = false;
14606            }
14607            pw.println("  mPreviousProcess: " + mPreviousProcess);
14608        }
14609        if (dumpAll) {
14610            StringBuilder sb = new StringBuilder(128);
14611            sb.append("  mPreviousProcessVisibleTime: ");
14612            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14613            pw.println(sb);
14614        }
14615        if (mHeavyWeightProcess != null && (dumpPackage == null
14616                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14617            if (needSep) {
14618                pw.println();
14619                needSep = false;
14620            }
14621            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14622        }
14623        if (dumpPackage == null) {
14624            pw.println("  mConfiguration: " + mConfiguration);
14625        }
14626        if (dumpAll) {
14627            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14628            if (mCompatModePackages.getPackages().size() > 0) {
14629                boolean printed = false;
14630                for (Map.Entry<String, Integer> entry
14631                        : mCompatModePackages.getPackages().entrySet()) {
14632                    String pkg = entry.getKey();
14633                    int mode = entry.getValue();
14634                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14635                        continue;
14636                    }
14637                    if (!printed) {
14638                        pw.println("  mScreenCompatPackages:");
14639                        printed = true;
14640                    }
14641                    pw.print("    "); pw.print(pkg); pw.print(": ");
14642                            pw.print(mode); pw.println();
14643                }
14644            }
14645        }
14646        if (dumpPackage == null) {
14647            pw.println("  mWakefulness="
14648                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14649            pw.println("  mSleepTokens=" + mSleepTokens);
14650            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14651                    + lockScreenShownToString());
14652            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14653            if (mRunningVoice != null) {
14654                pw.println("  mRunningVoice=" + mRunningVoice);
14655                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14656            }
14657        }
14658        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14659                || mOrigWaitForDebugger) {
14660            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14661                    || dumpPackage.equals(mOrigDebugApp)) {
14662                if (needSep) {
14663                    pw.println();
14664                    needSep = false;
14665                }
14666                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14667                        + " mDebugTransient=" + mDebugTransient
14668                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14669            }
14670        }
14671        if (mCurAppTimeTracker != null) {
14672            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14673        }
14674        if (mMemWatchProcesses.getMap().size() > 0) {
14675            pw.println("  Mem watch processes:");
14676            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14677                    = mMemWatchProcesses.getMap();
14678            for (int i=0; i<procs.size(); i++) {
14679                final String proc = procs.keyAt(i);
14680                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14681                for (int j=0; j<uids.size(); j++) {
14682                    if (needSep) {
14683                        pw.println();
14684                        needSep = false;
14685                    }
14686                    StringBuilder sb = new StringBuilder();
14687                    sb.append("    ").append(proc).append('/');
14688                    UserHandle.formatUid(sb, uids.keyAt(j));
14689                    Pair<Long, String> val = uids.valueAt(j);
14690                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14691                    if (val.second != null) {
14692                        sb.append(", report to ").append(val.second);
14693                    }
14694                    pw.println(sb.toString());
14695                }
14696            }
14697            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14698            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14699            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14700                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14701        }
14702        if (mTrackAllocationApp != null) {
14703            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14704                if (needSep) {
14705                    pw.println();
14706                    needSep = false;
14707                }
14708                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14709            }
14710        }
14711        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14712                || mProfileFd != null) {
14713            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14714                if (needSep) {
14715                    pw.println();
14716                    needSep = false;
14717                }
14718                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14719                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14720                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14721                        + mAutoStopProfiler);
14722                pw.println("  mProfileType=" + mProfileType);
14723            }
14724        }
14725        if (mNativeDebuggingApp != null) {
14726            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14727                if (needSep) {
14728                    pw.println();
14729                    needSep = false;
14730                }
14731                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14732            }
14733        }
14734        if (dumpPackage == null) {
14735            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14736                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14737                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14738            }
14739            if (mController != null) {
14740                pw.println("  mController=" + mController
14741                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14742            }
14743            if (dumpAll) {
14744                pw.println("  Total persistent processes: " + numPers);
14745                pw.println("  mProcessesReady=" + mProcessesReady
14746                        + " mSystemReady=" + mSystemReady
14747                        + " mBooted=" + mBooted
14748                        + " mFactoryTest=" + mFactoryTest);
14749                pw.println("  mBooting=" + mBooting
14750                        + " mCallFinishBooting=" + mCallFinishBooting
14751                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14752                pw.print("  mLastPowerCheckRealtime=");
14753                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14754                        pw.println("");
14755                pw.print("  mLastPowerCheckUptime=");
14756                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14757                        pw.println("");
14758                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14759                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14760                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14761                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14762                        + " (" + mLruProcesses.size() + " total)"
14763                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14764                        + " mNumServiceProcs=" + mNumServiceProcs
14765                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14766                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14767                        + " mLastMemoryLevel=" + mLastMemoryLevel
14768                        + " mLastNumProcesses=" + mLastNumProcesses);
14769                long now = SystemClock.uptimeMillis();
14770                pw.print("  mLastIdleTime=");
14771                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14772                        pw.print(" mLowRamSinceLastIdle=");
14773                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14774                        pw.println();
14775            }
14776        }
14777
14778        if (!printedAnything) {
14779            pw.println("  (nothing)");
14780        }
14781    }
14782
14783    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14784            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14785        if (mProcessesToGc.size() > 0) {
14786            boolean printed = false;
14787            long now = SystemClock.uptimeMillis();
14788            for (int i=0; i<mProcessesToGc.size(); i++) {
14789                ProcessRecord proc = mProcessesToGc.get(i);
14790                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14791                    continue;
14792                }
14793                if (!printed) {
14794                    if (needSep) pw.println();
14795                    needSep = true;
14796                    pw.println("  Processes that are waiting to GC:");
14797                    printed = true;
14798                }
14799                pw.print("    Process "); pw.println(proc);
14800                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14801                        pw.print(", last gced=");
14802                        pw.print(now-proc.lastRequestedGc);
14803                        pw.print(" ms ago, last lowMem=");
14804                        pw.print(now-proc.lastLowMemory);
14805                        pw.println(" ms ago");
14806
14807            }
14808        }
14809        return needSep;
14810    }
14811
14812    void printOomLevel(PrintWriter pw, String name, int adj) {
14813        pw.print("    ");
14814        if (adj >= 0) {
14815            pw.print(' ');
14816            if (adj < 10) pw.print(' ');
14817        } else {
14818            if (adj > -10) pw.print(' ');
14819        }
14820        pw.print(adj);
14821        pw.print(": ");
14822        pw.print(name);
14823        pw.print(" (");
14824        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14825        pw.println(")");
14826    }
14827
14828    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14829            int opti, boolean dumpAll) {
14830        boolean needSep = false;
14831
14832        if (mLruProcesses.size() > 0) {
14833            if (needSep) pw.println();
14834            needSep = true;
14835            pw.println("  OOM levels:");
14836            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14837            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14838            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14839            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14840            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14841            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14842            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14843            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14844            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14845            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14846            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14847            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14848            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14849            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14850
14851            if (needSep) pw.println();
14852            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14853                    pw.print(" total, non-act at ");
14854                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14855                    pw.print(", non-svc at ");
14856                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14857                    pw.println("):");
14858            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14859            needSep = true;
14860        }
14861
14862        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14863
14864        pw.println();
14865        pw.println("  mHomeProcess: " + mHomeProcess);
14866        pw.println("  mPreviousProcess: " + mPreviousProcess);
14867        if (mHeavyWeightProcess != null) {
14868            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14869        }
14870
14871        return true;
14872    }
14873
14874    /**
14875     * There are three ways to call this:
14876     *  - no provider specified: dump all the providers
14877     *  - a flattened component name that matched an existing provider was specified as the
14878     *    first arg: dump that one provider
14879     *  - the first arg isn't the flattened component name of an existing provider:
14880     *    dump all providers whose component contains the first arg as a substring
14881     */
14882    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14883            int opti, boolean dumpAll) {
14884        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14885    }
14886
14887    static class ItemMatcher {
14888        ArrayList<ComponentName> components;
14889        ArrayList<String> strings;
14890        ArrayList<Integer> objects;
14891        boolean all;
14892
14893        ItemMatcher() {
14894            all = true;
14895        }
14896
14897        void build(String name) {
14898            ComponentName componentName = ComponentName.unflattenFromString(name);
14899            if (componentName != null) {
14900                if (components == null) {
14901                    components = new ArrayList<ComponentName>();
14902                }
14903                components.add(componentName);
14904                all = false;
14905            } else {
14906                int objectId = 0;
14907                // Not a '/' separated full component name; maybe an object ID?
14908                try {
14909                    objectId = Integer.parseInt(name, 16);
14910                    if (objects == null) {
14911                        objects = new ArrayList<Integer>();
14912                    }
14913                    objects.add(objectId);
14914                    all = false;
14915                } catch (RuntimeException e) {
14916                    // Not an integer; just do string match.
14917                    if (strings == null) {
14918                        strings = new ArrayList<String>();
14919                    }
14920                    strings.add(name);
14921                    all = false;
14922                }
14923            }
14924        }
14925
14926        int build(String[] args, int opti) {
14927            for (; opti<args.length; opti++) {
14928                String name = args[opti];
14929                if ("--".equals(name)) {
14930                    return opti+1;
14931                }
14932                build(name);
14933            }
14934            return opti;
14935        }
14936
14937        boolean match(Object object, ComponentName comp) {
14938            if (all) {
14939                return true;
14940            }
14941            if (components != null) {
14942                for (int i=0; i<components.size(); i++) {
14943                    if (components.get(i).equals(comp)) {
14944                        return true;
14945                    }
14946                }
14947            }
14948            if (objects != null) {
14949                for (int i=0; i<objects.size(); i++) {
14950                    if (System.identityHashCode(object) == objects.get(i)) {
14951                        return true;
14952                    }
14953                }
14954            }
14955            if (strings != null) {
14956                String flat = comp.flattenToString();
14957                for (int i=0; i<strings.size(); i++) {
14958                    if (flat.contains(strings.get(i))) {
14959                        return true;
14960                    }
14961                }
14962            }
14963            return false;
14964        }
14965    }
14966
14967    /**
14968     * There are three things that cmd can be:
14969     *  - a flattened component name that matches an existing activity
14970     *  - the cmd arg isn't the flattened component name of an existing activity:
14971     *    dump all activity whose component contains the cmd as a substring
14972     *  - A hex number of the ActivityRecord object instance.
14973     */
14974    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14975            int opti, boolean dumpAll) {
14976        ArrayList<ActivityRecord> activities;
14977
14978        synchronized (this) {
14979            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14980        }
14981
14982        if (activities.size() <= 0) {
14983            return false;
14984        }
14985
14986        String[] newArgs = new String[args.length - opti];
14987        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14988
14989        TaskRecord lastTask = null;
14990        boolean needSep = false;
14991        for (int i=activities.size()-1; i>=0; i--) {
14992            ActivityRecord r = activities.get(i);
14993            if (needSep) {
14994                pw.println();
14995            }
14996            needSep = true;
14997            synchronized (this) {
14998                if (lastTask != r.task) {
14999                    lastTask = r.task;
15000                    pw.print("TASK "); pw.print(lastTask.affinity);
15001                            pw.print(" id="); pw.println(lastTask.taskId);
15002                    if (dumpAll) {
15003                        lastTask.dump(pw, "  ");
15004                    }
15005                }
15006            }
15007            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15008        }
15009        return true;
15010    }
15011
15012    /**
15013     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15014     * there is a thread associated with the activity.
15015     */
15016    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15017            final ActivityRecord r, String[] args, boolean dumpAll) {
15018        String innerPrefix = prefix + "  ";
15019        synchronized (this) {
15020            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15021                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15022                    pw.print(" pid=");
15023                    if (r.app != null) pw.println(r.app.pid);
15024                    else pw.println("(not running)");
15025            if (dumpAll) {
15026                r.dump(pw, innerPrefix);
15027            }
15028        }
15029        if (r.app != null && r.app.thread != null) {
15030            // flush anything that is already in the PrintWriter since the thread is going
15031            // to write to the file descriptor directly
15032            pw.flush();
15033            try {
15034                TransferPipe tp = new TransferPipe();
15035                try {
15036                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15037                            r.appToken, innerPrefix, args);
15038                    tp.go(fd);
15039                } finally {
15040                    tp.kill();
15041                }
15042            } catch (IOException e) {
15043                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15044            } catch (RemoteException e) {
15045                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15046            }
15047        }
15048    }
15049
15050    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15051            int opti, boolean dumpAll, String dumpPackage) {
15052        boolean needSep = false;
15053        boolean onlyHistory = false;
15054        boolean printedAnything = false;
15055
15056        if ("history".equals(dumpPackage)) {
15057            if (opti < args.length && "-s".equals(args[opti])) {
15058                dumpAll = false;
15059            }
15060            onlyHistory = true;
15061            dumpPackage = null;
15062        }
15063
15064        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15065        if (!onlyHistory && dumpAll) {
15066            if (mRegisteredReceivers.size() > 0) {
15067                boolean printed = false;
15068                Iterator it = mRegisteredReceivers.values().iterator();
15069                while (it.hasNext()) {
15070                    ReceiverList r = (ReceiverList)it.next();
15071                    if (dumpPackage != null && (r.app == null ||
15072                            !dumpPackage.equals(r.app.info.packageName))) {
15073                        continue;
15074                    }
15075                    if (!printed) {
15076                        pw.println("  Registered Receivers:");
15077                        needSep = true;
15078                        printed = true;
15079                        printedAnything = true;
15080                    }
15081                    pw.print("  * "); pw.println(r);
15082                    r.dump(pw, "    ");
15083                }
15084            }
15085
15086            if (mReceiverResolver.dump(pw, needSep ?
15087                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15088                    "    ", dumpPackage, false, false)) {
15089                needSep = true;
15090                printedAnything = true;
15091            }
15092        }
15093
15094        for (BroadcastQueue q : mBroadcastQueues) {
15095            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15096            printedAnything |= needSep;
15097        }
15098
15099        needSep = true;
15100
15101        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15102            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15103                if (needSep) {
15104                    pw.println();
15105                }
15106                needSep = true;
15107                printedAnything = true;
15108                pw.print("  Sticky broadcasts for user ");
15109                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15110                StringBuilder sb = new StringBuilder(128);
15111                for (Map.Entry<String, ArrayList<Intent>> ent
15112                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15113                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15114                    if (dumpAll) {
15115                        pw.println(":");
15116                        ArrayList<Intent> intents = ent.getValue();
15117                        final int N = intents.size();
15118                        for (int i=0; i<N; i++) {
15119                            sb.setLength(0);
15120                            sb.append("    Intent: ");
15121                            intents.get(i).toShortString(sb, false, true, false, false);
15122                            pw.println(sb.toString());
15123                            Bundle bundle = intents.get(i).getExtras();
15124                            if (bundle != null) {
15125                                pw.print("      ");
15126                                pw.println(bundle.toString());
15127                            }
15128                        }
15129                    } else {
15130                        pw.println("");
15131                    }
15132                }
15133            }
15134        }
15135
15136        if (!onlyHistory && dumpAll) {
15137            pw.println();
15138            for (BroadcastQueue queue : mBroadcastQueues) {
15139                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15140                        + queue.mBroadcastsScheduled);
15141            }
15142            pw.println("  mHandler:");
15143            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15144            needSep = true;
15145            printedAnything = true;
15146        }
15147
15148        if (!printedAnything) {
15149            pw.println("  (nothing)");
15150        }
15151    }
15152
15153    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15154            int opti, boolean dumpAll, String dumpPackage) {
15155        if (mCurBroadcastStats == null) {
15156            return;
15157        }
15158
15159        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15160        final long now = SystemClock.elapsedRealtime();
15161        if (mLastBroadcastStats != null) {
15162            pw.print("  Last stats (from ");
15163            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15164            pw.print(" to ");
15165            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15166            pw.print(", ");
15167            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15168                    - mLastBroadcastStats.mStartUptime, pw);
15169            pw.println(" uptime):");
15170            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15171                pw.println("    (nothing)");
15172            }
15173            pw.println();
15174        }
15175        pw.print("  Current stats (from ");
15176        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15177        pw.print(" to now, ");
15178        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15179                - mCurBroadcastStats.mStartUptime, pw);
15180        pw.println(" uptime):");
15181        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15182            pw.println("    (nothing)");
15183        }
15184    }
15185
15186    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15187            int opti, boolean fullCheckin, String dumpPackage) {
15188        if (mCurBroadcastStats == null) {
15189            return;
15190        }
15191
15192        if (mLastBroadcastStats != null) {
15193            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15194            if (fullCheckin) {
15195                mLastBroadcastStats = null;
15196                return;
15197            }
15198        }
15199        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15200        if (fullCheckin) {
15201            mCurBroadcastStats = null;
15202        }
15203    }
15204
15205    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15206            int opti, boolean dumpAll, String dumpPackage) {
15207        boolean needSep;
15208        boolean printedAnything = false;
15209
15210        ItemMatcher matcher = new ItemMatcher();
15211        matcher.build(args, opti);
15212
15213        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15214
15215        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15216        printedAnything |= needSep;
15217
15218        if (mLaunchingProviders.size() > 0) {
15219            boolean printed = false;
15220            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15221                ContentProviderRecord r = mLaunchingProviders.get(i);
15222                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15223                    continue;
15224                }
15225                if (!printed) {
15226                    if (needSep) pw.println();
15227                    needSep = true;
15228                    pw.println("  Launching content providers:");
15229                    printed = true;
15230                    printedAnything = true;
15231                }
15232                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15233                        pw.println(r);
15234            }
15235        }
15236
15237        if (!printedAnything) {
15238            pw.println("  (nothing)");
15239        }
15240    }
15241
15242    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15243            int opti, boolean dumpAll, String dumpPackage) {
15244        boolean needSep = false;
15245        boolean printedAnything = false;
15246
15247        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15248
15249        if (mGrantedUriPermissions.size() > 0) {
15250            boolean printed = false;
15251            int dumpUid = -2;
15252            if (dumpPackage != null) {
15253                try {
15254                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15255                            MATCH_UNINSTALLED_PACKAGES, 0);
15256                } catch (NameNotFoundException e) {
15257                    dumpUid = -1;
15258                }
15259            }
15260            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15261                int uid = mGrantedUriPermissions.keyAt(i);
15262                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15263                    continue;
15264                }
15265                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15266                if (!printed) {
15267                    if (needSep) pw.println();
15268                    needSep = true;
15269                    pw.println("  Granted Uri Permissions:");
15270                    printed = true;
15271                    printedAnything = true;
15272                }
15273                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15274                for (UriPermission perm : perms.values()) {
15275                    pw.print("    "); pw.println(perm);
15276                    if (dumpAll) {
15277                        perm.dump(pw, "      ");
15278                    }
15279                }
15280            }
15281        }
15282
15283        if (!printedAnything) {
15284            pw.println("  (nothing)");
15285        }
15286    }
15287
15288    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15289            int opti, boolean dumpAll, String dumpPackage) {
15290        boolean printed = false;
15291
15292        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15293
15294        if (mIntentSenderRecords.size() > 0) {
15295            Iterator<WeakReference<PendingIntentRecord>> it
15296                    = mIntentSenderRecords.values().iterator();
15297            while (it.hasNext()) {
15298                WeakReference<PendingIntentRecord> ref = it.next();
15299                PendingIntentRecord rec = ref != null ? ref.get(): null;
15300                if (dumpPackage != null && (rec == null
15301                        || !dumpPackage.equals(rec.key.packageName))) {
15302                    continue;
15303                }
15304                printed = true;
15305                if (rec != null) {
15306                    pw.print("  * "); pw.println(rec);
15307                    if (dumpAll) {
15308                        rec.dump(pw, "    ");
15309                    }
15310                } else {
15311                    pw.print("  * "); pw.println(ref);
15312                }
15313            }
15314        }
15315
15316        if (!printed) {
15317            pw.println("  (nothing)");
15318        }
15319    }
15320
15321    private static final int dumpProcessList(PrintWriter pw,
15322            ActivityManagerService service, List list,
15323            String prefix, String normalLabel, String persistentLabel,
15324            String dumpPackage) {
15325        int numPers = 0;
15326        final int N = list.size()-1;
15327        for (int i=N; i>=0; i--) {
15328            ProcessRecord r = (ProcessRecord)list.get(i);
15329            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15330                continue;
15331            }
15332            pw.println(String.format("%s%s #%2d: %s",
15333                    prefix, (r.persistent ? persistentLabel : normalLabel),
15334                    i, r.toString()));
15335            if (r.persistent) {
15336                numPers++;
15337            }
15338        }
15339        return numPers;
15340    }
15341
15342    private static final boolean dumpProcessOomList(PrintWriter pw,
15343            ActivityManagerService service, List<ProcessRecord> origList,
15344            String prefix, String normalLabel, String persistentLabel,
15345            boolean inclDetails, String dumpPackage) {
15346
15347        ArrayList<Pair<ProcessRecord, Integer>> list
15348                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15349        for (int i=0; i<origList.size(); i++) {
15350            ProcessRecord r = origList.get(i);
15351            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15352                continue;
15353            }
15354            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15355        }
15356
15357        if (list.size() <= 0) {
15358            return false;
15359        }
15360
15361        Comparator<Pair<ProcessRecord, Integer>> comparator
15362                = new Comparator<Pair<ProcessRecord, Integer>>() {
15363            @Override
15364            public int compare(Pair<ProcessRecord, Integer> object1,
15365                    Pair<ProcessRecord, Integer> object2) {
15366                if (object1.first.setAdj != object2.first.setAdj) {
15367                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15368                }
15369                if (object1.first.setProcState != object2.first.setProcState) {
15370                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15371                }
15372                if (object1.second.intValue() != object2.second.intValue()) {
15373                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15374                }
15375                return 0;
15376            }
15377        };
15378
15379        Collections.sort(list, comparator);
15380
15381        final long curRealtime = SystemClock.elapsedRealtime();
15382        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15383        final long curUptime = SystemClock.uptimeMillis();
15384        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15385
15386        for (int i=list.size()-1; i>=0; i--) {
15387            ProcessRecord r = list.get(i).first;
15388            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15389            char schedGroup;
15390            switch (r.setSchedGroup) {
15391                case ProcessList.SCHED_GROUP_BACKGROUND:
15392                    schedGroup = 'B';
15393                    break;
15394                case ProcessList.SCHED_GROUP_DEFAULT:
15395                    schedGroup = 'F';
15396                    break;
15397                case ProcessList.SCHED_GROUP_TOP_APP:
15398                    schedGroup = 'T';
15399                    break;
15400                default:
15401                    schedGroup = '?';
15402                    break;
15403            }
15404            char foreground;
15405            if (r.foregroundActivities) {
15406                foreground = 'A';
15407            } else if (r.foregroundServices) {
15408                foreground = 'S';
15409            } else {
15410                foreground = ' ';
15411            }
15412            String procState = ProcessList.makeProcStateString(r.curProcState);
15413            pw.print(prefix);
15414            pw.print(r.persistent ? persistentLabel : normalLabel);
15415            pw.print(" #");
15416            int num = (origList.size()-1)-list.get(i).second;
15417            if (num < 10) pw.print(' ');
15418            pw.print(num);
15419            pw.print(": ");
15420            pw.print(oomAdj);
15421            pw.print(' ');
15422            pw.print(schedGroup);
15423            pw.print('/');
15424            pw.print(foreground);
15425            pw.print('/');
15426            pw.print(procState);
15427            pw.print(" trm:");
15428            if (r.trimMemoryLevel < 10) pw.print(' ');
15429            pw.print(r.trimMemoryLevel);
15430            pw.print(' ');
15431            pw.print(r.toShortString());
15432            pw.print(" (");
15433            pw.print(r.adjType);
15434            pw.println(')');
15435            if (r.adjSource != null || r.adjTarget != null) {
15436                pw.print(prefix);
15437                pw.print("    ");
15438                if (r.adjTarget instanceof ComponentName) {
15439                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15440                } else if (r.adjTarget != null) {
15441                    pw.print(r.adjTarget.toString());
15442                } else {
15443                    pw.print("{null}");
15444                }
15445                pw.print("<=");
15446                if (r.adjSource instanceof ProcessRecord) {
15447                    pw.print("Proc{");
15448                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15449                    pw.println("}");
15450                } else if (r.adjSource != null) {
15451                    pw.println(r.adjSource.toString());
15452                } else {
15453                    pw.println("{null}");
15454                }
15455            }
15456            if (inclDetails) {
15457                pw.print(prefix);
15458                pw.print("    ");
15459                pw.print("oom: max="); pw.print(r.maxAdj);
15460                pw.print(" curRaw="); pw.print(r.curRawAdj);
15461                pw.print(" setRaw="); pw.print(r.setRawAdj);
15462                pw.print(" cur="); pw.print(r.curAdj);
15463                pw.print(" set="); pw.println(r.setAdj);
15464                pw.print(prefix);
15465                pw.print("    ");
15466                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15467                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15468                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15469                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15470                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15471                pw.println();
15472                pw.print(prefix);
15473                pw.print("    ");
15474                pw.print("cached="); pw.print(r.cached);
15475                pw.print(" empty="); pw.print(r.empty);
15476                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15477
15478                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15479                    if (r.lastWakeTime != 0) {
15480                        long wtime;
15481                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15482                        synchronized (stats) {
15483                            wtime = stats.getProcessWakeTime(r.info.uid,
15484                                    r.pid, curRealtime);
15485                        }
15486                        long timeUsed = wtime - r.lastWakeTime;
15487                        pw.print(prefix);
15488                        pw.print("    ");
15489                        pw.print("keep awake over ");
15490                        TimeUtils.formatDuration(realtimeSince, pw);
15491                        pw.print(" used ");
15492                        TimeUtils.formatDuration(timeUsed, pw);
15493                        pw.print(" (");
15494                        pw.print((timeUsed*100)/realtimeSince);
15495                        pw.println("%)");
15496                    }
15497                    if (r.lastCpuTime != 0) {
15498                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15499                        pw.print(prefix);
15500                        pw.print("    ");
15501                        pw.print("run cpu over ");
15502                        TimeUtils.formatDuration(uptimeSince, pw);
15503                        pw.print(" used ");
15504                        TimeUtils.formatDuration(timeUsed, pw);
15505                        pw.print(" (");
15506                        pw.print((timeUsed*100)/uptimeSince);
15507                        pw.println("%)");
15508                    }
15509                }
15510            }
15511        }
15512        return true;
15513    }
15514
15515    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15516            String[] args) {
15517        ArrayList<ProcessRecord> procs;
15518        synchronized (this) {
15519            if (args != null && args.length > start
15520                    && args[start].charAt(0) != '-') {
15521                procs = new ArrayList<ProcessRecord>();
15522                int pid = -1;
15523                try {
15524                    pid = Integer.parseInt(args[start]);
15525                } catch (NumberFormatException e) {
15526                }
15527                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15528                    ProcessRecord proc = mLruProcesses.get(i);
15529                    if (proc.pid == pid) {
15530                        procs.add(proc);
15531                    } else if (allPkgs && proc.pkgList != null
15532                            && proc.pkgList.containsKey(args[start])) {
15533                        procs.add(proc);
15534                    } else if (proc.processName.equals(args[start])) {
15535                        procs.add(proc);
15536                    }
15537                }
15538                if (procs.size() <= 0) {
15539                    return null;
15540                }
15541            } else {
15542                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15543            }
15544        }
15545        return procs;
15546    }
15547
15548    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15549            PrintWriter pw, String[] args) {
15550        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15551        if (procs == null) {
15552            pw.println("No process found for: " + args[0]);
15553            return;
15554        }
15555
15556        long uptime = SystemClock.uptimeMillis();
15557        long realtime = SystemClock.elapsedRealtime();
15558        pw.println("Applications Graphics Acceleration Info:");
15559        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15560
15561        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15562            ProcessRecord r = procs.get(i);
15563            if (r.thread != null) {
15564                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15565                pw.flush();
15566                try {
15567                    TransferPipe tp = new TransferPipe();
15568                    try {
15569                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15570                        tp.go(fd);
15571                    } finally {
15572                        tp.kill();
15573                    }
15574                } catch (IOException e) {
15575                    pw.println("Failure while dumping the app: " + r);
15576                    pw.flush();
15577                } catch (RemoteException e) {
15578                    pw.println("Got a RemoteException while dumping the app " + r);
15579                    pw.flush();
15580                }
15581            }
15582        }
15583    }
15584
15585    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15586        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15587        if (procs == null) {
15588            pw.println("No process found for: " + args[0]);
15589            return;
15590        }
15591
15592        pw.println("Applications Database Info:");
15593
15594        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15595            ProcessRecord r = procs.get(i);
15596            if (r.thread != null) {
15597                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15598                pw.flush();
15599                try {
15600                    TransferPipe tp = new TransferPipe();
15601                    try {
15602                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15603                        tp.go(fd);
15604                    } finally {
15605                        tp.kill();
15606                    }
15607                } catch (IOException e) {
15608                    pw.println("Failure while dumping the app: " + r);
15609                    pw.flush();
15610                } catch (RemoteException e) {
15611                    pw.println("Got a RemoteException while dumping the app " + r);
15612                    pw.flush();
15613                }
15614            }
15615        }
15616    }
15617
15618    final static class MemItem {
15619        final boolean isProc;
15620        final String label;
15621        final String shortLabel;
15622        final long pss;
15623        final long swapPss;
15624        final int id;
15625        final boolean hasActivities;
15626        ArrayList<MemItem> subitems;
15627
15628        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15629                boolean _hasActivities) {
15630            isProc = true;
15631            label = _label;
15632            shortLabel = _shortLabel;
15633            pss = _pss;
15634            swapPss = _swapPss;
15635            id = _id;
15636            hasActivities = _hasActivities;
15637        }
15638
15639        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15640            isProc = false;
15641            label = _label;
15642            shortLabel = _shortLabel;
15643            pss = _pss;
15644            swapPss = _swapPss;
15645            id = _id;
15646            hasActivities = false;
15647        }
15648    }
15649
15650    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15651            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15652        if (sort && !isCompact) {
15653            Collections.sort(items, new Comparator<MemItem>() {
15654                @Override
15655                public int compare(MemItem lhs, MemItem rhs) {
15656                    if (lhs.pss < rhs.pss) {
15657                        return 1;
15658                    } else if (lhs.pss > rhs.pss) {
15659                        return -1;
15660                    }
15661                    return 0;
15662                }
15663            });
15664        }
15665
15666        for (int i=0; i<items.size(); i++) {
15667            MemItem mi = items.get(i);
15668            if (!isCompact) {
15669                if (dumpSwapPss) {
15670                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15671                            mi.label, stringifyKBSize(mi.swapPss));
15672                } else {
15673                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15674                }
15675            } else if (mi.isProc) {
15676                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15677                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15678                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15679                pw.println(mi.hasActivities ? ",a" : ",e");
15680            } else {
15681                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15682                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15683            }
15684            if (mi.subitems != null) {
15685                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15686                        true, isCompact, dumpSwapPss);
15687            }
15688        }
15689    }
15690
15691    // These are in KB.
15692    static final long[] DUMP_MEM_BUCKETS = new long[] {
15693        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15694        120*1024, 160*1024, 200*1024,
15695        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15696        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15697    };
15698
15699    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15700            boolean stackLike) {
15701        int start = label.lastIndexOf('.');
15702        if (start >= 0) start++;
15703        else start = 0;
15704        int end = label.length();
15705        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15706            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15707                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15708                out.append(bucket);
15709                out.append(stackLike ? "MB." : "MB ");
15710                out.append(label, start, end);
15711                return;
15712            }
15713        }
15714        out.append(memKB/1024);
15715        out.append(stackLike ? "MB." : "MB ");
15716        out.append(label, start, end);
15717    }
15718
15719    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15720            ProcessList.NATIVE_ADJ,
15721            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15722            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15723            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15724            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15725            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15726            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15727    };
15728    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15729            "Native",
15730            "System", "Persistent", "Persistent Service", "Foreground",
15731            "Visible", "Perceptible",
15732            "Heavy Weight", "Backup",
15733            "A Services", "Home",
15734            "Previous", "B Services", "Cached"
15735    };
15736    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15737            "native",
15738            "sys", "pers", "persvc", "fore",
15739            "vis", "percept",
15740            "heavy", "backup",
15741            "servicea", "home",
15742            "prev", "serviceb", "cached"
15743    };
15744
15745    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15746            long realtime, boolean isCheckinRequest, boolean isCompact) {
15747        if (isCompact) {
15748            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15749        }
15750        if (isCheckinRequest || isCompact) {
15751            // short checkin version
15752            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15753        } else {
15754            pw.println("Applications Memory Usage (in Kilobytes):");
15755            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15756        }
15757    }
15758
15759    private static final int KSM_SHARED = 0;
15760    private static final int KSM_SHARING = 1;
15761    private static final int KSM_UNSHARED = 2;
15762    private static final int KSM_VOLATILE = 3;
15763
15764    private final long[] getKsmInfo() {
15765        long[] longOut = new long[4];
15766        final int[] SINGLE_LONG_FORMAT = new int[] {
15767            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15768        };
15769        long[] longTmp = new long[1];
15770        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15771                SINGLE_LONG_FORMAT, null, longTmp, null);
15772        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15773        longTmp[0] = 0;
15774        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15775                SINGLE_LONG_FORMAT, null, longTmp, null);
15776        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15777        longTmp[0] = 0;
15778        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15779                SINGLE_LONG_FORMAT, null, longTmp, null);
15780        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15781        longTmp[0] = 0;
15782        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15783                SINGLE_LONG_FORMAT, null, longTmp, null);
15784        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15785        return longOut;
15786    }
15787
15788    private static String stringifySize(long size, int order) {
15789        Locale locale = Locale.US;
15790        switch (order) {
15791            case 1:
15792                return String.format(locale, "%,13d", size);
15793            case 1024:
15794                return String.format(locale, "%,9dK", size / 1024);
15795            case 1024 * 1024:
15796                return String.format(locale, "%,5dM", size / 1024 / 1024);
15797            case 1024 * 1024 * 1024:
15798                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15799            default:
15800                throw new IllegalArgumentException("Invalid size order");
15801        }
15802    }
15803
15804    private static String stringifyKBSize(long size) {
15805        return stringifySize(size * 1024, 1024);
15806    }
15807
15808    // Update this version number in case you change the 'compact' format
15809    private static final int MEMINFO_COMPACT_VERSION = 1;
15810
15811    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15812            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15813        boolean dumpDetails = false;
15814        boolean dumpFullDetails = false;
15815        boolean dumpDalvik = false;
15816        boolean dumpSummaryOnly = false;
15817        boolean dumpUnreachable = false;
15818        boolean oomOnly = false;
15819        boolean isCompact = false;
15820        boolean localOnly = false;
15821        boolean packages = false;
15822        boolean isCheckinRequest = false;
15823        boolean dumpSwapPss = false;
15824
15825        int opti = 0;
15826        while (opti < args.length) {
15827            String opt = args[opti];
15828            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15829                break;
15830            }
15831            opti++;
15832            if ("-a".equals(opt)) {
15833                dumpDetails = true;
15834                dumpFullDetails = true;
15835                dumpDalvik = true;
15836                dumpSwapPss = true;
15837            } else if ("-d".equals(opt)) {
15838                dumpDalvik = true;
15839            } else if ("-c".equals(opt)) {
15840                isCompact = true;
15841            } else if ("-s".equals(opt)) {
15842                dumpDetails = true;
15843                dumpSummaryOnly = true;
15844            } else if ("-S".equals(opt)) {
15845                dumpSwapPss = true;
15846            } else if ("--unreachable".equals(opt)) {
15847                dumpUnreachable = true;
15848            } else if ("--oom".equals(opt)) {
15849                oomOnly = true;
15850            } else if ("--local".equals(opt)) {
15851                localOnly = true;
15852            } else if ("--package".equals(opt)) {
15853                packages = true;
15854            } else if ("--checkin".equals(opt)) {
15855                isCheckinRequest = true;
15856
15857            } else if ("-h".equals(opt)) {
15858                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15859                pw.println("  -a: include all available information for each process.");
15860                pw.println("  -d: include dalvik details.");
15861                pw.println("  -c: dump in a compact machine-parseable representation.");
15862                pw.println("  -s: dump only summary of application memory usage.");
15863                pw.println("  -S: dump also SwapPss.");
15864                pw.println("  --oom: only show processes organized by oom adj.");
15865                pw.println("  --local: only collect details locally, don't call process.");
15866                pw.println("  --package: interpret process arg as package, dumping all");
15867                pw.println("             processes that have loaded that package.");
15868                pw.println("  --checkin: dump data for a checkin");
15869                pw.println("If [process] is specified it can be the name or ");
15870                pw.println("pid of a specific process to dump.");
15871                return;
15872            } else {
15873                pw.println("Unknown argument: " + opt + "; use -h for help");
15874            }
15875        }
15876
15877        long uptime = SystemClock.uptimeMillis();
15878        long realtime = SystemClock.elapsedRealtime();
15879        final long[] tmpLong = new long[1];
15880
15881        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15882        if (procs == null) {
15883            // No Java processes.  Maybe they want to print a native process.
15884            if (args != null && args.length > opti
15885                    && args[opti].charAt(0) != '-') {
15886                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15887                        = new ArrayList<ProcessCpuTracker.Stats>();
15888                updateCpuStatsNow();
15889                int findPid = -1;
15890                try {
15891                    findPid = Integer.parseInt(args[opti]);
15892                } catch (NumberFormatException e) {
15893                }
15894                synchronized (mProcessCpuTracker) {
15895                    final int N = mProcessCpuTracker.countStats();
15896                    for (int i=0; i<N; i++) {
15897                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15898                        if (st.pid == findPid || (st.baseName != null
15899                                && st.baseName.equals(args[opti]))) {
15900                            nativeProcs.add(st);
15901                        }
15902                    }
15903                }
15904                if (nativeProcs.size() > 0) {
15905                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15906                            isCompact);
15907                    Debug.MemoryInfo mi = null;
15908                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15909                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15910                        final int pid = r.pid;
15911                        if (!isCheckinRequest && dumpDetails) {
15912                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15913                        }
15914                        if (mi == null) {
15915                            mi = new Debug.MemoryInfo();
15916                        }
15917                        if (dumpDetails || (!brief && !oomOnly)) {
15918                            Debug.getMemoryInfo(pid, mi);
15919                        } else {
15920                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15921                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15922                        }
15923                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15924                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15925                        if (isCheckinRequest) {
15926                            pw.println();
15927                        }
15928                    }
15929                    return;
15930                }
15931            }
15932            pw.println("No process found for: " + args[opti]);
15933            return;
15934        }
15935
15936        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15937            dumpDetails = true;
15938        }
15939
15940        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15941
15942        String[] innerArgs = new String[args.length-opti];
15943        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15944
15945        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15946        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15947        long nativePss = 0;
15948        long nativeSwapPss = 0;
15949        long dalvikPss = 0;
15950        long dalvikSwapPss = 0;
15951        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15952                EmptyArray.LONG;
15953        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15954                EmptyArray.LONG;
15955        long otherPss = 0;
15956        long otherSwapPss = 0;
15957        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15958        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15959
15960        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15961        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15962        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15963                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15964
15965        long totalPss = 0;
15966        long totalSwapPss = 0;
15967        long cachedPss = 0;
15968        long cachedSwapPss = 0;
15969        boolean hasSwapPss = false;
15970
15971        Debug.MemoryInfo mi = null;
15972        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15973            final ProcessRecord r = procs.get(i);
15974            final IApplicationThread thread;
15975            final int pid;
15976            final int oomAdj;
15977            final boolean hasActivities;
15978            synchronized (this) {
15979                thread = r.thread;
15980                pid = r.pid;
15981                oomAdj = r.getSetAdjWithServices();
15982                hasActivities = r.activities.size() > 0;
15983            }
15984            if (thread != null) {
15985                if (!isCheckinRequest && dumpDetails) {
15986                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15987                }
15988                if (mi == null) {
15989                    mi = new Debug.MemoryInfo();
15990                }
15991                if (dumpDetails || (!brief && !oomOnly)) {
15992                    Debug.getMemoryInfo(pid, mi);
15993                    hasSwapPss = mi.hasSwappedOutPss;
15994                } else {
15995                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15996                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15997                }
15998                if (dumpDetails) {
15999                    if (localOnly) {
16000                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16001                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16002                        if (isCheckinRequest) {
16003                            pw.println();
16004                        }
16005                    } else {
16006                        try {
16007                            pw.flush();
16008                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16009                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16010                        } catch (RemoteException e) {
16011                            if (!isCheckinRequest) {
16012                                pw.println("Got RemoteException!");
16013                                pw.flush();
16014                            }
16015                        }
16016                    }
16017                }
16018
16019                final long myTotalPss = mi.getTotalPss();
16020                final long myTotalUss = mi.getTotalUss();
16021                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16022
16023                synchronized (this) {
16024                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16025                        // Record this for posterity if the process has been stable.
16026                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16027                    }
16028                }
16029
16030                if (!isCheckinRequest && mi != null) {
16031                    totalPss += myTotalPss;
16032                    totalSwapPss += myTotalSwapPss;
16033                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16034                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16035                            myTotalSwapPss, pid, hasActivities);
16036                    procMems.add(pssItem);
16037                    procMemsMap.put(pid, pssItem);
16038
16039                    nativePss += mi.nativePss;
16040                    nativeSwapPss += mi.nativeSwappedOutPss;
16041                    dalvikPss += mi.dalvikPss;
16042                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16043                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16044                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16045                        dalvikSubitemSwapPss[j] +=
16046                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16047                    }
16048                    otherPss += mi.otherPss;
16049                    otherSwapPss += mi.otherSwappedOutPss;
16050                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16051                        long mem = mi.getOtherPss(j);
16052                        miscPss[j] += mem;
16053                        otherPss -= mem;
16054                        mem = mi.getOtherSwappedOutPss(j);
16055                        miscSwapPss[j] += mem;
16056                        otherSwapPss -= mem;
16057                    }
16058
16059                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16060                        cachedPss += myTotalPss;
16061                        cachedSwapPss += myTotalSwapPss;
16062                    }
16063
16064                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16065                        if (oomIndex == (oomPss.length - 1)
16066                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16067                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16068                            oomPss[oomIndex] += myTotalPss;
16069                            oomSwapPss[oomIndex] += myTotalSwapPss;
16070                            if (oomProcs[oomIndex] == null) {
16071                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16072                            }
16073                            oomProcs[oomIndex].add(pssItem);
16074                            break;
16075                        }
16076                    }
16077                }
16078            }
16079        }
16080
16081        long nativeProcTotalPss = 0;
16082
16083        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16084            // If we are showing aggregations, also look for native processes to
16085            // include so that our aggregations are more accurate.
16086            updateCpuStatsNow();
16087            mi = null;
16088            synchronized (mProcessCpuTracker) {
16089                final int N = mProcessCpuTracker.countStats();
16090                for (int i=0; i<N; i++) {
16091                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16092                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16093                        if (mi == null) {
16094                            mi = new Debug.MemoryInfo();
16095                        }
16096                        if (!brief && !oomOnly) {
16097                            Debug.getMemoryInfo(st.pid, mi);
16098                        } else {
16099                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16100                            mi.nativePrivateDirty = (int)tmpLong[0];
16101                        }
16102
16103                        final long myTotalPss = mi.getTotalPss();
16104                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16105                        totalPss += myTotalPss;
16106                        nativeProcTotalPss += myTotalPss;
16107
16108                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16109                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16110                        procMems.add(pssItem);
16111
16112                        nativePss += mi.nativePss;
16113                        nativeSwapPss += mi.nativeSwappedOutPss;
16114                        dalvikPss += mi.dalvikPss;
16115                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16116                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16117                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16118                            dalvikSubitemSwapPss[j] +=
16119                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16120                        }
16121                        otherPss += mi.otherPss;
16122                        otherSwapPss += mi.otherSwappedOutPss;
16123                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16124                            long mem = mi.getOtherPss(j);
16125                            miscPss[j] += mem;
16126                            otherPss -= mem;
16127                            mem = mi.getOtherSwappedOutPss(j);
16128                            miscSwapPss[j] += mem;
16129                            otherSwapPss -= mem;
16130                        }
16131                        oomPss[0] += myTotalPss;
16132                        oomSwapPss[0] += myTotalSwapPss;
16133                        if (oomProcs[0] == null) {
16134                            oomProcs[0] = new ArrayList<MemItem>();
16135                        }
16136                        oomProcs[0].add(pssItem);
16137                    }
16138                }
16139            }
16140
16141            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16142
16143            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16144            final MemItem dalvikItem =
16145                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16146            if (dalvikSubitemPss.length > 0) {
16147                dalvikItem.subitems = new ArrayList<MemItem>();
16148                for (int j=0; j<dalvikSubitemPss.length; j++) {
16149                    final String name = Debug.MemoryInfo.getOtherLabel(
16150                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16151                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16152                                    dalvikSubitemSwapPss[j], j));
16153                }
16154            }
16155            catMems.add(dalvikItem);
16156            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16157            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16158                String label = Debug.MemoryInfo.getOtherLabel(j);
16159                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16160            }
16161
16162            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16163            for (int j=0; j<oomPss.length; j++) {
16164                if (oomPss[j] != 0) {
16165                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16166                            : DUMP_MEM_OOM_LABEL[j];
16167                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16168                            DUMP_MEM_OOM_ADJ[j]);
16169                    item.subitems = oomProcs[j];
16170                    oomMems.add(item);
16171                }
16172            }
16173
16174            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16175            if (!brief && !oomOnly && !isCompact) {
16176                pw.println();
16177                pw.println("Total PSS by process:");
16178                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16179                pw.println();
16180            }
16181            if (!isCompact) {
16182                pw.println("Total PSS by OOM adjustment:");
16183            }
16184            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16185            if (!brief && !oomOnly) {
16186                PrintWriter out = categoryPw != null ? categoryPw : pw;
16187                if (!isCompact) {
16188                    out.println();
16189                    out.println("Total PSS by category:");
16190                }
16191                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16192            }
16193            if (!isCompact) {
16194                pw.println();
16195            }
16196            MemInfoReader memInfo = new MemInfoReader();
16197            memInfo.readMemInfo();
16198            if (nativeProcTotalPss > 0) {
16199                synchronized (this) {
16200                    final long cachedKb = memInfo.getCachedSizeKb();
16201                    final long freeKb = memInfo.getFreeSizeKb();
16202                    final long zramKb = memInfo.getZramTotalSizeKb();
16203                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16204                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16205                            kernelKb*1024, nativeProcTotalPss*1024);
16206                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16207                            nativeProcTotalPss);
16208                }
16209            }
16210            if (!brief) {
16211                if (!isCompact) {
16212                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16213                    pw.print(" (status ");
16214                    switch (mLastMemoryLevel) {
16215                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16216                            pw.println("normal)");
16217                            break;
16218                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16219                            pw.println("moderate)");
16220                            break;
16221                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16222                            pw.println("low)");
16223                            break;
16224                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16225                            pw.println("critical)");
16226                            break;
16227                        default:
16228                            pw.print(mLastMemoryLevel);
16229                            pw.println(")");
16230                            break;
16231                    }
16232                    pw.print(" Free RAM: ");
16233                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16234                            + memInfo.getFreeSizeKb()));
16235                    pw.print(" (");
16236                    pw.print(stringifyKBSize(cachedPss));
16237                    pw.print(" cached pss + ");
16238                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16239                    pw.print(" cached kernel + ");
16240                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16241                    pw.println(" free)");
16242                } else {
16243                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16244                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16245                            + memInfo.getFreeSizeKb()); pw.print(",");
16246                    pw.println(totalPss - cachedPss);
16247                }
16248            }
16249            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16250                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16251                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16252            if (!isCompact) {
16253                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16254                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16255                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16256                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16257                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16258            } else {
16259                pw.print("lostram,"); pw.println(lostRAM);
16260            }
16261            if (!brief) {
16262                if (memInfo.getZramTotalSizeKb() != 0) {
16263                    if (!isCompact) {
16264                        pw.print("     ZRAM: ");
16265                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16266                                pw.print(" physical used for ");
16267                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16268                                        - memInfo.getSwapFreeSizeKb()));
16269                                pw.print(" in swap (");
16270                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16271                                pw.println(" total swap)");
16272                    } else {
16273                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16274                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16275                                pw.println(memInfo.getSwapFreeSizeKb());
16276                    }
16277                }
16278                final long[] ksm = getKsmInfo();
16279                if (!isCompact) {
16280                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16281                            || ksm[KSM_VOLATILE] != 0) {
16282                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16283                                pw.print(" saved from shared ");
16284                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16285                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16286                                pw.print(" unshared; ");
16287                                pw.print(stringifyKBSize(
16288                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16289                    }
16290                    pw.print("   Tuning: ");
16291                    pw.print(ActivityManager.staticGetMemoryClass());
16292                    pw.print(" (large ");
16293                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16294                    pw.print("), oom ");
16295                    pw.print(stringifySize(
16296                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16297                    pw.print(", restore limit ");
16298                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16299                    if (ActivityManager.isLowRamDeviceStatic()) {
16300                        pw.print(" (low-ram)");
16301                    }
16302                    if (ActivityManager.isHighEndGfx()) {
16303                        pw.print(" (high-end-gfx)");
16304                    }
16305                    pw.println();
16306                } else {
16307                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16308                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16309                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16310                    pw.print("tuning,");
16311                    pw.print(ActivityManager.staticGetMemoryClass());
16312                    pw.print(',');
16313                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16314                    pw.print(',');
16315                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16316                    if (ActivityManager.isLowRamDeviceStatic()) {
16317                        pw.print(",low-ram");
16318                    }
16319                    if (ActivityManager.isHighEndGfx()) {
16320                        pw.print(",high-end-gfx");
16321                    }
16322                    pw.println();
16323                }
16324            }
16325        }
16326    }
16327
16328    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16329            long memtrack, String name) {
16330        sb.append("  ");
16331        sb.append(ProcessList.makeOomAdjString(oomAdj));
16332        sb.append(' ');
16333        sb.append(ProcessList.makeProcStateString(procState));
16334        sb.append(' ');
16335        ProcessList.appendRamKb(sb, pss);
16336        sb.append(": ");
16337        sb.append(name);
16338        if (memtrack > 0) {
16339            sb.append(" (");
16340            sb.append(stringifyKBSize(memtrack));
16341            sb.append(" memtrack)");
16342        }
16343    }
16344
16345    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16346        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16347        sb.append(" (pid ");
16348        sb.append(mi.pid);
16349        sb.append(") ");
16350        sb.append(mi.adjType);
16351        sb.append('\n');
16352        if (mi.adjReason != null) {
16353            sb.append("                      ");
16354            sb.append(mi.adjReason);
16355            sb.append('\n');
16356        }
16357    }
16358
16359    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16360        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16361        for (int i=0, N=memInfos.size(); i<N; i++) {
16362            ProcessMemInfo mi = memInfos.get(i);
16363            infoMap.put(mi.pid, mi);
16364        }
16365        updateCpuStatsNow();
16366        long[] memtrackTmp = new long[1];
16367        synchronized (mProcessCpuTracker) {
16368            final int N = mProcessCpuTracker.countStats();
16369            for (int i=0; i<N; i++) {
16370                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16371                if (st.vsize > 0) {
16372                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16373                    if (pss > 0) {
16374                        if (infoMap.indexOfKey(st.pid) < 0) {
16375                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16376                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16377                            mi.pss = pss;
16378                            mi.memtrack = memtrackTmp[0];
16379                            memInfos.add(mi);
16380                        }
16381                    }
16382                }
16383            }
16384        }
16385
16386        long totalPss = 0;
16387        long totalMemtrack = 0;
16388        for (int i=0, N=memInfos.size(); i<N; i++) {
16389            ProcessMemInfo mi = memInfos.get(i);
16390            if (mi.pss == 0) {
16391                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16392                mi.memtrack = memtrackTmp[0];
16393            }
16394            totalPss += mi.pss;
16395            totalMemtrack += mi.memtrack;
16396        }
16397        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16398            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16399                if (lhs.oomAdj != rhs.oomAdj) {
16400                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16401                }
16402                if (lhs.pss != rhs.pss) {
16403                    return lhs.pss < rhs.pss ? 1 : -1;
16404                }
16405                return 0;
16406            }
16407        });
16408
16409        StringBuilder tag = new StringBuilder(128);
16410        StringBuilder stack = new StringBuilder(128);
16411        tag.append("Low on memory -- ");
16412        appendMemBucket(tag, totalPss, "total", false);
16413        appendMemBucket(stack, totalPss, "total", true);
16414
16415        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16416        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16417        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16418
16419        boolean firstLine = true;
16420        int lastOomAdj = Integer.MIN_VALUE;
16421        long extraNativeRam = 0;
16422        long extraNativeMemtrack = 0;
16423        long cachedPss = 0;
16424        for (int i=0, N=memInfos.size(); i<N; i++) {
16425            ProcessMemInfo mi = memInfos.get(i);
16426
16427            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16428                cachedPss += mi.pss;
16429            }
16430
16431            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16432                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16433                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16434                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16435                if (lastOomAdj != mi.oomAdj) {
16436                    lastOomAdj = mi.oomAdj;
16437                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16438                        tag.append(" / ");
16439                    }
16440                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16441                        if (firstLine) {
16442                            stack.append(":");
16443                            firstLine = false;
16444                        }
16445                        stack.append("\n\t at ");
16446                    } else {
16447                        stack.append("$");
16448                    }
16449                } else {
16450                    tag.append(" ");
16451                    stack.append("$");
16452                }
16453                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16454                    appendMemBucket(tag, mi.pss, mi.name, false);
16455                }
16456                appendMemBucket(stack, mi.pss, mi.name, true);
16457                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16458                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16459                    stack.append("(");
16460                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16461                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16462                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16463                            stack.append(":");
16464                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16465                        }
16466                    }
16467                    stack.append(")");
16468                }
16469            }
16470
16471            appendMemInfo(fullNativeBuilder, mi);
16472            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16473                // The short form only has native processes that are >= 512K.
16474                if (mi.pss >= 512) {
16475                    appendMemInfo(shortNativeBuilder, mi);
16476                } else {
16477                    extraNativeRam += mi.pss;
16478                    extraNativeMemtrack += mi.memtrack;
16479                }
16480            } else {
16481                // Short form has all other details, but if we have collected RAM
16482                // from smaller native processes let's dump a summary of that.
16483                if (extraNativeRam > 0) {
16484                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16485                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16486                    shortNativeBuilder.append('\n');
16487                    extraNativeRam = 0;
16488                }
16489                appendMemInfo(fullJavaBuilder, mi);
16490            }
16491        }
16492
16493        fullJavaBuilder.append("           ");
16494        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16495        fullJavaBuilder.append(": TOTAL");
16496        if (totalMemtrack > 0) {
16497            fullJavaBuilder.append(" (");
16498            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16499            fullJavaBuilder.append(" memtrack)");
16500        } else {
16501        }
16502        fullJavaBuilder.append("\n");
16503
16504        MemInfoReader memInfo = new MemInfoReader();
16505        memInfo.readMemInfo();
16506        final long[] infos = memInfo.getRawInfo();
16507
16508        StringBuilder memInfoBuilder = new StringBuilder(1024);
16509        Debug.getMemInfo(infos);
16510        memInfoBuilder.append("  MemInfo: ");
16511        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16512        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16513        memInfoBuilder.append(stringifyKBSize(
16514                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16515        memInfoBuilder.append(stringifyKBSize(
16516                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16517        memInfoBuilder.append(stringifyKBSize(
16518                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16519        memInfoBuilder.append("           ");
16520        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16521        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16522        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16523        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16524        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16525            memInfoBuilder.append("  ZRAM: ");
16526            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16527            memInfoBuilder.append(" RAM, ");
16528            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16529            memInfoBuilder.append(" swap total, ");
16530            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16531            memInfoBuilder.append(" swap free\n");
16532        }
16533        final long[] ksm = getKsmInfo();
16534        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16535                || ksm[KSM_VOLATILE] != 0) {
16536            memInfoBuilder.append("  KSM: ");
16537            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16538            memInfoBuilder.append(" saved from shared ");
16539            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16540            memInfoBuilder.append("\n       ");
16541            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16542            memInfoBuilder.append(" unshared; ");
16543            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16544            memInfoBuilder.append(" volatile\n");
16545        }
16546        memInfoBuilder.append("  Free RAM: ");
16547        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16548                + memInfo.getFreeSizeKb()));
16549        memInfoBuilder.append("\n");
16550        memInfoBuilder.append("  Used RAM: ");
16551        memInfoBuilder.append(stringifyKBSize(
16552                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16553        memInfoBuilder.append("\n");
16554        memInfoBuilder.append("  Lost RAM: ");
16555        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16556                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16557                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16558        memInfoBuilder.append("\n");
16559        Slog.i(TAG, "Low on memory:");
16560        Slog.i(TAG, shortNativeBuilder.toString());
16561        Slog.i(TAG, fullJavaBuilder.toString());
16562        Slog.i(TAG, memInfoBuilder.toString());
16563
16564        StringBuilder dropBuilder = new StringBuilder(1024);
16565        /*
16566        StringWriter oomSw = new StringWriter();
16567        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16568        StringWriter catSw = new StringWriter();
16569        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16570        String[] emptyArgs = new String[] { };
16571        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16572        oomPw.flush();
16573        String oomString = oomSw.toString();
16574        */
16575        dropBuilder.append("Low on memory:");
16576        dropBuilder.append(stack);
16577        dropBuilder.append('\n');
16578        dropBuilder.append(fullNativeBuilder);
16579        dropBuilder.append(fullJavaBuilder);
16580        dropBuilder.append('\n');
16581        dropBuilder.append(memInfoBuilder);
16582        dropBuilder.append('\n');
16583        /*
16584        dropBuilder.append(oomString);
16585        dropBuilder.append('\n');
16586        */
16587        StringWriter catSw = new StringWriter();
16588        synchronized (ActivityManagerService.this) {
16589            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16590            String[] emptyArgs = new String[] { };
16591            catPw.println();
16592            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16593            catPw.println();
16594            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16595                    false, null).dumpLocked();
16596            catPw.println();
16597            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16598            catPw.flush();
16599        }
16600        dropBuilder.append(catSw.toString());
16601        addErrorToDropBox("lowmem", null, "system_server", null,
16602                null, tag.toString(), dropBuilder.toString(), null, null);
16603        //Slog.i(TAG, "Sent to dropbox:");
16604        //Slog.i(TAG, dropBuilder.toString());
16605        synchronized (ActivityManagerService.this) {
16606            long now = SystemClock.uptimeMillis();
16607            if (mLastMemUsageReportTime < now) {
16608                mLastMemUsageReportTime = now;
16609            }
16610        }
16611    }
16612
16613    /**
16614     * Searches array of arguments for the specified string
16615     * @param args array of argument strings
16616     * @param value value to search for
16617     * @return true if the value is contained in the array
16618     */
16619    private static boolean scanArgs(String[] args, String value) {
16620        if (args != null) {
16621            for (String arg : args) {
16622                if (value.equals(arg)) {
16623                    return true;
16624                }
16625            }
16626        }
16627        return false;
16628    }
16629
16630    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16631            ContentProviderRecord cpr, boolean always) {
16632        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16633
16634        if (!inLaunching || always) {
16635            synchronized (cpr) {
16636                cpr.launchingApp = null;
16637                cpr.notifyAll();
16638            }
16639            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16640            String names[] = cpr.info.authority.split(";");
16641            for (int j = 0; j < names.length; j++) {
16642                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16643            }
16644        }
16645
16646        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16647            ContentProviderConnection conn = cpr.connections.get(i);
16648            if (conn.waiting) {
16649                // If this connection is waiting for the provider, then we don't
16650                // need to mess with its process unless we are always removing
16651                // or for some reason the provider is not currently launching.
16652                if (inLaunching && !always) {
16653                    continue;
16654                }
16655            }
16656            ProcessRecord capp = conn.client;
16657            conn.dead = true;
16658            if (conn.stableCount > 0) {
16659                if (!capp.persistent && capp.thread != null
16660                        && capp.pid != 0
16661                        && capp.pid != MY_PID) {
16662                    capp.kill("depends on provider "
16663                            + cpr.name.flattenToShortString()
16664                            + " in dying proc " + (proc != null ? proc.processName : "??")
16665                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16666                }
16667            } else if (capp.thread != null && conn.provider.provider != null) {
16668                try {
16669                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16670                } catch (RemoteException e) {
16671                }
16672                // In the protocol here, we don't expect the client to correctly
16673                // clean up this connection, we'll just remove it.
16674                cpr.connections.remove(i);
16675                if (conn.client.conProviders.remove(conn)) {
16676                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16677                }
16678            }
16679        }
16680
16681        if (inLaunching && always) {
16682            mLaunchingProviders.remove(cpr);
16683        }
16684        return inLaunching;
16685    }
16686
16687    /**
16688     * Main code for cleaning up a process when it has gone away.  This is
16689     * called both as a result of the process dying, or directly when stopping
16690     * a process when running in single process mode.
16691     *
16692     * @return Returns true if the given process has been restarted, so the
16693     * app that was passed in must remain on the process lists.
16694     */
16695    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16696            boolean restarting, boolean allowRestart, int index) {
16697        if (index >= 0) {
16698            removeLruProcessLocked(app);
16699            ProcessList.remove(app.pid);
16700        }
16701
16702        mProcessesToGc.remove(app);
16703        mPendingPssProcesses.remove(app);
16704
16705        // Dismiss any open dialogs.
16706        if (app.crashDialog != null && !app.forceCrashReport) {
16707            app.crashDialog.dismiss();
16708            app.crashDialog = null;
16709        }
16710        if (app.anrDialog != null) {
16711            app.anrDialog.dismiss();
16712            app.anrDialog = null;
16713        }
16714        if (app.waitDialog != null) {
16715            app.waitDialog.dismiss();
16716            app.waitDialog = null;
16717        }
16718
16719        app.crashing = false;
16720        app.notResponding = false;
16721
16722        app.resetPackageList(mProcessStats);
16723        app.unlinkDeathRecipient();
16724        app.makeInactive(mProcessStats);
16725        app.waitingToKill = null;
16726        app.forcingToForeground = null;
16727        updateProcessForegroundLocked(app, false, false);
16728        app.foregroundActivities = false;
16729        app.hasShownUi = false;
16730        app.treatLikeActivity = false;
16731        app.hasAboveClient = false;
16732        app.hasClientActivities = false;
16733
16734        mServices.killServicesLocked(app, allowRestart);
16735
16736        boolean restart = false;
16737
16738        // Remove published content providers.
16739        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16740            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16741            final boolean always = app.bad || !allowRestart;
16742            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16743            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16744                // We left the provider in the launching list, need to
16745                // restart it.
16746                restart = true;
16747            }
16748
16749            cpr.provider = null;
16750            cpr.proc = null;
16751        }
16752        app.pubProviders.clear();
16753
16754        // Take care of any launching providers waiting for this process.
16755        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16756            restart = true;
16757        }
16758
16759        // Unregister from connected content providers.
16760        if (!app.conProviders.isEmpty()) {
16761            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16762                ContentProviderConnection conn = app.conProviders.get(i);
16763                conn.provider.connections.remove(conn);
16764                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16765                        conn.provider.name);
16766            }
16767            app.conProviders.clear();
16768        }
16769
16770        // At this point there may be remaining entries in mLaunchingProviders
16771        // where we were the only one waiting, so they are no longer of use.
16772        // Look for these and clean up if found.
16773        // XXX Commented out for now.  Trying to figure out a way to reproduce
16774        // the actual situation to identify what is actually going on.
16775        if (false) {
16776            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16777                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16778                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16779                    synchronized (cpr) {
16780                        cpr.launchingApp = null;
16781                        cpr.notifyAll();
16782                    }
16783                }
16784            }
16785        }
16786
16787        skipCurrentReceiverLocked(app);
16788
16789        // Unregister any receivers.
16790        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16791            removeReceiverLocked(app.receivers.valueAt(i));
16792        }
16793        app.receivers.clear();
16794
16795        // If the app is undergoing backup, tell the backup manager about it
16796        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16797            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16798                    + mBackupTarget.appInfo + " died during backup");
16799            try {
16800                IBackupManager bm = IBackupManager.Stub.asInterface(
16801                        ServiceManager.getService(Context.BACKUP_SERVICE));
16802                bm.agentDisconnected(app.info.packageName);
16803            } catch (RemoteException e) {
16804                // can't happen; backup manager is local
16805            }
16806        }
16807
16808        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16809            ProcessChangeItem item = mPendingProcessChanges.get(i);
16810            if (item.pid == app.pid) {
16811                mPendingProcessChanges.remove(i);
16812                mAvailProcessChanges.add(item);
16813            }
16814        }
16815        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16816                null).sendToTarget();
16817
16818        // If the caller is restarting this app, then leave it in its
16819        // current lists and let the caller take care of it.
16820        if (restarting) {
16821            return false;
16822        }
16823
16824        if (!app.persistent || app.isolated) {
16825            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16826                    "Removing non-persistent process during cleanup: " + app);
16827            removeProcessNameLocked(app.processName, app.uid);
16828            if (mHeavyWeightProcess == app) {
16829                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16830                        mHeavyWeightProcess.userId, 0));
16831                mHeavyWeightProcess = null;
16832            }
16833        } else if (!app.removed) {
16834            // This app is persistent, so we need to keep its record around.
16835            // If it is not already on the pending app list, add it there
16836            // and start a new process for it.
16837            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16838                mPersistentStartingProcesses.add(app);
16839                restart = true;
16840            }
16841        }
16842        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16843                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16844        mProcessesOnHold.remove(app);
16845
16846        if (app == mHomeProcess) {
16847            mHomeProcess = null;
16848        }
16849        if (app == mPreviousProcess) {
16850            mPreviousProcess = null;
16851        }
16852
16853        if (restart && !app.isolated) {
16854            // We have components that still need to be running in the
16855            // process, so re-launch it.
16856            if (index < 0) {
16857                ProcessList.remove(app.pid);
16858            }
16859            addProcessNameLocked(app);
16860            startProcessLocked(app, "restart", app.processName);
16861            return true;
16862        } else if (app.pid > 0 && app.pid != MY_PID) {
16863            // Goodbye!
16864            boolean removed;
16865            synchronized (mPidsSelfLocked) {
16866                mPidsSelfLocked.remove(app.pid);
16867                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16868            }
16869            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16870            if (app.isolated) {
16871                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16872            }
16873            app.setPid(0);
16874        }
16875        return false;
16876    }
16877
16878    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16879        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16880            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16881            if (cpr.launchingApp == app) {
16882                return true;
16883            }
16884        }
16885        return false;
16886    }
16887
16888    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16889        // Look through the content providers we are waiting to have launched,
16890        // and if any run in this process then either schedule a restart of
16891        // the process or kill the client waiting for it if this process has
16892        // gone bad.
16893        boolean restart = false;
16894        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16895            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16896            if (cpr.launchingApp == app) {
16897                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16898                    restart = true;
16899                } else {
16900                    removeDyingProviderLocked(app, cpr, true);
16901                }
16902            }
16903        }
16904        return restart;
16905    }
16906
16907    // =========================================================
16908    // SERVICES
16909    // =========================================================
16910
16911    @Override
16912    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16913            int flags) {
16914        enforceNotIsolatedCaller("getServices");
16915        synchronized (this) {
16916            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16917        }
16918    }
16919
16920    @Override
16921    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16922        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16923        synchronized (this) {
16924            return mServices.getRunningServiceControlPanelLocked(name);
16925        }
16926    }
16927
16928    @Override
16929    public ComponentName startService(IApplicationThread caller, Intent service,
16930            String resolvedType, String callingPackage, int userId)
16931            throws TransactionTooLargeException {
16932        enforceNotIsolatedCaller("startService");
16933        // Refuse possible leaked file descriptors
16934        if (service != null && service.hasFileDescriptors() == true) {
16935            throw new IllegalArgumentException("File descriptors passed in Intent");
16936        }
16937
16938        if (callingPackage == null) {
16939            throw new IllegalArgumentException("callingPackage cannot be null");
16940        }
16941
16942        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16943                "startService: " + service + " type=" + resolvedType);
16944        synchronized(this) {
16945            final int callingPid = Binder.getCallingPid();
16946            final int callingUid = Binder.getCallingUid();
16947            final long origId = Binder.clearCallingIdentity();
16948            ComponentName res = mServices.startServiceLocked(caller, service,
16949                    resolvedType, callingPid, callingUid, callingPackage, userId);
16950            Binder.restoreCallingIdentity(origId);
16951            return res;
16952        }
16953    }
16954
16955    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16956            String callingPackage, int userId)
16957            throws TransactionTooLargeException {
16958        synchronized(this) {
16959            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16960                    "startServiceInPackage: " + service + " type=" + resolvedType);
16961            final long origId = Binder.clearCallingIdentity();
16962            ComponentName res = mServices.startServiceLocked(null, service,
16963                    resolvedType, -1, uid, callingPackage, userId);
16964            Binder.restoreCallingIdentity(origId);
16965            return res;
16966        }
16967    }
16968
16969    @Override
16970    public int stopService(IApplicationThread caller, Intent service,
16971            String resolvedType, int userId) {
16972        enforceNotIsolatedCaller("stopService");
16973        // Refuse possible leaked file descriptors
16974        if (service != null && service.hasFileDescriptors() == true) {
16975            throw new IllegalArgumentException("File descriptors passed in Intent");
16976        }
16977
16978        synchronized(this) {
16979            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16980        }
16981    }
16982
16983    @Override
16984    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16985        enforceNotIsolatedCaller("peekService");
16986        // Refuse possible leaked file descriptors
16987        if (service != null && service.hasFileDescriptors() == true) {
16988            throw new IllegalArgumentException("File descriptors passed in Intent");
16989        }
16990
16991        if (callingPackage == null) {
16992            throw new IllegalArgumentException("callingPackage cannot be null");
16993        }
16994
16995        synchronized(this) {
16996            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16997        }
16998    }
16999
17000    @Override
17001    public boolean stopServiceToken(ComponentName className, IBinder token,
17002            int startId) {
17003        synchronized(this) {
17004            return mServices.stopServiceTokenLocked(className, token, startId);
17005        }
17006    }
17007
17008    @Override
17009    public void setServiceForeground(ComponentName className, IBinder token,
17010            int id, Notification notification, int flags) {
17011        synchronized(this) {
17012            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17013        }
17014    }
17015
17016    @Override
17017    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17018            boolean requireFull, String name, String callerPackage) {
17019        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17020                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17021    }
17022
17023    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17024            String className, int flags) {
17025        boolean result = false;
17026        // For apps that don't have pre-defined UIDs, check for permission
17027        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17028            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17029                if (ActivityManager.checkUidPermission(
17030                        INTERACT_ACROSS_USERS,
17031                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17032                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17033                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17034                            + " requests FLAG_SINGLE_USER, but app does not hold "
17035                            + INTERACT_ACROSS_USERS;
17036                    Slog.w(TAG, msg);
17037                    throw new SecurityException(msg);
17038                }
17039                // Permission passed
17040                result = true;
17041            }
17042        } else if ("system".equals(componentProcessName)) {
17043            result = true;
17044        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17045            // Phone app and persistent apps are allowed to export singleuser providers.
17046            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17047                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17048        }
17049        if (DEBUG_MU) Slog.v(TAG_MU,
17050                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17051                + Integer.toHexString(flags) + ") = " + result);
17052        return result;
17053    }
17054
17055    /**
17056     * Checks to see if the caller is in the same app as the singleton
17057     * component, or the component is in a special app. It allows special apps
17058     * to export singleton components but prevents exporting singleton
17059     * components for regular apps.
17060     */
17061    boolean isValidSingletonCall(int callingUid, int componentUid) {
17062        int componentAppId = UserHandle.getAppId(componentUid);
17063        return UserHandle.isSameApp(callingUid, componentUid)
17064                || componentAppId == Process.SYSTEM_UID
17065                || componentAppId == Process.PHONE_UID
17066                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17067                        == PackageManager.PERMISSION_GRANTED;
17068    }
17069
17070    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17071            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17072            int userId) throws TransactionTooLargeException {
17073        enforceNotIsolatedCaller("bindService");
17074
17075        // Refuse possible leaked file descriptors
17076        if (service != null && service.hasFileDescriptors() == true) {
17077            throw new IllegalArgumentException("File descriptors passed in Intent");
17078        }
17079
17080        if (callingPackage == null) {
17081            throw new IllegalArgumentException("callingPackage cannot be null");
17082        }
17083
17084        synchronized(this) {
17085            return mServices.bindServiceLocked(caller, token, service,
17086                    resolvedType, connection, flags, callingPackage, userId);
17087        }
17088    }
17089
17090    public boolean unbindService(IServiceConnection connection) {
17091        synchronized (this) {
17092            return mServices.unbindServiceLocked(connection);
17093        }
17094    }
17095
17096    public void publishService(IBinder token, Intent intent, IBinder service) {
17097        // Refuse possible leaked file descriptors
17098        if (intent != null && intent.hasFileDescriptors() == true) {
17099            throw new IllegalArgumentException("File descriptors passed in Intent");
17100        }
17101
17102        synchronized(this) {
17103            if (!(token instanceof ServiceRecord)) {
17104                throw new IllegalArgumentException("Invalid service token");
17105            }
17106            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17107        }
17108    }
17109
17110    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17111        // Refuse possible leaked file descriptors
17112        if (intent != null && intent.hasFileDescriptors() == true) {
17113            throw new IllegalArgumentException("File descriptors passed in Intent");
17114        }
17115
17116        synchronized(this) {
17117            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17118        }
17119    }
17120
17121    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17122        synchronized(this) {
17123            if (!(token instanceof ServiceRecord)) {
17124                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17125                throw new IllegalArgumentException("Invalid service token");
17126            }
17127            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17128        }
17129    }
17130
17131    // =========================================================
17132    // BACKUP AND RESTORE
17133    // =========================================================
17134
17135    // Cause the target app to be launched if necessary and its backup agent
17136    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17137    // activity manager to announce its creation.
17138    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17139        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17140        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17141
17142        IPackageManager pm = AppGlobals.getPackageManager();
17143        ApplicationInfo app = null;
17144        try {
17145            app = pm.getApplicationInfo(packageName, 0, userId);
17146        } catch (RemoteException e) {
17147            // can't happen; package manager is process-local
17148        }
17149        if (app == null) {
17150            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17151            return false;
17152        }
17153
17154        synchronized(this) {
17155            // !!! TODO: currently no check here that we're already bound
17156            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17157            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17158            synchronized (stats) {
17159                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17160            }
17161
17162            // Backup agent is now in use, its package can't be stopped.
17163            try {
17164                AppGlobals.getPackageManager().setPackageStoppedState(
17165                        app.packageName, false, UserHandle.getUserId(app.uid));
17166            } catch (RemoteException e) {
17167            } catch (IllegalArgumentException e) {
17168                Slog.w(TAG, "Failed trying to unstop package "
17169                        + app.packageName + ": " + e);
17170            }
17171
17172            BackupRecord r = new BackupRecord(ss, app, backupMode);
17173            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17174                    ? new ComponentName(app.packageName, app.backupAgentName)
17175                    : new ComponentName("android", "FullBackupAgent");
17176            // startProcessLocked() returns existing proc's record if it's already running
17177            ProcessRecord proc = startProcessLocked(app.processName, app,
17178                    false, 0, "backup", hostingName, false, false, false);
17179            if (proc == null) {
17180                Slog.e(TAG, "Unable to start backup agent process " + r);
17181                return false;
17182            }
17183
17184            // If the app is a regular app (uid >= 10000) and not the system server or phone
17185            // process, etc, then mark it as being in full backup so that certain calls to the
17186            // process can be blocked. This is not reset to false anywhere because we kill the
17187            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17188            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17189                proc.inFullBackup = true;
17190            }
17191            r.app = proc;
17192            mBackupTarget = r;
17193            mBackupAppName = app.packageName;
17194
17195            // Try not to kill the process during backup
17196            updateOomAdjLocked(proc);
17197
17198            // If the process is already attached, schedule the creation of the backup agent now.
17199            // If it is not yet live, this will be done when it attaches to the framework.
17200            if (proc.thread != null) {
17201                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17202                try {
17203                    proc.thread.scheduleCreateBackupAgent(app,
17204                            compatibilityInfoForPackageLocked(app), backupMode);
17205                } catch (RemoteException e) {
17206                    // Will time out on the backup manager side
17207                }
17208            } else {
17209                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17210            }
17211            // Invariants: at this point, the target app process exists and the application
17212            // is either already running or in the process of coming up.  mBackupTarget and
17213            // mBackupAppName describe the app, so that when it binds back to the AM we
17214            // know that it's scheduled for a backup-agent operation.
17215        }
17216
17217        return true;
17218    }
17219
17220    @Override
17221    public void clearPendingBackup() {
17222        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17223        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17224
17225        synchronized (this) {
17226            mBackupTarget = null;
17227            mBackupAppName = null;
17228        }
17229    }
17230
17231    // A backup agent has just come up
17232    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17233        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17234                + " = " + agent);
17235
17236        synchronized(this) {
17237            if (!agentPackageName.equals(mBackupAppName)) {
17238                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17239                return;
17240            }
17241        }
17242
17243        long oldIdent = Binder.clearCallingIdentity();
17244        try {
17245            IBackupManager bm = IBackupManager.Stub.asInterface(
17246                    ServiceManager.getService(Context.BACKUP_SERVICE));
17247            bm.agentConnected(agentPackageName, agent);
17248        } catch (RemoteException e) {
17249            // can't happen; the backup manager service is local
17250        } catch (Exception e) {
17251            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17252            e.printStackTrace();
17253        } finally {
17254            Binder.restoreCallingIdentity(oldIdent);
17255        }
17256    }
17257
17258    // done with this agent
17259    public void unbindBackupAgent(ApplicationInfo appInfo) {
17260        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17261        if (appInfo == null) {
17262            Slog.w(TAG, "unbind backup agent for null app");
17263            return;
17264        }
17265
17266        synchronized(this) {
17267            try {
17268                if (mBackupAppName == null) {
17269                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17270                    return;
17271                }
17272
17273                if (!mBackupAppName.equals(appInfo.packageName)) {
17274                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17275                    return;
17276                }
17277
17278                // Not backing this app up any more; reset its OOM adjustment
17279                final ProcessRecord proc = mBackupTarget.app;
17280                updateOomAdjLocked(proc);
17281
17282                // If the app crashed during backup, 'thread' will be null here
17283                if (proc.thread != null) {
17284                    try {
17285                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17286                                compatibilityInfoForPackageLocked(appInfo));
17287                    } catch (Exception e) {
17288                        Slog.e(TAG, "Exception when unbinding backup agent:");
17289                        e.printStackTrace();
17290                    }
17291                }
17292            } finally {
17293                mBackupTarget = null;
17294                mBackupAppName = null;
17295            }
17296        }
17297    }
17298    // =========================================================
17299    // BROADCASTS
17300    // =========================================================
17301
17302    boolean isPendingBroadcastProcessLocked(int pid) {
17303        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17304                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17305    }
17306
17307    void skipPendingBroadcastLocked(int pid) {
17308            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17309            for (BroadcastQueue queue : mBroadcastQueues) {
17310                queue.skipPendingBroadcastLocked(pid);
17311            }
17312    }
17313
17314    // The app just attached; send any pending broadcasts that it should receive
17315    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17316        boolean didSomething = false;
17317        for (BroadcastQueue queue : mBroadcastQueues) {
17318            didSomething |= queue.sendPendingBroadcastsLocked(app);
17319        }
17320        return didSomething;
17321    }
17322
17323    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17324            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17325        enforceNotIsolatedCaller("registerReceiver");
17326        ArrayList<Intent> stickyIntents = null;
17327        ProcessRecord callerApp = null;
17328        int callingUid;
17329        int callingPid;
17330        synchronized(this) {
17331            if (caller != null) {
17332                callerApp = getRecordForAppLocked(caller);
17333                if (callerApp == null) {
17334                    throw new SecurityException(
17335                            "Unable to find app for caller " + caller
17336                            + " (pid=" + Binder.getCallingPid()
17337                            + ") when registering receiver " + receiver);
17338                }
17339                if (callerApp.info.uid != Process.SYSTEM_UID &&
17340                        !callerApp.pkgList.containsKey(callerPackage) &&
17341                        !"android".equals(callerPackage)) {
17342                    throw new SecurityException("Given caller package " + callerPackage
17343                            + " is not running in process " + callerApp);
17344                }
17345                callingUid = callerApp.info.uid;
17346                callingPid = callerApp.pid;
17347            } else {
17348                callerPackage = null;
17349                callingUid = Binder.getCallingUid();
17350                callingPid = Binder.getCallingPid();
17351            }
17352
17353            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17354                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17355
17356            Iterator<String> actions = filter.actionsIterator();
17357            if (actions == null) {
17358                ArrayList<String> noAction = new ArrayList<String>(1);
17359                noAction.add(null);
17360                actions = noAction.iterator();
17361            }
17362
17363            // Collect stickies of users
17364            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17365            while (actions.hasNext()) {
17366                String action = actions.next();
17367                for (int id : userIds) {
17368                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17369                    if (stickies != null) {
17370                        ArrayList<Intent> intents = stickies.get(action);
17371                        if (intents != null) {
17372                            if (stickyIntents == null) {
17373                                stickyIntents = new ArrayList<Intent>();
17374                            }
17375                            stickyIntents.addAll(intents);
17376                        }
17377                    }
17378                }
17379            }
17380        }
17381
17382        ArrayList<Intent> allSticky = null;
17383        if (stickyIntents != null) {
17384            final ContentResolver resolver = mContext.getContentResolver();
17385            // Look for any matching sticky broadcasts...
17386            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17387                Intent intent = stickyIntents.get(i);
17388                // If intent has scheme "content", it will need to acccess
17389                // provider that needs to lock mProviderMap in ActivityThread
17390                // and also it may need to wait application response, so we
17391                // cannot lock ActivityManagerService here.
17392                if (filter.match(resolver, intent, true, TAG) >= 0) {
17393                    if (allSticky == null) {
17394                        allSticky = new ArrayList<Intent>();
17395                    }
17396                    allSticky.add(intent);
17397                }
17398            }
17399        }
17400
17401        // The first sticky in the list is returned directly back to the client.
17402        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17403        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17404        if (receiver == null) {
17405            return sticky;
17406        }
17407
17408        synchronized (this) {
17409            if (callerApp != null && (callerApp.thread == null
17410                    || callerApp.thread.asBinder() != caller.asBinder())) {
17411                // Original caller already died
17412                return null;
17413            }
17414            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17415            if (rl == null) {
17416                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17417                        userId, receiver);
17418                if (rl.app != null) {
17419                    rl.app.receivers.add(rl);
17420                } else {
17421                    try {
17422                        receiver.asBinder().linkToDeath(rl, 0);
17423                    } catch (RemoteException e) {
17424                        return sticky;
17425                    }
17426                    rl.linkedToDeath = true;
17427                }
17428                mRegisteredReceivers.put(receiver.asBinder(), rl);
17429            } else if (rl.uid != callingUid) {
17430                throw new IllegalArgumentException(
17431                        "Receiver requested to register for uid " + callingUid
17432                        + " was previously registered for uid " + rl.uid);
17433            } else if (rl.pid != callingPid) {
17434                throw new IllegalArgumentException(
17435                        "Receiver requested to register for pid " + callingPid
17436                        + " was previously registered for pid " + rl.pid);
17437            } else if (rl.userId != userId) {
17438                throw new IllegalArgumentException(
17439                        "Receiver requested to register for user " + userId
17440                        + " was previously registered for user " + rl.userId);
17441            }
17442            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17443                    permission, callingUid, userId);
17444            rl.add(bf);
17445            if (!bf.debugCheck()) {
17446                Slog.w(TAG, "==> For Dynamic broadcast");
17447            }
17448            mReceiverResolver.addFilter(bf);
17449
17450            // Enqueue broadcasts for all existing stickies that match
17451            // this filter.
17452            if (allSticky != null) {
17453                ArrayList receivers = new ArrayList();
17454                receivers.add(bf);
17455
17456                final int stickyCount = allSticky.size();
17457                for (int i = 0; i < stickyCount; i++) {
17458                    Intent intent = allSticky.get(i);
17459                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17460                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17461                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17462                            null, 0, null, null, false, true, true, -1);
17463                    queue.enqueueParallelBroadcastLocked(r);
17464                    queue.scheduleBroadcastsLocked();
17465                }
17466            }
17467
17468            return sticky;
17469        }
17470    }
17471
17472    public void unregisterReceiver(IIntentReceiver receiver) {
17473        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17474
17475        final long origId = Binder.clearCallingIdentity();
17476        try {
17477            boolean doTrim = false;
17478
17479            synchronized(this) {
17480                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17481                if (rl != null) {
17482                    final BroadcastRecord r = rl.curBroadcast;
17483                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17484                        final boolean doNext = r.queue.finishReceiverLocked(
17485                                r, r.resultCode, r.resultData, r.resultExtras,
17486                                r.resultAbort, false);
17487                        if (doNext) {
17488                            doTrim = true;
17489                            r.queue.processNextBroadcast(false);
17490                        }
17491                    }
17492
17493                    if (rl.app != null) {
17494                        rl.app.receivers.remove(rl);
17495                    }
17496                    removeReceiverLocked(rl);
17497                    if (rl.linkedToDeath) {
17498                        rl.linkedToDeath = false;
17499                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17500                    }
17501                }
17502            }
17503
17504            // If we actually concluded any broadcasts, we might now be able
17505            // to trim the recipients' apps from our working set
17506            if (doTrim) {
17507                trimApplications();
17508                return;
17509            }
17510
17511        } finally {
17512            Binder.restoreCallingIdentity(origId);
17513        }
17514    }
17515
17516    void removeReceiverLocked(ReceiverList rl) {
17517        mRegisteredReceivers.remove(rl.receiver.asBinder());
17518        for (int i = rl.size() - 1; i >= 0; i--) {
17519            mReceiverResolver.removeFilter(rl.get(i));
17520        }
17521    }
17522
17523    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17524        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17525            ProcessRecord r = mLruProcesses.get(i);
17526            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17527                try {
17528                    r.thread.dispatchPackageBroadcast(cmd, packages);
17529                } catch (RemoteException ex) {
17530                }
17531            }
17532        }
17533    }
17534
17535    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17536            int callingUid, int[] users) {
17537        // TODO: come back and remove this assumption to triage all broadcasts
17538        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17539
17540        List<ResolveInfo> receivers = null;
17541        try {
17542            HashSet<ComponentName> singleUserReceivers = null;
17543            boolean scannedFirstReceivers = false;
17544            for (int user : users) {
17545                // Skip users that have Shell restrictions, with exception of always permitted
17546                // Shell broadcasts
17547                if (callingUid == Process.SHELL_UID
17548                        && mUserController.hasUserRestriction(
17549                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17550                        && !isPermittedShellBroadcast(intent)) {
17551                    continue;
17552                }
17553                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17554                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17555                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17556                    // If this is not the system user, we need to check for
17557                    // any receivers that should be filtered out.
17558                    for (int i=0; i<newReceivers.size(); i++) {
17559                        ResolveInfo ri = newReceivers.get(i);
17560                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17561                            newReceivers.remove(i);
17562                            i--;
17563                        }
17564                    }
17565                }
17566                if (newReceivers != null && newReceivers.size() == 0) {
17567                    newReceivers = null;
17568                }
17569                if (receivers == null) {
17570                    receivers = newReceivers;
17571                } else if (newReceivers != null) {
17572                    // We need to concatenate the additional receivers
17573                    // found with what we have do far.  This would be easy,
17574                    // but we also need to de-dup any receivers that are
17575                    // singleUser.
17576                    if (!scannedFirstReceivers) {
17577                        // Collect any single user receivers we had already retrieved.
17578                        scannedFirstReceivers = true;
17579                        for (int i=0; i<receivers.size(); i++) {
17580                            ResolveInfo ri = receivers.get(i);
17581                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17582                                ComponentName cn = new ComponentName(
17583                                        ri.activityInfo.packageName, ri.activityInfo.name);
17584                                if (singleUserReceivers == null) {
17585                                    singleUserReceivers = new HashSet<ComponentName>();
17586                                }
17587                                singleUserReceivers.add(cn);
17588                            }
17589                        }
17590                    }
17591                    // Add the new results to the existing results, tracking
17592                    // and de-dupping single user receivers.
17593                    for (int i=0; i<newReceivers.size(); i++) {
17594                        ResolveInfo ri = newReceivers.get(i);
17595                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17596                            ComponentName cn = new ComponentName(
17597                                    ri.activityInfo.packageName, ri.activityInfo.name);
17598                            if (singleUserReceivers == null) {
17599                                singleUserReceivers = new HashSet<ComponentName>();
17600                            }
17601                            if (!singleUserReceivers.contains(cn)) {
17602                                singleUserReceivers.add(cn);
17603                                receivers.add(ri);
17604                            }
17605                        } else {
17606                            receivers.add(ri);
17607                        }
17608                    }
17609                }
17610            }
17611        } catch (RemoteException ex) {
17612            // pm is in same process, this will never happen.
17613        }
17614        return receivers;
17615    }
17616
17617    private boolean isPermittedShellBroadcast(Intent intent) {
17618        // remote bugreport should always be allowed to be taken
17619        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17620    }
17621
17622    final int broadcastIntentLocked(ProcessRecord callerApp,
17623            String callerPackage, Intent intent, String resolvedType,
17624            IIntentReceiver resultTo, int resultCode, String resultData,
17625            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17626            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17627        intent = new Intent(intent);
17628
17629        // By default broadcasts do not go to stopped apps.
17630        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17631
17632        // If we have not finished booting, don't allow this to launch new processes.
17633        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17634            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17635        }
17636
17637        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17638                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17639                + " ordered=" + ordered + " userid=" + userId);
17640        if ((resultTo != null) && !ordered) {
17641            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17642        }
17643
17644        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17645                ALLOW_NON_FULL, "broadcast", callerPackage);
17646
17647        // Make sure that the user who is receiving this broadcast is running.
17648        // If not, we will just skip it. Make an exception for shutdown broadcasts
17649        // and upgrade steps.
17650
17651        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17652            if ((callingUid != Process.SYSTEM_UID
17653                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17654                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17655                Slog.w(TAG, "Skipping broadcast of " + intent
17656                        + ": user " + userId + " is stopped");
17657                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17658            }
17659        }
17660
17661        BroadcastOptions brOptions = null;
17662        if (bOptions != null) {
17663            brOptions = new BroadcastOptions(bOptions);
17664            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17665                // See if the caller is allowed to do this.  Note we are checking against
17666                // the actual real caller (not whoever provided the operation as say a
17667                // PendingIntent), because that who is actually supplied the arguments.
17668                if (checkComponentPermission(
17669                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17670                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17671                        != PackageManager.PERMISSION_GRANTED) {
17672                    String msg = "Permission Denial: " + intent.getAction()
17673                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17674                            + ", uid=" + callingUid + ")"
17675                            + " requires "
17676                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17677                    Slog.w(TAG, msg);
17678                    throw new SecurityException(msg);
17679                }
17680            }
17681        }
17682
17683        // Verify that protected broadcasts are only being sent by system code,
17684        // and that system code is only sending protected broadcasts.
17685        final String action = intent.getAction();
17686        final boolean isProtectedBroadcast;
17687        try {
17688            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17689        } catch (RemoteException e) {
17690            Slog.w(TAG, "Remote exception", e);
17691            return ActivityManager.BROADCAST_SUCCESS;
17692        }
17693
17694        final boolean isCallerSystem;
17695        switch (UserHandle.getAppId(callingUid)) {
17696            case Process.ROOT_UID:
17697            case Process.SYSTEM_UID:
17698            case Process.PHONE_UID:
17699            case Process.BLUETOOTH_UID:
17700            case Process.NFC_UID:
17701                isCallerSystem = true;
17702                break;
17703            default:
17704                isCallerSystem = (callerApp != null) && callerApp.persistent;
17705                break;
17706        }
17707
17708        if (isCallerSystem) {
17709            if (isProtectedBroadcast
17710                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17711                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17712                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17713                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17714                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17715                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17716                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17717                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17718                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17719                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17720                // Broadcast is either protected, or it's a public action that
17721                // we've relaxed, so it's fine for system internals to send.
17722            } else {
17723                // The vast majority of broadcasts sent from system internals
17724                // should be protected to avoid security holes, so yell loudly
17725                // to ensure we examine these cases.
17726                if (callerApp != null) {
17727                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17728                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17729                            new Throwable());
17730                } else {
17731                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17732                            + " from system uid " + UserHandle.formatUid(callingUid)
17733                            + " pkg " + callerPackage,
17734                            new Throwable());
17735                }
17736            }
17737
17738        } else {
17739            if (isProtectedBroadcast) {
17740                String msg = "Permission Denial: not allowed to send broadcast "
17741                        + action + " from pid="
17742                        + callingPid + ", uid=" + callingUid;
17743                Slog.w(TAG, msg);
17744                throw new SecurityException(msg);
17745
17746            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17747                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17748                // Special case for compatibility: we don't want apps to send this,
17749                // but historically it has not been protected and apps may be using it
17750                // to poke their own app widget.  So, instead of making it protected,
17751                // just limit it to the caller.
17752                if (callerPackage == null) {
17753                    String msg = "Permission Denial: not allowed to send broadcast "
17754                            + action + " from unknown caller.";
17755                    Slog.w(TAG, msg);
17756                    throw new SecurityException(msg);
17757                } else if (intent.getComponent() != null) {
17758                    // They are good enough to send to an explicit component...  verify
17759                    // it is being sent to the calling app.
17760                    if (!intent.getComponent().getPackageName().equals(
17761                            callerPackage)) {
17762                        String msg = "Permission Denial: not allowed to send broadcast "
17763                                + action + " to "
17764                                + intent.getComponent().getPackageName() + " from "
17765                                + callerPackage;
17766                        Slog.w(TAG, msg);
17767                        throw new SecurityException(msg);
17768                    }
17769                } else {
17770                    // Limit broadcast to their own package.
17771                    intent.setPackage(callerPackage);
17772                }
17773            }
17774        }
17775
17776        if (action != null) {
17777            switch (action) {
17778                case Intent.ACTION_UID_REMOVED:
17779                case Intent.ACTION_PACKAGE_REMOVED:
17780                case Intent.ACTION_PACKAGE_CHANGED:
17781                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17782                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17783                case Intent.ACTION_PACKAGES_SUSPENDED:
17784                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17785                    // Handle special intents: if this broadcast is from the package
17786                    // manager about a package being removed, we need to remove all of
17787                    // its activities from the history stack.
17788                    if (checkComponentPermission(
17789                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17790                            callingPid, callingUid, -1, true)
17791                            != PackageManager.PERMISSION_GRANTED) {
17792                        String msg = "Permission Denial: " + intent.getAction()
17793                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17794                                + ", uid=" + callingUid + ")"
17795                                + " requires "
17796                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17797                        Slog.w(TAG, msg);
17798                        throw new SecurityException(msg);
17799                    }
17800                    switch (action) {
17801                        case Intent.ACTION_UID_REMOVED:
17802                            final Bundle intentExtras = intent.getExtras();
17803                            final int uid = intentExtras != null
17804                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17805                            if (uid >= 0) {
17806                                mBatteryStatsService.removeUid(uid);
17807                                mAppOpsService.uidRemoved(uid);
17808                            }
17809                            break;
17810                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17811                            // If resources are unavailable just force stop all those packages
17812                            // and flush the attribute cache as well.
17813                            String list[] =
17814                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17815                            if (list != null && list.length > 0) {
17816                                for (int i = 0; i < list.length; i++) {
17817                                    forceStopPackageLocked(list[i], -1, false, true, true,
17818                                            false, false, userId, "storage unmount");
17819                                }
17820                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17821                                sendPackageBroadcastLocked(
17822                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17823                                        userId);
17824                            }
17825                            break;
17826                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17827                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17828                            break;
17829                        case Intent.ACTION_PACKAGE_REMOVED:
17830                        case Intent.ACTION_PACKAGE_CHANGED:
17831                            Uri data = intent.getData();
17832                            String ssp;
17833                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17834                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17835                                final boolean replacing =
17836                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17837                                final boolean killProcess =
17838                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17839                                final boolean fullUninstall = removed && !replacing;
17840                                if (removed) {
17841                                    if (killProcess) {
17842                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17843                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17844                                                false, true, true, false, fullUninstall, userId,
17845                                                removed ? "pkg removed" : "pkg changed");
17846                                    }
17847                                    final int cmd = killProcess
17848                                            ? IApplicationThread.PACKAGE_REMOVED
17849                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17850                                    sendPackageBroadcastLocked(cmd,
17851                                            new String[] {ssp}, userId);
17852                                    if (fullUninstall) {
17853                                        mAppOpsService.packageRemoved(
17854                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17855
17856                                        // Remove all permissions granted from/to this package
17857                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17858
17859                                        removeTasksByPackageNameLocked(ssp, userId);
17860
17861                                        // Hide the "unsupported display" dialog if necessary.
17862                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17863                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17864                                            mUnsupportedDisplaySizeDialog.dismiss();
17865                                            mUnsupportedDisplaySizeDialog = null;
17866                                        }
17867                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17868                                        mBatteryStatsService.notePackageUninstalled(ssp);
17869                                    }
17870                                } else {
17871                                    if (killProcess) {
17872                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17873                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17874                                                userId, ProcessList.INVALID_ADJ,
17875                                                false, true, true, false, "change " + ssp);
17876                                    }
17877                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17878                                            intent.getStringArrayExtra(
17879                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17880                                }
17881                            }
17882                            break;
17883                        case Intent.ACTION_PACKAGES_SUSPENDED:
17884                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17885                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17886                                    intent.getAction());
17887                            final String[] packageNames = intent.getStringArrayExtra(
17888                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17889                            final int userHandle = intent.getIntExtra(
17890                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17891
17892                            synchronized(ActivityManagerService.this) {
17893                                mRecentTasks.onPackagesSuspendedChanged(
17894                                        packageNames, suspended, userHandle);
17895                            }
17896                            break;
17897                    }
17898                    break;
17899                case Intent.ACTION_PACKAGE_REPLACED:
17900                {
17901                    final Uri data = intent.getData();
17902                    final String ssp;
17903                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17904                        final ApplicationInfo aInfo =
17905                                getPackageManagerInternalLocked().getApplicationInfo(
17906                                        ssp,
17907                                        userId);
17908                        if (aInfo == null) {
17909                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17910                                    + " ssp=" + ssp + " data=" + data);
17911                            return ActivityManager.BROADCAST_SUCCESS;
17912                        }
17913                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17914                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17915                                new String[] {ssp}, userId);
17916                    }
17917                    break;
17918                }
17919                case Intent.ACTION_PACKAGE_ADDED:
17920                {
17921                    // Special case for adding a package: by default turn on compatibility mode.
17922                    Uri data = intent.getData();
17923                    String ssp;
17924                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17925                        final boolean replacing =
17926                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17927                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17928
17929                        try {
17930                            ApplicationInfo ai = AppGlobals.getPackageManager().
17931                                    getApplicationInfo(ssp, 0, 0);
17932                            mBatteryStatsService.notePackageInstalled(ssp,
17933                                    ai != null ? ai.versionCode : 0);
17934                        } catch (RemoteException e) {
17935                        }
17936                    }
17937                    break;
17938                }
17939                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17940                {
17941                    Uri data = intent.getData();
17942                    String ssp;
17943                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17944                        // Hide the "unsupported display" dialog if necessary.
17945                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17946                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17947                            mUnsupportedDisplaySizeDialog.dismiss();
17948                            mUnsupportedDisplaySizeDialog = null;
17949                        }
17950                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
17951                    }
17952                    break;
17953                }
17954                case Intent.ACTION_TIMEZONE_CHANGED:
17955                    // If this is the time zone changed action, queue up a message that will reset
17956                    // the timezone of all currently running processes. This message will get
17957                    // queued up before the broadcast happens.
17958                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17959                    break;
17960                case Intent.ACTION_TIME_CHANGED:
17961                    // If the user set the time, let all running processes know.
17962                    final int is24Hour =
17963                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17964                                    : 0;
17965                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17966                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17967                    synchronized (stats) {
17968                        stats.noteCurrentTimeChangedLocked();
17969                    }
17970                    break;
17971                case Intent.ACTION_CLEAR_DNS_CACHE:
17972                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17973                    break;
17974                case Proxy.PROXY_CHANGE_ACTION:
17975                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17976                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17977                    break;
17978                case android.hardware.Camera.ACTION_NEW_PICTURE:
17979                case android.hardware.Camera.ACTION_NEW_VIDEO:
17980                    // These broadcasts are no longer allowed by the system, since they can
17981                    // cause significant thrashing at a crictical point (using the camera).
17982                    // Apps should use JobScehduler to monitor for media provider changes.
17983                    Slog.w(TAG, action + " no longer allowed; dropping from "
17984                            + UserHandle.formatUid(callingUid));
17985                    if (resultTo != null) {
17986                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
17987                        try {
17988                            queue.performReceiveLocked(callerApp, resultTo, intent,
17989                                    Activity.RESULT_CANCELED, null, null,
17990                                    false, false, userId);
17991                        } catch (RemoteException e) {
17992                            Slog.w(TAG, "Failure ["
17993                                    + queue.mQueueName + "] sending broadcast result of "
17994                                    + intent, e);
17995
17996                        }
17997                    }
17998                    // Lie; we don't want to crash the app.
17999                    return ActivityManager.BROADCAST_SUCCESS;
18000            }
18001        }
18002
18003        // Add to the sticky list if requested.
18004        if (sticky) {
18005            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18006                    callingPid, callingUid)
18007                    != PackageManager.PERMISSION_GRANTED) {
18008                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18009                        + callingPid + ", uid=" + callingUid
18010                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18011                Slog.w(TAG, msg);
18012                throw new SecurityException(msg);
18013            }
18014            if (requiredPermissions != null && requiredPermissions.length > 0) {
18015                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18016                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18017                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18018            }
18019            if (intent.getComponent() != null) {
18020                throw new SecurityException(
18021                        "Sticky broadcasts can't target a specific component");
18022            }
18023            // We use userId directly here, since the "all" target is maintained
18024            // as a separate set of sticky broadcasts.
18025            if (userId != UserHandle.USER_ALL) {
18026                // But first, if this is not a broadcast to all users, then
18027                // make sure it doesn't conflict with an existing broadcast to
18028                // all users.
18029                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18030                        UserHandle.USER_ALL);
18031                if (stickies != null) {
18032                    ArrayList<Intent> list = stickies.get(intent.getAction());
18033                    if (list != null) {
18034                        int N = list.size();
18035                        int i;
18036                        for (i=0; i<N; i++) {
18037                            if (intent.filterEquals(list.get(i))) {
18038                                throw new IllegalArgumentException(
18039                                        "Sticky broadcast " + intent + " for user "
18040                                        + userId + " conflicts with existing global broadcast");
18041                            }
18042                        }
18043                    }
18044                }
18045            }
18046            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18047            if (stickies == null) {
18048                stickies = new ArrayMap<>();
18049                mStickyBroadcasts.put(userId, stickies);
18050            }
18051            ArrayList<Intent> list = stickies.get(intent.getAction());
18052            if (list == null) {
18053                list = new ArrayList<>();
18054                stickies.put(intent.getAction(), list);
18055            }
18056            final int stickiesCount = list.size();
18057            int i;
18058            for (i = 0; i < stickiesCount; i++) {
18059                if (intent.filterEquals(list.get(i))) {
18060                    // This sticky already exists, replace it.
18061                    list.set(i, new Intent(intent));
18062                    break;
18063                }
18064            }
18065            if (i >= stickiesCount) {
18066                list.add(new Intent(intent));
18067            }
18068        }
18069
18070        int[] users;
18071        if (userId == UserHandle.USER_ALL) {
18072            // Caller wants broadcast to go to all started users.
18073            users = mUserController.getStartedUserArrayLocked();
18074        } else {
18075            // Caller wants broadcast to go to one specific user.
18076            users = new int[] {userId};
18077        }
18078
18079        // Figure out who all will receive this broadcast.
18080        List receivers = null;
18081        List<BroadcastFilter> registeredReceivers = null;
18082        // Need to resolve the intent to interested receivers...
18083        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18084                 == 0) {
18085            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18086        }
18087        if (intent.getComponent() == null) {
18088            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18089                // Query one target user at a time, excluding shell-restricted users
18090                for (int i = 0; i < users.length; i++) {
18091                    if (mUserController.hasUserRestriction(
18092                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18093                        continue;
18094                    }
18095                    List<BroadcastFilter> registeredReceiversForUser =
18096                            mReceiverResolver.queryIntent(intent,
18097                                    resolvedType, false, users[i]);
18098                    if (registeredReceivers == null) {
18099                        registeredReceivers = registeredReceiversForUser;
18100                    } else if (registeredReceiversForUser != null) {
18101                        registeredReceivers.addAll(registeredReceiversForUser);
18102                    }
18103                }
18104            } else {
18105                registeredReceivers = mReceiverResolver.queryIntent(intent,
18106                        resolvedType, false, userId);
18107            }
18108        }
18109
18110        final boolean replacePending =
18111                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18112
18113        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18114                + " replacePending=" + replacePending);
18115
18116        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18117        if (!ordered && NR > 0) {
18118            // If we are not serializing this broadcast, then send the
18119            // registered receivers separately so they don't wait for the
18120            // components to be launched.
18121            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18122            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18123                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18124                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18125                    resultExtras, ordered, sticky, false, userId);
18126            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18127            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18128            if (!replaced) {
18129                queue.enqueueParallelBroadcastLocked(r);
18130                queue.scheduleBroadcastsLocked();
18131            }
18132            registeredReceivers = null;
18133            NR = 0;
18134        }
18135
18136        // Merge into one list.
18137        int ir = 0;
18138        if (receivers != null) {
18139            // A special case for PACKAGE_ADDED: do not allow the package
18140            // being added to see this broadcast.  This prevents them from
18141            // using this as a back door to get run as soon as they are
18142            // installed.  Maybe in the future we want to have a special install
18143            // broadcast or such for apps, but we'd like to deliberately make
18144            // this decision.
18145            String skipPackages[] = null;
18146            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18147                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18148                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18149                Uri data = intent.getData();
18150                if (data != null) {
18151                    String pkgName = data.getSchemeSpecificPart();
18152                    if (pkgName != null) {
18153                        skipPackages = new String[] { pkgName };
18154                    }
18155                }
18156            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18157                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18158            }
18159            if (skipPackages != null && (skipPackages.length > 0)) {
18160                for (String skipPackage : skipPackages) {
18161                    if (skipPackage != null) {
18162                        int NT = receivers.size();
18163                        for (int it=0; it<NT; it++) {
18164                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18165                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18166                                receivers.remove(it);
18167                                it--;
18168                                NT--;
18169                            }
18170                        }
18171                    }
18172                }
18173            }
18174
18175            int NT = receivers != null ? receivers.size() : 0;
18176            int it = 0;
18177            ResolveInfo curt = null;
18178            BroadcastFilter curr = null;
18179            while (it < NT && ir < NR) {
18180                if (curt == null) {
18181                    curt = (ResolveInfo)receivers.get(it);
18182                }
18183                if (curr == null) {
18184                    curr = registeredReceivers.get(ir);
18185                }
18186                if (curr.getPriority() >= curt.priority) {
18187                    // Insert this broadcast record into the final list.
18188                    receivers.add(it, curr);
18189                    ir++;
18190                    curr = null;
18191                    it++;
18192                    NT++;
18193                } else {
18194                    // Skip to the next ResolveInfo in the final list.
18195                    it++;
18196                    curt = null;
18197                }
18198            }
18199        }
18200        while (ir < NR) {
18201            if (receivers == null) {
18202                receivers = new ArrayList();
18203            }
18204            receivers.add(registeredReceivers.get(ir));
18205            ir++;
18206        }
18207
18208        if ((receivers != null && receivers.size() > 0)
18209                || resultTo != null) {
18210            BroadcastQueue queue = broadcastQueueForIntent(intent);
18211            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18212                    callerPackage, callingPid, callingUid, resolvedType,
18213                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18214                    resultData, resultExtras, ordered, sticky, false, userId);
18215
18216            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18217                    + ": prev had " + queue.mOrderedBroadcasts.size());
18218            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18219                    "Enqueueing broadcast " + r.intent.getAction());
18220
18221            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18222            if (!replaced) {
18223                queue.enqueueOrderedBroadcastLocked(r);
18224                queue.scheduleBroadcastsLocked();
18225            }
18226        } else {
18227            // There was nobody interested in the broadcast, but we still want to record
18228            // that it happened.
18229            if (intent.getComponent() == null && intent.getPackage() == null
18230                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18231                // This was an implicit broadcast... let's record it for posterity.
18232                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18233            }
18234        }
18235
18236        return ActivityManager.BROADCAST_SUCCESS;
18237    }
18238
18239    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18240            int skipCount, long dispatchTime) {
18241        final long now = SystemClock.elapsedRealtime();
18242        if (mCurBroadcastStats == null ||
18243                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18244            mLastBroadcastStats = mCurBroadcastStats;
18245            if (mLastBroadcastStats != null) {
18246                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18247                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18248            }
18249            mCurBroadcastStats = new BroadcastStats();
18250        }
18251        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18252    }
18253
18254    final Intent verifyBroadcastLocked(Intent intent) {
18255        // Refuse possible leaked file descriptors
18256        if (intent != null && intent.hasFileDescriptors() == true) {
18257            throw new IllegalArgumentException("File descriptors passed in Intent");
18258        }
18259
18260        int flags = intent.getFlags();
18261
18262        if (!mProcessesReady) {
18263            // if the caller really truly claims to know what they're doing, go
18264            // ahead and allow the broadcast without launching any receivers
18265            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18266                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18267            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18268                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18269                        + " before boot completion");
18270                throw new IllegalStateException("Cannot broadcast before boot completed");
18271            }
18272        }
18273
18274        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18275            throw new IllegalArgumentException(
18276                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18277        }
18278
18279        return intent;
18280    }
18281
18282    public final int broadcastIntent(IApplicationThread caller,
18283            Intent intent, String resolvedType, IIntentReceiver resultTo,
18284            int resultCode, String resultData, Bundle resultExtras,
18285            String[] requiredPermissions, int appOp, Bundle bOptions,
18286            boolean serialized, boolean sticky, int userId) {
18287        enforceNotIsolatedCaller("broadcastIntent");
18288        synchronized(this) {
18289            intent = verifyBroadcastLocked(intent);
18290
18291            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18292            final int callingPid = Binder.getCallingPid();
18293            final int callingUid = Binder.getCallingUid();
18294            final long origId = Binder.clearCallingIdentity();
18295            int res = broadcastIntentLocked(callerApp,
18296                    callerApp != null ? callerApp.info.packageName : null,
18297                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18298                    requiredPermissions, appOp, bOptions, serialized, sticky,
18299                    callingPid, callingUid, userId);
18300            Binder.restoreCallingIdentity(origId);
18301            return res;
18302        }
18303    }
18304
18305
18306    int broadcastIntentInPackage(String packageName, int uid,
18307            Intent intent, String resolvedType, IIntentReceiver resultTo,
18308            int resultCode, String resultData, Bundle resultExtras,
18309            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18310            int userId) {
18311        synchronized(this) {
18312            intent = verifyBroadcastLocked(intent);
18313
18314            final long origId = Binder.clearCallingIdentity();
18315            String[] requiredPermissions = requiredPermission == null ? null
18316                    : new String[] {requiredPermission};
18317            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18318                    resultTo, resultCode, resultData, resultExtras,
18319                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18320                    sticky, -1, uid, userId);
18321            Binder.restoreCallingIdentity(origId);
18322            return res;
18323        }
18324    }
18325
18326    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18327        // Refuse possible leaked file descriptors
18328        if (intent != null && intent.hasFileDescriptors() == true) {
18329            throw new IllegalArgumentException("File descriptors passed in Intent");
18330        }
18331
18332        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18333                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18334
18335        synchronized(this) {
18336            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18337                    != PackageManager.PERMISSION_GRANTED) {
18338                String msg = "Permission Denial: unbroadcastIntent() from pid="
18339                        + Binder.getCallingPid()
18340                        + ", uid=" + Binder.getCallingUid()
18341                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18342                Slog.w(TAG, msg);
18343                throw new SecurityException(msg);
18344            }
18345            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18346            if (stickies != null) {
18347                ArrayList<Intent> list = stickies.get(intent.getAction());
18348                if (list != null) {
18349                    int N = list.size();
18350                    int i;
18351                    for (i=0; i<N; i++) {
18352                        if (intent.filterEquals(list.get(i))) {
18353                            list.remove(i);
18354                            break;
18355                        }
18356                    }
18357                    if (list.size() <= 0) {
18358                        stickies.remove(intent.getAction());
18359                    }
18360                }
18361                if (stickies.size() <= 0) {
18362                    mStickyBroadcasts.remove(userId);
18363                }
18364            }
18365        }
18366    }
18367
18368    void backgroundServicesFinishedLocked(int userId) {
18369        for (BroadcastQueue queue : mBroadcastQueues) {
18370            queue.backgroundServicesFinishedLocked(userId);
18371        }
18372    }
18373
18374    public void finishReceiver(IBinder who, int resultCode, String resultData,
18375            Bundle resultExtras, boolean resultAbort, int flags) {
18376        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18377
18378        // Refuse possible leaked file descriptors
18379        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18380            throw new IllegalArgumentException("File descriptors passed in Bundle");
18381        }
18382
18383        final long origId = Binder.clearCallingIdentity();
18384        try {
18385            boolean doNext = false;
18386            BroadcastRecord r;
18387
18388            synchronized(this) {
18389                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18390                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18391                r = queue.getMatchingOrderedReceiver(who);
18392                if (r != null) {
18393                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18394                        resultData, resultExtras, resultAbort, true);
18395                }
18396            }
18397
18398            if (doNext) {
18399                r.queue.processNextBroadcast(false);
18400            }
18401            trimApplications();
18402        } finally {
18403            Binder.restoreCallingIdentity(origId);
18404        }
18405    }
18406
18407    // =========================================================
18408    // INSTRUMENTATION
18409    // =========================================================
18410
18411    public boolean startInstrumentation(ComponentName className,
18412            String profileFile, int flags, Bundle arguments,
18413            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18414            int userId, String abiOverride) {
18415        enforceNotIsolatedCaller("startInstrumentation");
18416        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18417                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18418        // Refuse possible leaked file descriptors
18419        if (arguments != null && arguments.hasFileDescriptors()) {
18420            throw new IllegalArgumentException("File descriptors passed in Bundle");
18421        }
18422
18423        synchronized(this) {
18424            InstrumentationInfo ii = null;
18425            ApplicationInfo ai = null;
18426            try {
18427                ii = mContext.getPackageManager().getInstrumentationInfo(
18428                    className, STOCK_PM_FLAGS);
18429                ai = AppGlobals.getPackageManager().getApplicationInfo(
18430                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18431            } catch (PackageManager.NameNotFoundException e) {
18432            } catch (RemoteException e) {
18433            }
18434            if (ii == null) {
18435                reportStartInstrumentationFailureLocked(watcher, className,
18436                        "Unable to find instrumentation info for: " + className);
18437                return false;
18438            }
18439            if (ai == null) {
18440                reportStartInstrumentationFailureLocked(watcher, className,
18441                        "Unable to find instrumentation target package: " + ii.targetPackage);
18442                return false;
18443            }
18444            if (!ai.hasCode()) {
18445                reportStartInstrumentationFailureLocked(watcher, className,
18446                        "Instrumentation target has no code: " + ii.targetPackage);
18447                return false;
18448            }
18449
18450            int match = mContext.getPackageManager().checkSignatures(
18451                    ii.targetPackage, ii.packageName);
18452            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18453                String msg = "Permission Denial: starting instrumentation "
18454                        + className + " from pid="
18455                        + Binder.getCallingPid()
18456                        + ", uid=" + Binder.getCallingPid()
18457                        + " not allowed because package " + ii.packageName
18458                        + " does not have a signature matching the target "
18459                        + ii.targetPackage;
18460                reportStartInstrumentationFailureLocked(watcher, className, msg);
18461                throw new SecurityException(msg);
18462            }
18463
18464            final long origId = Binder.clearCallingIdentity();
18465            // Instrumentation can kill and relaunch even persistent processes
18466            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18467                    "start instr");
18468            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18469            app.instrumentationClass = className;
18470            app.instrumentationInfo = ai;
18471            app.instrumentationProfileFile = profileFile;
18472            app.instrumentationArguments = arguments;
18473            app.instrumentationWatcher = watcher;
18474            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18475            app.instrumentationResultClass = className;
18476            Binder.restoreCallingIdentity(origId);
18477        }
18478
18479        return true;
18480    }
18481
18482    /**
18483     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18484     * error to the logs, but if somebody is watching, send the report there too.  This enables
18485     * the "am" command to report errors with more information.
18486     *
18487     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18488     * @param cn The component name of the instrumentation.
18489     * @param report The error report.
18490     */
18491    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18492            ComponentName cn, String report) {
18493        Slog.w(TAG, report);
18494        if (watcher != null) {
18495            Bundle results = new Bundle();
18496            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18497            results.putString("Error", report);
18498            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18499        }
18500    }
18501
18502    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18503        if (app.instrumentationWatcher != null) {
18504            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18505                    app.instrumentationClass, resultCode, results);
18506        }
18507
18508        // Can't call out of the system process with a lock held, so post a message.
18509        if (app.instrumentationUiAutomationConnection != null) {
18510            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18511                    app.instrumentationUiAutomationConnection).sendToTarget();
18512        }
18513
18514        app.instrumentationWatcher = null;
18515        app.instrumentationUiAutomationConnection = null;
18516        app.instrumentationClass = null;
18517        app.instrumentationInfo = null;
18518        app.instrumentationProfileFile = null;
18519        app.instrumentationArguments = null;
18520
18521        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18522                "finished inst");
18523    }
18524
18525    public void finishInstrumentation(IApplicationThread target,
18526            int resultCode, Bundle results) {
18527        int userId = UserHandle.getCallingUserId();
18528        // Refuse possible leaked file descriptors
18529        if (results != null && results.hasFileDescriptors()) {
18530            throw new IllegalArgumentException("File descriptors passed in Intent");
18531        }
18532
18533        synchronized(this) {
18534            ProcessRecord app = getRecordForAppLocked(target);
18535            if (app == null) {
18536                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18537                return;
18538            }
18539            final long origId = Binder.clearCallingIdentity();
18540            finishInstrumentationLocked(app, resultCode, results);
18541            Binder.restoreCallingIdentity(origId);
18542        }
18543    }
18544
18545    // =========================================================
18546    // CONFIGURATION
18547    // =========================================================
18548
18549    public ConfigurationInfo getDeviceConfigurationInfo() {
18550        ConfigurationInfo config = new ConfigurationInfo();
18551        synchronized (this) {
18552            config.reqTouchScreen = mConfiguration.touchscreen;
18553            config.reqKeyboardType = mConfiguration.keyboard;
18554            config.reqNavigation = mConfiguration.navigation;
18555            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18556                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18557                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18558            }
18559            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18560                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18561                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18562            }
18563            config.reqGlEsVersion = GL_ES_VERSION;
18564        }
18565        return config;
18566    }
18567
18568    ActivityStack getFocusedStack() {
18569        return mStackSupervisor.getFocusedStack();
18570    }
18571
18572    @Override
18573    public int getFocusedStackId() throws RemoteException {
18574        ActivityStack focusedStack = getFocusedStack();
18575        if (focusedStack != null) {
18576            return focusedStack.getStackId();
18577        }
18578        return -1;
18579    }
18580
18581    public Configuration getConfiguration() {
18582        Configuration ci;
18583        synchronized(this) {
18584            ci = new Configuration(mConfiguration);
18585            ci.userSetLocale = false;
18586        }
18587        return ci;
18588    }
18589
18590    @Override
18591    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18592        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18593        synchronized (this) {
18594            mSuppressResizeConfigChanges = suppress;
18595        }
18596    }
18597
18598    @Override
18599    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18600        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18601        if (fromStackId == HOME_STACK_ID) {
18602            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18603        }
18604        synchronized (this) {
18605            final long origId = Binder.clearCallingIdentity();
18606            try {
18607                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18608            } finally {
18609                Binder.restoreCallingIdentity(origId);
18610            }
18611        }
18612    }
18613
18614    @Override
18615    public void updatePersistentConfiguration(Configuration values) {
18616        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18617                "updateConfiguration()");
18618        enforceWriteSettingsPermission("updateConfiguration()");
18619        if (values == null) {
18620            throw new NullPointerException("Configuration must not be null");
18621        }
18622
18623        int userId = UserHandle.getCallingUserId();
18624
18625        synchronized(this) {
18626            final long origId = Binder.clearCallingIdentity();
18627            updateConfigurationLocked(values, null, false, true, userId);
18628            Binder.restoreCallingIdentity(origId);
18629        }
18630    }
18631
18632    private void updateFontScaleIfNeeded() {
18633        final int currentUserId;
18634        synchronized(this) {
18635            currentUserId = mUserController.getCurrentUserIdLocked();
18636        }
18637        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18638                FONT_SCALE, 1.0f, currentUserId);
18639        if (mConfiguration.fontScale != scaleFactor) {
18640            final Configuration configuration = mWindowManager.computeNewConfiguration();
18641            configuration.fontScale = scaleFactor;
18642            updatePersistentConfiguration(configuration);
18643        }
18644    }
18645
18646    private void enforceWriteSettingsPermission(String func) {
18647        int uid = Binder.getCallingUid();
18648        if (uid == Process.ROOT_UID) {
18649            return;
18650        }
18651
18652        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18653                Settings.getPackageNameForUid(mContext, uid), false)) {
18654            return;
18655        }
18656
18657        String msg = "Permission Denial: " + func + " from pid="
18658                + Binder.getCallingPid()
18659                + ", uid=" + uid
18660                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18661        Slog.w(TAG, msg);
18662        throw new SecurityException(msg);
18663    }
18664
18665    public void updateConfiguration(Configuration values) {
18666        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18667                "updateConfiguration()");
18668
18669        synchronized(this) {
18670            if (values == null && mWindowManager != null) {
18671                // sentinel: fetch the current configuration from the window manager
18672                values = mWindowManager.computeNewConfiguration();
18673            }
18674
18675            if (mWindowManager != null) {
18676                mProcessList.applyDisplaySize(mWindowManager);
18677            }
18678
18679            final long origId = Binder.clearCallingIdentity();
18680            if (values != null) {
18681                Settings.System.clearConfiguration(values);
18682            }
18683            updateConfigurationLocked(values, null, false);
18684            Binder.restoreCallingIdentity(origId);
18685        }
18686    }
18687
18688    void updateUserConfigurationLocked() {
18689        Configuration configuration = new Configuration(mConfiguration);
18690        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18691                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18692        updateConfigurationLocked(configuration, null, false);
18693    }
18694
18695    boolean updateConfigurationLocked(Configuration values,
18696            ActivityRecord starting, boolean initLocale) {
18697        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18698        return updateConfigurationLocked(values, starting, initLocale, false,
18699                UserHandle.USER_NULL);
18700    }
18701
18702    // To cache the list of supported system locales
18703    private String[] mSupportedSystemLocales = null;
18704
18705    /**
18706     * Do either or both things: (1) change the current configuration, and (2)
18707     * make sure the given activity is running with the (now) current
18708     * configuration.  Returns true if the activity has been left running, or
18709     * false if <var>starting</var> is being destroyed to match the new
18710     * configuration.
18711     *
18712     * @param userId is only used when persistent parameter is set to true to persist configuration
18713     *               for that particular user
18714     */
18715    private boolean updateConfigurationLocked(Configuration values,
18716            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18717        int changes = 0;
18718
18719        if (mWindowManager != null) {
18720            mWindowManager.deferSurfaceLayout();
18721        }
18722        if (values != null) {
18723            Configuration newConfig = new Configuration(mConfiguration);
18724            changes = newConfig.updateFrom(values);
18725            if (changes != 0) {
18726                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18727                        "Updating configuration to: " + values);
18728
18729                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18730
18731                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18732                    final LocaleList locales = values.getLocales();
18733                    int bestLocaleIndex = 0;
18734                    if (locales.size() > 1) {
18735                        if (mSupportedSystemLocales == null) {
18736                            mSupportedSystemLocales =
18737                                    Resources.getSystem().getAssets().getLocales();
18738                        }
18739                        bestLocaleIndex = Math.max(0,
18740                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18741                    }
18742                    SystemProperties.set("persist.sys.locale",
18743                            locales.get(bestLocaleIndex).toLanguageTag());
18744                    LocaleList.setDefault(locales, bestLocaleIndex);
18745                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18746                            locales.get(bestLocaleIndex)));
18747                }
18748
18749                mConfigurationSeq++;
18750                if (mConfigurationSeq <= 0) {
18751                    mConfigurationSeq = 1;
18752                }
18753                newConfig.seq = mConfigurationSeq;
18754                mConfiguration = newConfig;
18755                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18756                mUsageStatsService.reportConfigurationChange(newConfig,
18757                        mUserController.getCurrentUserIdLocked());
18758                //mUsageStatsService.noteStartConfig(newConfig);
18759
18760                final Configuration configCopy = new Configuration(mConfiguration);
18761
18762                // TODO: If our config changes, should we auto dismiss any currently
18763                // showing dialogs?
18764                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18765
18766                AttributeCache ac = AttributeCache.instance();
18767                if (ac != null) {
18768                    ac.updateConfiguration(configCopy);
18769                }
18770
18771                // Make sure all resources in our process are updated
18772                // right now, so that anyone who is going to retrieve
18773                // resource values after we return will be sure to get
18774                // the new ones.  This is especially important during
18775                // boot, where the first config change needs to guarantee
18776                // all resources have that config before following boot
18777                // code is executed.
18778                mSystemThread.applyConfigurationToResources(configCopy);
18779
18780                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18781                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18782                    msg.obj = new Configuration(configCopy);
18783                    msg.arg1 = userId;
18784                    mHandler.sendMessage(msg);
18785                }
18786
18787                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18788                if (isDensityChange) {
18789                    // Reset the unsupported display size dialog.
18790                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18791
18792                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18793                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18794                }
18795
18796                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18797                    ProcessRecord app = mLruProcesses.get(i);
18798                    try {
18799                        if (app.thread != null) {
18800                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18801                                    + app.processName + " new config " + mConfiguration);
18802                            app.thread.scheduleConfigurationChanged(configCopy);
18803                        }
18804                    } catch (Exception e) {
18805                    }
18806                }
18807                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18808                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18809                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18810                        | Intent.FLAG_RECEIVER_FOREGROUND);
18811                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18812                        null, AppOpsManager.OP_NONE, null, false, false,
18813                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18814                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18815                    // Tell the shortcut manager that the system locale changed.  It needs to know
18816                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18817                    // we "push" from here, rather than having the service listen to the broadcast.
18818                    final ShortcutServiceInternal shortcutService =
18819                            LocalServices.getService(ShortcutServiceInternal.class);
18820                    if (shortcutService != null) {
18821                        shortcutService.onSystemLocaleChangedNoLock();
18822                    }
18823
18824                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18825                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18826                    if (!mProcessesReady) {
18827                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18828                    }
18829                    broadcastIntentLocked(null, null, intent,
18830                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18831                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18832                }
18833            }
18834            // Update the configuration with WM first and check if any of the stacks need to be
18835            // resized due to the configuration change. If so, resize the stacks now and do any
18836            // relaunches if necessary. This way we don't need to relaunch again below in
18837            // ensureActivityConfigurationLocked().
18838            if (mWindowManager != null) {
18839                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18840                if (resizedStacks != null) {
18841                    for (int stackId : resizedStacks) {
18842                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18843                        mStackSupervisor.resizeStackLocked(
18844                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18845                    }
18846                }
18847            }
18848        }
18849
18850        boolean kept = true;
18851        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18852        // mainStack is null during startup.
18853        if (mainStack != null) {
18854            if (changes != 0 && starting == null) {
18855                // If the configuration changed, and the caller is not already
18856                // in the process of starting an activity, then find the top
18857                // activity to check if its configuration needs to change.
18858                starting = mainStack.topRunningActivityLocked();
18859            }
18860
18861            if (starting != null) {
18862                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18863                // And we need to make sure at this point that all other activities
18864                // are made visible with the correct configuration.
18865                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18866                        !PRESERVE_WINDOWS);
18867            }
18868        }
18869        if (mWindowManager != null) {
18870            mWindowManager.continueSurfaceLayout();
18871        }
18872        return kept;
18873    }
18874
18875    /**
18876     * Decide based on the configuration whether we should shouw the ANR,
18877     * crash, etc dialogs.  The idea is that if there is no affordence to
18878     * press the on-screen buttons, or the user experience would be more
18879     * greatly impacted than the crash itself, we shouldn't show the dialog.
18880     *
18881     * A thought: SystemUI might also want to get told about this, the Power
18882     * dialog / global actions also might want different behaviors.
18883     */
18884    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18885        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18886                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18887                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18888        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
18889        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
18890                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
18891        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
18892    }
18893
18894    @Override
18895    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18896        synchronized (this) {
18897            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18898            if (srec != null) {
18899                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18900            }
18901        }
18902        return false;
18903    }
18904
18905    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18906            Intent resultData) {
18907
18908        synchronized (this) {
18909            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18910            if (r != null) {
18911                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18912            }
18913            return false;
18914        }
18915    }
18916
18917    public int getLaunchedFromUid(IBinder activityToken) {
18918        ActivityRecord srec;
18919        synchronized (this) {
18920            srec = ActivityRecord.forTokenLocked(activityToken);
18921        }
18922        if (srec == null) {
18923            return -1;
18924        }
18925        return srec.launchedFromUid;
18926    }
18927
18928    public String getLaunchedFromPackage(IBinder activityToken) {
18929        ActivityRecord srec;
18930        synchronized (this) {
18931            srec = ActivityRecord.forTokenLocked(activityToken);
18932        }
18933        if (srec == null) {
18934            return null;
18935        }
18936        return srec.launchedFromPackage;
18937    }
18938
18939    // =========================================================
18940    // LIFETIME MANAGEMENT
18941    // =========================================================
18942
18943    // Returns which broadcast queue the app is the current [or imminent] receiver
18944    // on, or 'null' if the app is not an active broadcast recipient.
18945    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18946        BroadcastRecord r = app.curReceiver;
18947        if (r != null) {
18948            return r.queue;
18949        }
18950
18951        // It's not the current receiver, but it might be starting up to become one
18952        synchronized (this) {
18953            for (BroadcastQueue queue : mBroadcastQueues) {
18954                r = queue.mPendingBroadcast;
18955                if (r != null && r.curApp == app) {
18956                    // found it; report which queue it's in
18957                    return queue;
18958                }
18959            }
18960        }
18961
18962        return null;
18963    }
18964
18965    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18966            int targetUid, ComponentName targetComponent, String targetProcess) {
18967        if (!mTrackingAssociations) {
18968            return null;
18969        }
18970        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18971                = mAssociations.get(targetUid);
18972        if (components == null) {
18973            components = new ArrayMap<>();
18974            mAssociations.put(targetUid, components);
18975        }
18976        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18977        if (sourceUids == null) {
18978            sourceUids = new SparseArray<>();
18979            components.put(targetComponent, sourceUids);
18980        }
18981        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18982        if (sourceProcesses == null) {
18983            sourceProcesses = new ArrayMap<>();
18984            sourceUids.put(sourceUid, sourceProcesses);
18985        }
18986        Association ass = sourceProcesses.get(sourceProcess);
18987        if (ass == null) {
18988            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18989                    targetProcess);
18990            sourceProcesses.put(sourceProcess, ass);
18991        }
18992        ass.mCount++;
18993        ass.mNesting++;
18994        if (ass.mNesting == 1) {
18995            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18996            ass.mLastState = sourceState;
18997        }
18998        return ass;
18999    }
19000
19001    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19002            ComponentName targetComponent) {
19003        if (!mTrackingAssociations) {
19004            return;
19005        }
19006        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19007                = mAssociations.get(targetUid);
19008        if (components == null) {
19009            return;
19010        }
19011        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19012        if (sourceUids == null) {
19013            return;
19014        }
19015        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19016        if (sourceProcesses == null) {
19017            return;
19018        }
19019        Association ass = sourceProcesses.get(sourceProcess);
19020        if (ass == null || ass.mNesting <= 0) {
19021            return;
19022        }
19023        ass.mNesting--;
19024        if (ass.mNesting == 0) {
19025            long uptime = SystemClock.uptimeMillis();
19026            ass.mTime += uptime - ass.mStartTime;
19027            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19028                    += uptime - ass.mLastStateUptime;
19029            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19030        }
19031    }
19032
19033    private void noteUidProcessState(final int uid, final int state) {
19034        mBatteryStatsService.noteUidProcessState(uid, state);
19035        if (mTrackingAssociations) {
19036            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19037                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19038                        = mAssociations.valueAt(i1);
19039                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19040                    SparseArray<ArrayMap<String, Association>> sourceUids
19041                            = targetComponents.valueAt(i2);
19042                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19043                    if (sourceProcesses != null) {
19044                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19045                            Association ass = sourceProcesses.valueAt(i4);
19046                            if (ass.mNesting >= 1) {
19047                                // currently associated
19048                                long uptime = SystemClock.uptimeMillis();
19049                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19050                                        += uptime - ass.mLastStateUptime;
19051                                ass.mLastState = state;
19052                                ass.mLastStateUptime = uptime;
19053                            }
19054                        }
19055                    }
19056                }
19057            }
19058        }
19059    }
19060
19061    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19062            boolean doingAll, long now) {
19063        if (mAdjSeq == app.adjSeq) {
19064            // This adjustment has already been computed.
19065            return app.curRawAdj;
19066        }
19067
19068        if (app.thread == null) {
19069            app.adjSeq = mAdjSeq;
19070            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19071            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19072            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19073        }
19074
19075        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19076        app.adjSource = null;
19077        app.adjTarget = null;
19078        app.empty = false;
19079        app.cached = false;
19080
19081        final int activitiesSize = app.activities.size();
19082
19083        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19084            // The max adjustment doesn't allow this app to be anything
19085            // below foreground, so it is not worth doing work for it.
19086            app.adjType = "fixed";
19087            app.adjSeq = mAdjSeq;
19088            app.curRawAdj = app.maxAdj;
19089            app.foregroundActivities = false;
19090            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19091            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19092            // System processes can do UI, and when they do we want to have
19093            // them trim their memory after the user leaves the UI.  To
19094            // facilitate this, here we need to determine whether or not it
19095            // is currently showing UI.
19096            app.systemNoUi = true;
19097            if (app == TOP_APP) {
19098                app.systemNoUi = false;
19099                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19100                app.adjType = "pers-top-activity";
19101            } else if (activitiesSize > 0) {
19102                for (int j = 0; j < activitiesSize; j++) {
19103                    final ActivityRecord r = app.activities.get(j);
19104                    if (r.visible) {
19105                        app.systemNoUi = false;
19106                    }
19107                }
19108            }
19109            if (!app.systemNoUi) {
19110                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19111            }
19112            return (app.curAdj=app.maxAdj);
19113        }
19114
19115        app.systemNoUi = false;
19116
19117        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19118
19119        // Determine the importance of the process, starting with most
19120        // important to least, and assign an appropriate OOM adjustment.
19121        int adj;
19122        int schedGroup;
19123        int procState;
19124        boolean foregroundActivities = false;
19125        BroadcastQueue queue;
19126        if (app == TOP_APP) {
19127            // The last app on the list is the foreground app.
19128            adj = ProcessList.FOREGROUND_APP_ADJ;
19129            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19130            app.adjType = "top-activity";
19131            foregroundActivities = true;
19132            procState = PROCESS_STATE_CUR_TOP;
19133        } else if (app.instrumentationClass != null) {
19134            // Don't want to kill running instrumentation.
19135            adj = ProcessList.FOREGROUND_APP_ADJ;
19136            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19137            app.adjType = "instrumentation";
19138            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19139        } else if ((queue = isReceivingBroadcast(app)) != null) {
19140            // An app that is currently receiving a broadcast also
19141            // counts as being in the foreground for OOM killer purposes.
19142            // It's placed in a sched group based on the nature of the
19143            // broadcast as reflected by which queue it's active in.
19144            adj = ProcessList.FOREGROUND_APP_ADJ;
19145            schedGroup = (queue == mFgBroadcastQueue)
19146                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19147            app.adjType = "broadcast";
19148            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19149        } else if (app.executingServices.size() > 0) {
19150            // An app that is currently executing a service callback also
19151            // counts as being in the foreground.
19152            adj = ProcessList.FOREGROUND_APP_ADJ;
19153            schedGroup = app.execServicesFg ?
19154                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19155            app.adjType = "exec-service";
19156            procState = ActivityManager.PROCESS_STATE_SERVICE;
19157            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19158        } else {
19159            // As far as we know the process is empty.  We may change our mind later.
19160            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19161            // At this point we don't actually know the adjustment.  Use the cached adj
19162            // value that the caller wants us to.
19163            adj = cachedAdj;
19164            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19165            app.cached = true;
19166            app.empty = true;
19167            app.adjType = "cch-empty";
19168        }
19169
19170        // Examine all activities if not already foreground.
19171        if (!foregroundActivities && activitiesSize > 0) {
19172            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19173            for (int j = 0; j < activitiesSize; j++) {
19174                final ActivityRecord r = app.activities.get(j);
19175                if (r.app != app) {
19176                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19177                            + " instead of expected " + app);
19178                    if (r.app == null || (r.app.uid == app.uid)) {
19179                        // Only fix things up when they look sane
19180                        r.app = app;
19181                    } else {
19182                        continue;
19183                    }
19184                }
19185                if (r.visible) {
19186                    // App has a visible activity; only upgrade adjustment.
19187                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19188                        adj = ProcessList.VISIBLE_APP_ADJ;
19189                        app.adjType = "visible";
19190                    }
19191                    if (procState > PROCESS_STATE_CUR_TOP) {
19192                        procState = PROCESS_STATE_CUR_TOP;
19193                    }
19194                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19195                    app.cached = false;
19196                    app.empty = false;
19197                    foregroundActivities = true;
19198                    if (r.task != null && minLayer > 0) {
19199                        final int layer = r.task.mLayerRank;
19200                        if (layer >= 0 && minLayer > layer) {
19201                            minLayer = layer;
19202                        }
19203                    }
19204                    break;
19205                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19206                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19207                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19208                        app.adjType = "pausing";
19209                    }
19210                    if (procState > PROCESS_STATE_CUR_TOP) {
19211                        procState = PROCESS_STATE_CUR_TOP;
19212                    }
19213                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19214                    app.cached = false;
19215                    app.empty = false;
19216                    foregroundActivities = true;
19217                } else if (r.state == ActivityState.STOPPING) {
19218                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19219                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19220                        app.adjType = "stopping";
19221                    }
19222                    // For the process state, we will at this point consider the
19223                    // process to be cached.  It will be cached either as an activity
19224                    // or empty depending on whether the activity is finishing.  We do
19225                    // this so that we can treat the process as cached for purposes of
19226                    // memory trimming (determing current memory level, trim command to
19227                    // send to process) since there can be an arbitrary number of stopping
19228                    // processes and they should soon all go into the cached state.
19229                    if (!r.finishing) {
19230                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19231                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19232                        }
19233                    }
19234                    app.cached = false;
19235                    app.empty = false;
19236                    foregroundActivities = true;
19237                } else {
19238                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19239                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19240                        app.adjType = "cch-act";
19241                    }
19242                }
19243            }
19244            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19245                adj += minLayer;
19246            }
19247        }
19248
19249        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19250                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19251            if (app.foregroundServices) {
19252                // The user is aware of this app, so make it visible.
19253                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19254                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19255                app.cached = false;
19256                app.adjType = "fg-service";
19257                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19258            } else if (app.forcingToForeground != null) {
19259                // The user is aware of this app, so make it visible.
19260                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19261                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19262                app.cached = false;
19263                app.adjType = "force-fg";
19264                app.adjSource = app.forcingToForeground;
19265                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19266            }
19267        }
19268
19269        if (app == mHeavyWeightProcess) {
19270            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19271                // We don't want to kill the current heavy-weight process.
19272                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19273                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19274                app.cached = false;
19275                app.adjType = "heavy";
19276            }
19277            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19278                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19279            }
19280        }
19281
19282        if (app == mHomeProcess) {
19283            if (adj > ProcessList.HOME_APP_ADJ) {
19284                // This process is hosting what we currently consider to be the
19285                // home app, so we don't want to let it go into the background.
19286                adj = ProcessList.HOME_APP_ADJ;
19287                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19288                app.cached = false;
19289                app.adjType = "home";
19290            }
19291            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19292                procState = ActivityManager.PROCESS_STATE_HOME;
19293            }
19294        }
19295
19296        if (app == mPreviousProcess && app.activities.size() > 0) {
19297            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19298                // This was the previous process that showed UI to the user.
19299                // We want to try to keep it around more aggressively, to give
19300                // a good experience around switching between two apps.
19301                adj = ProcessList.PREVIOUS_APP_ADJ;
19302                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19303                app.cached = false;
19304                app.adjType = "previous";
19305            }
19306            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19307                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19308            }
19309        }
19310
19311        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19312                + " reason=" + app.adjType);
19313
19314        // By default, we use the computed adjustment.  It may be changed if
19315        // there are applications dependent on our services or providers, but
19316        // this gives us a baseline and makes sure we don't get into an
19317        // infinite recursion.
19318        app.adjSeq = mAdjSeq;
19319        app.curRawAdj = adj;
19320        app.hasStartedServices = false;
19321
19322        if (mBackupTarget != null && app == mBackupTarget.app) {
19323            // If possible we want to avoid killing apps while they're being backed up
19324            if (adj > ProcessList.BACKUP_APP_ADJ) {
19325                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19326                adj = ProcessList.BACKUP_APP_ADJ;
19327                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19328                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19329                }
19330                app.adjType = "backup";
19331                app.cached = false;
19332            }
19333            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19334                procState = ActivityManager.PROCESS_STATE_BACKUP;
19335            }
19336        }
19337
19338        boolean mayBeTop = false;
19339
19340        for (int is = app.services.size()-1;
19341                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19342                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19343                        || procState > ActivityManager.PROCESS_STATE_TOP);
19344                is--) {
19345            ServiceRecord s = app.services.valueAt(is);
19346            if (s.startRequested) {
19347                app.hasStartedServices = true;
19348                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19349                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19350                }
19351                if (app.hasShownUi && app != mHomeProcess) {
19352                    // If this process has shown some UI, let it immediately
19353                    // go to the LRU list because it may be pretty heavy with
19354                    // UI stuff.  We'll tag it with a label just to help
19355                    // debug and understand what is going on.
19356                    if (adj > ProcessList.SERVICE_ADJ) {
19357                        app.adjType = "cch-started-ui-services";
19358                    }
19359                } else {
19360                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19361                        // This service has seen some activity within
19362                        // recent memory, so we will keep its process ahead
19363                        // of the background processes.
19364                        if (adj > ProcessList.SERVICE_ADJ) {
19365                            adj = ProcessList.SERVICE_ADJ;
19366                            app.adjType = "started-services";
19367                            app.cached = false;
19368                        }
19369                    }
19370                    // If we have let the service slide into the background
19371                    // state, still have some text describing what it is doing
19372                    // even though the service no longer has an impact.
19373                    if (adj > ProcessList.SERVICE_ADJ) {
19374                        app.adjType = "cch-started-services";
19375                    }
19376                }
19377            }
19378
19379            for (int conni = s.connections.size()-1;
19380                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19381                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19382                            || procState > ActivityManager.PROCESS_STATE_TOP);
19383                    conni--) {
19384                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19385                for (int i = 0;
19386                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19387                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19388                                || procState > ActivityManager.PROCESS_STATE_TOP);
19389                        i++) {
19390                    // XXX should compute this based on the max of
19391                    // all connected clients.
19392                    ConnectionRecord cr = clist.get(i);
19393                    if (cr.binding.client == app) {
19394                        // Binding to ourself is not interesting.
19395                        continue;
19396                    }
19397
19398                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19399                        ProcessRecord client = cr.binding.client;
19400                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19401                                TOP_APP, doingAll, now);
19402                        int clientProcState = client.curProcState;
19403                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19404                            // If the other app is cached for any reason, for purposes here
19405                            // we are going to consider it empty.  The specific cached state
19406                            // doesn't propagate except under certain conditions.
19407                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19408                        }
19409                        String adjType = null;
19410                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19411                            // Not doing bind OOM management, so treat
19412                            // this guy more like a started service.
19413                            if (app.hasShownUi && app != mHomeProcess) {
19414                                // If this process has shown some UI, let it immediately
19415                                // go to the LRU list because it may be pretty heavy with
19416                                // UI stuff.  We'll tag it with a label just to help
19417                                // debug and understand what is going on.
19418                                if (adj > clientAdj) {
19419                                    adjType = "cch-bound-ui-services";
19420                                }
19421                                app.cached = false;
19422                                clientAdj = adj;
19423                                clientProcState = procState;
19424                            } else {
19425                                if (now >= (s.lastActivity
19426                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19427                                    // This service has not seen activity within
19428                                    // recent memory, so allow it to drop to the
19429                                    // LRU list if there is no other reason to keep
19430                                    // it around.  We'll also tag it with a label just
19431                                    // to help debug and undertand what is going on.
19432                                    if (adj > clientAdj) {
19433                                        adjType = "cch-bound-services";
19434                                    }
19435                                    clientAdj = adj;
19436                                }
19437                            }
19438                        }
19439                        if (adj > clientAdj) {
19440                            // If this process has recently shown UI, and
19441                            // the process that is binding to it is less
19442                            // important than being visible, then we don't
19443                            // care about the binding as much as we care
19444                            // about letting this process get into the LRU
19445                            // list to be killed and restarted if needed for
19446                            // memory.
19447                            if (app.hasShownUi && app != mHomeProcess
19448                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19449                                adjType = "cch-bound-ui-services";
19450                            } else {
19451                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19452                                        |Context.BIND_IMPORTANT)) != 0) {
19453                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19454                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19455                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19456                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19457                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19458                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19459                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19460                                    adj = clientAdj;
19461                                } else {
19462                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19463                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19464                                    }
19465                                }
19466                                if (!client.cached) {
19467                                    app.cached = false;
19468                                }
19469                                adjType = "service";
19470                            }
19471                        }
19472                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19473                            // This will treat important bound services identically to
19474                            // the top app, which may behave differently than generic
19475                            // foreground work.
19476                            if (client.curSchedGroup > schedGroup) {
19477                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19478                                    schedGroup = client.curSchedGroup;
19479                                } else {
19480                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19481                                }
19482                            }
19483                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19484                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19485                                    // Special handling of clients who are in the top state.
19486                                    // We *may* want to consider this process to be in the
19487                                    // top state as well, but only if there is not another
19488                                    // reason for it to be running.  Being on the top is a
19489                                    // special state, meaning you are specifically running
19490                                    // for the current top app.  If the process is already
19491                                    // running in the background for some other reason, it
19492                                    // is more important to continue considering it to be
19493                                    // in the background state.
19494                                    mayBeTop = true;
19495                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19496                                } else {
19497                                    // Special handling for above-top states (persistent
19498                                    // processes).  These should not bring the current process
19499                                    // into the top state, since they are not on top.  Instead
19500                                    // give them the best state after that.
19501                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19502                                        clientProcState =
19503                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19504                                    } else if (mWakefulness
19505                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19506                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19507                                                    != 0) {
19508                                        clientProcState =
19509                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19510                                    } else {
19511                                        clientProcState =
19512                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19513                                    }
19514                                }
19515                            }
19516                        } else {
19517                            if (clientProcState <
19518                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19519                                clientProcState =
19520                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19521                            }
19522                        }
19523                        if (procState > clientProcState) {
19524                            procState = clientProcState;
19525                        }
19526                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19527                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19528                            app.pendingUiClean = true;
19529                        }
19530                        if (adjType != null) {
19531                            app.adjType = adjType;
19532                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19533                                    .REASON_SERVICE_IN_USE;
19534                            app.adjSource = cr.binding.client;
19535                            app.adjSourceProcState = clientProcState;
19536                            app.adjTarget = s.name;
19537                        }
19538                    }
19539                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19540                        app.treatLikeActivity = true;
19541                    }
19542                    final ActivityRecord a = cr.activity;
19543                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19544                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19545                            (a.visible || a.state == ActivityState.RESUMED ||
19546                             a.state == ActivityState.PAUSING)) {
19547                            adj = ProcessList.FOREGROUND_APP_ADJ;
19548                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19549                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19550                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19551                                } else {
19552                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19553                                }
19554                            }
19555                            app.cached = false;
19556                            app.adjType = "service";
19557                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19558                                    .REASON_SERVICE_IN_USE;
19559                            app.adjSource = a;
19560                            app.adjSourceProcState = procState;
19561                            app.adjTarget = s.name;
19562                        }
19563                    }
19564                }
19565            }
19566        }
19567
19568        for (int provi = app.pubProviders.size()-1;
19569                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19570                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19571                        || procState > ActivityManager.PROCESS_STATE_TOP);
19572                provi--) {
19573            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19574            for (int i = cpr.connections.size()-1;
19575                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19576                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19577                            || procState > ActivityManager.PROCESS_STATE_TOP);
19578                    i--) {
19579                ContentProviderConnection conn = cpr.connections.get(i);
19580                ProcessRecord client = conn.client;
19581                if (client == app) {
19582                    // Being our own client is not interesting.
19583                    continue;
19584                }
19585                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19586                int clientProcState = client.curProcState;
19587                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19588                    // If the other app is cached for any reason, for purposes here
19589                    // we are going to consider it empty.
19590                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19591                }
19592                if (adj > clientAdj) {
19593                    if (app.hasShownUi && app != mHomeProcess
19594                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19595                        app.adjType = "cch-ui-provider";
19596                    } else {
19597                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19598                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19599                        app.adjType = "provider";
19600                    }
19601                    app.cached &= client.cached;
19602                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19603                            .REASON_PROVIDER_IN_USE;
19604                    app.adjSource = client;
19605                    app.adjSourceProcState = clientProcState;
19606                    app.adjTarget = cpr.name;
19607                }
19608                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19609                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19610                        // Special handling of clients who are in the top state.
19611                        // We *may* want to consider this process to be in the
19612                        // top state as well, but only if there is not another
19613                        // reason for it to be running.  Being on the top is a
19614                        // special state, meaning you are specifically running
19615                        // for the current top app.  If the process is already
19616                        // running in the background for some other reason, it
19617                        // is more important to continue considering it to be
19618                        // in the background state.
19619                        mayBeTop = true;
19620                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19621                    } else {
19622                        // Special handling for above-top states (persistent
19623                        // processes).  These should not bring the current process
19624                        // into the top state, since they are not on top.  Instead
19625                        // give them the best state after that.
19626                        clientProcState =
19627                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19628                    }
19629                }
19630                if (procState > clientProcState) {
19631                    procState = clientProcState;
19632                }
19633                if (client.curSchedGroup > schedGroup) {
19634                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19635                }
19636            }
19637            // If the provider has external (non-framework) process
19638            // dependencies, ensure that its adjustment is at least
19639            // FOREGROUND_APP_ADJ.
19640            if (cpr.hasExternalProcessHandles()) {
19641                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19642                    adj = ProcessList.FOREGROUND_APP_ADJ;
19643                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19644                    app.cached = false;
19645                    app.adjType = "provider";
19646                    app.adjTarget = cpr.name;
19647                }
19648                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19649                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19650                }
19651            }
19652        }
19653
19654        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19655            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19656                adj = ProcessList.PREVIOUS_APP_ADJ;
19657                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19658                app.cached = false;
19659                app.adjType = "provider";
19660            }
19661            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19662                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19663            }
19664        }
19665
19666        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19667            // A client of one of our services or providers is in the top state.  We
19668            // *may* want to be in the top state, but not if we are already running in
19669            // the background for some other reason.  For the decision here, we are going
19670            // to pick out a few specific states that we want to remain in when a client
19671            // is top (states that tend to be longer-term) and otherwise allow it to go
19672            // to the top state.
19673            switch (procState) {
19674                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19675                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19676                case ActivityManager.PROCESS_STATE_SERVICE:
19677                    // These all are longer-term states, so pull them up to the top
19678                    // of the background states, but not all the way to the top state.
19679                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19680                    break;
19681                default:
19682                    // Otherwise, top is a better choice, so take it.
19683                    procState = ActivityManager.PROCESS_STATE_TOP;
19684                    break;
19685            }
19686        }
19687
19688        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19689            if (app.hasClientActivities) {
19690                // This is a cached process, but with client activities.  Mark it so.
19691                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19692                app.adjType = "cch-client-act";
19693            } else if (app.treatLikeActivity) {
19694                // This is a cached process, but somebody wants us to treat it like it has
19695                // an activity, okay!
19696                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19697                app.adjType = "cch-as-act";
19698            }
19699        }
19700
19701        if (adj == ProcessList.SERVICE_ADJ) {
19702            if (doingAll) {
19703                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19704                mNewNumServiceProcs++;
19705                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19706                if (!app.serviceb) {
19707                    // This service isn't far enough down on the LRU list to
19708                    // normally be a B service, but if we are low on RAM and it
19709                    // is large we want to force it down since we would prefer to
19710                    // keep launcher over it.
19711                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19712                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19713                        app.serviceHighRam = true;
19714                        app.serviceb = true;
19715                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19716                    } else {
19717                        mNewNumAServiceProcs++;
19718                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19719                    }
19720                } else {
19721                    app.serviceHighRam = false;
19722                }
19723            }
19724            if (app.serviceb) {
19725                adj = ProcessList.SERVICE_B_ADJ;
19726            }
19727        }
19728
19729        app.curRawAdj = adj;
19730
19731        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19732        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19733        if (adj > app.maxAdj) {
19734            adj = app.maxAdj;
19735            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19736                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19737            }
19738        }
19739
19740        // Do final modification to adj.  Everything we do between here and applying
19741        // the final setAdj must be done in this function, because we will also use
19742        // it when computing the final cached adj later.  Note that we don't need to
19743        // worry about this for max adj above, since max adj will always be used to
19744        // keep it out of the cached vaues.
19745        app.curAdj = app.modifyRawOomAdj(adj);
19746        app.curSchedGroup = schedGroup;
19747        app.curProcState = procState;
19748        app.foregroundActivities = foregroundActivities;
19749
19750        return app.curRawAdj;
19751    }
19752
19753    /**
19754     * Record new PSS sample for a process.
19755     */
19756    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19757            long now) {
19758        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19759                swapPss * 1024);
19760        proc.lastPssTime = now;
19761        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19762        if (DEBUG_PSS) Slog.d(TAG_PSS,
19763                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19764                + " state=" + ProcessList.makeProcStateString(procState));
19765        if (proc.initialIdlePss == 0) {
19766            proc.initialIdlePss = pss;
19767        }
19768        proc.lastPss = pss;
19769        proc.lastSwapPss = swapPss;
19770        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19771            proc.lastCachedPss = pss;
19772            proc.lastCachedSwapPss = swapPss;
19773        }
19774
19775        final SparseArray<Pair<Long, String>> watchUids
19776                = mMemWatchProcesses.getMap().get(proc.processName);
19777        Long check = null;
19778        if (watchUids != null) {
19779            Pair<Long, String> val = watchUids.get(proc.uid);
19780            if (val == null) {
19781                val = watchUids.get(0);
19782            }
19783            if (val != null) {
19784                check = val.first;
19785            }
19786        }
19787        if (check != null) {
19788            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19789                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19790                if (!isDebuggable) {
19791                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19792                        isDebuggable = true;
19793                    }
19794                }
19795                if (isDebuggable) {
19796                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19797                    final ProcessRecord myProc = proc;
19798                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19799                    mMemWatchDumpProcName = proc.processName;
19800                    mMemWatchDumpFile = heapdumpFile.toString();
19801                    mMemWatchDumpPid = proc.pid;
19802                    mMemWatchDumpUid = proc.uid;
19803                    BackgroundThread.getHandler().post(new Runnable() {
19804                        @Override
19805                        public void run() {
19806                            revokeUriPermission(ActivityThread.currentActivityThread()
19807                                            .getApplicationThread(),
19808                                    DumpHeapActivity.JAVA_URI,
19809                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19810                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19811                                    UserHandle.myUserId());
19812                            ParcelFileDescriptor fd = null;
19813                            try {
19814                                heapdumpFile.delete();
19815                                fd = ParcelFileDescriptor.open(heapdumpFile,
19816                                        ParcelFileDescriptor.MODE_CREATE |
19817                                                ParcelFileDescriptor.MODE_TRUNCATE |
19818                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19819                                                ParcelFileDescriptor.MODE_APPEND);
19820                                IApplicationThread thread = myProc.thread;
19821                                if (thread != null) {
19822                                    try {
19823                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19824                                                "Requesting dump heap from "
19825                                                + myProc + " to " + heapdumpFile);
19826                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19827                                    } catch (RemoteException e) {
19828                                    }
19829                                }
19830                            } catch (FileNotFoundException e) {
19831                                e.printStackTrace();
19832                            } finally {
19833                                if (fd != null) {
19834                                    try {
19835                                        fd.close();
19836                                    } catch (IOException e) {
19837                                    }
19838                                }
19839                            }
19840                        }
19841                    });
19842                } else {
19843                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19844                            + ", but debugging not enabled");
19845                }
19846            }
19847        }
19848    }
19849
19850    /**
19851     * Schedule PSS collection of a process.
19852     */
19853    void requestPssLocked(ProcessRecord proc, int procState) {
19854        if (mPendingPssProcesses.contains(proc)) {
19855            return;
19856        }
19857        if (mPendingPssProcesses.size() == 0) {
19858            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19859        }
19860        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19861        proc.pssProcState = procState;
19862        mPendingPssProcesses.add(proc);
19863    }
19864
19865    /**
19866     * Schedule PSS collection of all processes.
19867     */
19868    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19869        if (!always) {
19870            if (now < (mLastFullPssTime +
19871                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19872                return;
19873            }
19874        }
19875        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19876        mLastFullPssTime = now;
19877        mFullPssPending = true;
19878        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19879        mPendingPssProcesses.clear();
19880        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19881            ProcessRecord app = mLruProcesses.get(i);
19882            if (app.thread == null
19883                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19884                continue;
19885            }
19886            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19887                app.pssProcState = app.setProcState;
19888                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19889                        mTestPssMode, isSleepingLocked(), now);
19890                mPendingPssProcesses.add(app);
19891            }
19892        }
19893        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19894    }
19895
19896    public void setTestPssMode(boolean enabled) {
19897        synchronized (this) {
19898            mTestPssMode = enabled;
19899            if (enabled) {
19900                // Whenever we enable the mode, we want to take a snapshot all of current
19901                // process mem use.
19902                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19903            }
19904        }
19905    }
19906
19907    /**
19908     * Ask a given process to GC right now.
19909     */
19910    final void performAppGcLocked(ProcessRecord app) {
19911        try {
19912            app.lastRequestedGc = SystemClock.uptimeMillis();
19913            if (app.thread != null) {
19914                if (app.reportLowMemory) {
19915                    app.reportLowMemory = false;
19916                    app.thread.scheduleLowMemory();
19917                } else {
19918                    app.thread.processInBackground();
19919                }
19920            }
19921        } catch (Exception e) {
19922            // whatever.
19923        }
19924    }
19925
19926    /**
19927     * Returns true if things are idle enough to perform GCs.
19928     */
19929    private final boolean canGcNowLocked() {
19930        boolean processingBroadcasts = false;
19931        for (BroadcastQueue q : mBroadcastQueues) {
19932            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19933                processingBroadcasts = true;
19934            }
19935        }
19936        return !processingBroadcasts
19937                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19938    }
19939
19940    /**
19941     * Perform GCs on all processes that are waiting for it, but only
19942     * if things are idle.
19943     */
19944    final void performAppGcsLocked() {
19945        final int N = mProcessesToGc.size();
19946        if (N <= 0) {
19947            return;
19948        }
19949        if (canGcNowLocked()) {
19950            while (mProcessesToGc.size() > 0) {
19951                ProcessRecord proc = mProcessesToGc.remove(0);
19952                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19953                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19954                            <= SystemClock.uptimeMillis()) {
19955                        // To avoid spamming the system, we will GC processes one
19956                        // at a time, waiting a few seconds between each.
19957                        performAppGcLocked(proc);
19958                        scheduleAppGcsLocked();
19959                        return;
19960                    } else {
19961                        // It hasn't been long enough since we last GCed this
19962                        // process...  put it in the list to wait for its time.
19963                        addProcessToGcListLocked(proc);
19964                        break;
19965                    }
19966                }
19967            }
19968
19969            scheduleAppGcsLocked();
19970        }
19971    }
19972
19973    /**
19974     * If all looks good, perform GCs on all processes waiting for them.
19975     */
19976    final void performAppGcsIfAppropriateLocked() {
19977        if (canGcNowLocked()) {
19978            performAppGcsLocked();
19979            return;
19980        }
19981        // Still not idle, wait some more.
19982        scheduleAppGcsLocked();
19983    }
19984
19985    /**
19986     * Schedule the execution of all pending app GCs.
19987     */
19988    final void scheduleAppGcsLocked() {
19989        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19990
19991        if (mProcessesToGc.size() > 0) {
19992            // Schedule a GC for the time to the next process.
19993            ProcessRecord proc = mProcessesToGc.get(0);
19994            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19995
19996            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19997            long now = SystemClock.uptimeMillis();
19998            if (when < (now+GC_TIMEOUT)) {
19999                when = now + GC_TIMEOUT;
20000            }
20001            mHandler.sendMessageAtTime(msg, when);
20002        }
20003    }
20004
20005    /**
20006     * Add a process to the array of processes waiting to be GCed.  Keeps the
20007     * list in sorted order by the last GC time.  The process can't already be
20008     * on the list.
20009     */
20010    final void addProcessToGcListLocked(ProcessRecord proc) {
20011        boolean added = false;
20012        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20013            if (mProcessesToGc.get(i).lastRequestedGc <
20014                    proc.lastRequestedGc) {
20015                added = true;
20016                mProcessesToGc.add(i+1, proc);
20017                break;
20018            }
20019        }
20020        if (!added) {
20021            mProcessesToGc.add(0, proc);
20022        }
20023    }
20024
20025    /**
20026     * Set up to ask a process to GC itself.  This will either do it
20027     * immediately, or put it on the list of processes to gc the next
20028     * time things are idle.
20029     */
20030    final void scheduleAppGcLocked(ProcessRecord app) {
20031        long now = SystemClock.uptimeMillis();
20032        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20033            return;
20034        }
20035        if (!mProcessesToGc.contains(app)) {
20036            addProcessToGcListLocked(app);
20037            scheduleAppGcsLocked();
20038        }
20039    }
20040
20041    final void checkExcessivePowerUsageLocked(boolean doKills) {
20042        updateCpuStatsNow();
20043
20044        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20045        boolean doWakeKills = doKills;
20046        boolean doCpuKills = doKills;
20047        if (mLastPowerCheckRealtime == 0) {
20048            doWakeKills = false;
20049        }
20050        if (mLastPowerCheckUptime == 0) {
20051            doCpuKills = false;
20052        }
20053        if (stats.isScreenOn()) {
20054            doWakeKills = false;
20055        }
20056        final long curRealtime = SystemClock.elapsedRealtime();
20057        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20058        final long curUptime = SystemClock.uptimeMillis();
20059        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20060        mLastPowerCheckRealtime = curRealtime;
20061        mLastPowerCheckUptime = curUptime;
20062        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20063            doWakeKills = false;
20064        }
20065        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20066            doCpuKills = false;
20067        }
20068        int i = mLruProcesses.size();
20069        while (i > 0) {
20070            i--;
20071            ProcessRecord app = mLruProcesses.get(i);
20072            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20073                long wtime;
20074                synchronized (stats) {
20075                    wtime = stats.getProcessWakeTime(app.info.uid,
20076                            app.pid, curRealtime);
20077                }
20078                long wtimeUsed = wtime - app.lastWakeTime;
20079                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20080                if (DEBUG_POWER) {
20081                    StringBuilder sb = new StringBuilder(128);
20082                    sb.append("Wake for ");
20083                    app.toShortString(sb);
20084                    sb.append(": over ");
20085                    TimeUtils.formatDuration(realtimeSince, sb);
20086                    sb.append(" used ");
20087                    TimeUtils.formatDuration(wtimeUsed, sb);
20088                    sb.append(" (");
20089                    sb.append((wtimeUsed*100)/realtimeSince);
20090                    sb.append("%)");
20091                    Slog.i(TAG_POWER, sb.toString());
20092                    sb.setLength(0);
20093                    sb.append("CPU for ");
20094                    app.toShortString(sb);
20095                    sb.append(": over ");
20096                    TimeUtils.formatDuration(uptimeSince, sb);
20097                    sb.append(" used ");
20098                    TimeUtils.formatDuration(cputimeUsed, sb);
20099                    sb.append(" (");
20100                    sb.append((cputimeUsed*100)/uptimeSince);
20101                    sb.append("%)");
20102                    Slog.i(TAG_POWER, sb.toString());
20103                }
20104                // If a process has held a wake lock for more
20105                // than 50% of the time during this period,
20106                // that sounds bad.  Kill!
20107                if (doWakeKills && realtimeSince > 0
20108                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20109                    synchronized (stats) {
20110                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20111                                realtimeSince, wtimeUsed);
20112                    }
20113                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20114                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20115                } else if (doCpuKills && uptimeSince > 0
20116                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20117                    synchronized (stats) {
20118                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20119                                uptimeSince, cputimeUsed);
20120                    }
20121                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20122                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20123                } else {
20124                    app.lastWakeTime = wtime;
20125                    app.lastCpuTime = app.curCpuTime;
20126                }
20127            }
20128        }
20129    }
20130
20131    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20132            long nowElapsed) {
20133        boolean success = true;
20134
20135        if (app.curRawAdj != app.setRawAdj) {
20136            app.setRawAdj = app.curRawAdj;
20137        }
20138
20139        int changes = 0;
20140
20141        if (app.curAdj != app.setAdj) {
20142            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20143            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20144                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20145                    + app.adjType);
20146            app.setAdj = app.curAdj;
20147            app.verifiedAdj = ProcessList.INVALID_ADJ;
20148        }
20149
20150        if (app.setSchedGroup != app.curSchedGroup) {
20151            int oldSchedGroup = app.setSchedGroup;
20152            app.setSchedGroup = app.curSchedGroup;
20153            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20154                    "Setting sched group of " + app.processName
20155                    + " to " + app.curSchedGroup);
20156            if (app.waitingToKill != null && app.curReceiver == null
20157                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20158                app.kill(app.waitingToKill, true);
20159                success = false;
20160            } else {
20161                int processGroup;
20162                switch (app.curSchedGroup) {
20163                    case ProcessList.SCHED_GROUP_BACKGROUND:
20164                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20165                        break;
20166                    case ProcessList.SCHED_GROUP_TOP_APP:
20167                        processGroup = Process.THREAD_GROUP_TOP_APP;
20168                        break;
20169                    default:
20170                        processGroup = Process.THREAD_GROUP_DEFAULT;
20171                        break;
20172                }
20173                if (true) {
20174                    long oldId = Binder.clearCallingIdentity();
20175                    try {
20176                        Process.setProcessGroup(app.pid, processGroup);
20177                        if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20178                            // do nothing if we already switched to RT
20179                            if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20180                                // Switch VR thread for app to SCHED_FIFO
20181                                if (mInVrMode && app.vrThreadTid != 0) {
20182                                    Process.setThreadScheduler(app.vrThreadTid,
20183                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20184                                }
20185                            }
20186                        } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20187                                   app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20188                            // Reset VR thread to SCHED_OTHER
20189                            // Safe to do even if we're not in VR mode
20190                            if (app.vrThreadTid != 0) {
20191                                Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20192                            }
20193                        }
20194                    } catch (Exception e) {
20195                        Slog.w(TAG, "Failed setting process group of " + app.pid
20196                                + " to " + app.curSchedGroup);
20197                        e.printStackTrace();
20198                    } finally {
20199                        Binder.restoreCallingIdentity(oldId);
20200                    }
20201                } else {
20202                    if (app.thread != null) {
20203                        try {
20204                            app.thread.setSchedulingGroup(processGroup);
20205                        } catch (RemoteException e) {
20206                        }
20207                    }
20208                }
20209            }
20210        }
20211        if (app.repForegroundActivities != app.foregroundActivities) {
20212            app.repForegroundActivities = app.foregroundActivities;
20213            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20214        }
20215        if (app.repProcState != app.curProcState) {
20216            app.repProcState = app.curProcState;
20217            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20218            if (app.thread != null) {
20219                try {
20220                    if (false) {
20221                        //RuntimeException h = new RuntimeException("here");
20222                        Slog.i(TAG, "Sending new process state " + app.repProcState
20223                                + " to " + app /*, h*/);
20224                    }
20225                    app.thread.setProcessState(app.repProcState);
20226                } catch (RemoteException e) {
20227                }
20228            }
20229        }
20230        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20231                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20232            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20233                // Experimental code to more aggressively collect pss while
20234                // running test...  the problem is that this tends to collect
20235                // the data right when a process is transitioning between process
20236                // states, which well tend to give noisy data.
20237                long start = SystemClock.uptimeMillis();
20238                long pss = Debug.getPss(app.pid, mTmpLong, null);
20239                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20240                mPendingPssProcesses.remove(app);
20241                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20242                        + " to " + app.curProcState + ": "
20243                        + (SystemClock.uptimeMillis()-start) + "ms");
20244            }
20245            app.lastStateTime = now;
20246            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20247                    mTestPssMode, isSleepingLocked(), now);
20248            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20249                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20250                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20251                    + (app.nextPssTime-now) + ": " + app);
20252        } else {
20253            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20254                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20255                    mTestPssMode)))) {
20256                requestPssLocked(app, app.setProcState);
20257                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20258                        mTestPssMode, isSleepingLocked(), now);
20259            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20260                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20261        }
20262        if (app.setProcState != app.curProcState) {
20263            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20264                    "Proc state change of " + app.processName
20265                            + " to " + app.curProcState);
20266            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20267            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20268            if (setImportant && !curImportant) {
20269                // This app is no longer something we consider important enough to allow to
20270                // use arbitrary amounts of battery power.  Note
20271                // its current wake lock time to later know to kill it if
20272                // it is not behaving well.
20273                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20274                synchronized (stats) {
20275                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20276                            app.pid, nowElapsed);
20277                }
20278                app.lastCpuTime = app.curCpuTime;
20279
20280            }
20281            // Inform UsageStats of important process state change
20282            // Must be called before updating setProcState
20283            maybeUpdateUsageStatsLocked(app, nowElapsed);
20284
20285            app.setProcState = app.curProcState;
20286            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20287                app.notCachedSinceIdle = false;
20288            }
20289            if (!doingAll) {
20290                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20291            } else {
20292                app.procStateChanged = true;
20293            }
20294        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20295                > USAGE_STATS_INTERACTION_INTERVAL) {
20296            // For apps that sit around for a long time in the interactive state, we need
20297            // to report this at least once a day so they don't go idle.
20298            maybeUpdateUsageStatsLocked(app, nowElapsed);
20299        }
20300
20301        if (changes != 0) {
20302            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20303                    "Changes in " + app + ": " + changes);
20304            int i = mPendingProcessChanges.size()-1;
20305            ProcessChangeItem item = null;
20306            while (i >= 0) {
20307                item = mPendingProcessChanges.get(i);
20308                if (item.pid == app.pid) {
20309                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20310                            "Re-using existing item: " + item);
20311                    break;
20312                }
20313                i--;
20314            }
20315            if (i < 0) {
20316                // No existing item in pending changes; need a new one.
20317                final int NA = mAvailProcessChanges.size();
20318                if (NA > 0) {
20319                    item = mAvailProcessChanges.remove(NA-1);
20320                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20321                            "Retrieving available item: " + item);
20322                } else {
20323                    item = new ProcessChangeItem();
20324                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20325                            "Allocating new item: " + item);
20326                }
20327                item.changes = 0;
20328                item.pid = app.pid;
20329                item.uid = app.info.uid;
20330                if (mPendingProcessChanges.size() == 0) {
20331                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20332                            "*** Enqueueing dispatch processes changed!");
20333                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20334                }
20335                mPendingProcessChanges.add(item);
20336            }
20337            item.changes |= changes;
20338            item.processState = app.repProcState;
20339            item.foregroundActivities = app.repForegroundActivities;
20340            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20341                    "Item " + Integer.toHexString(System.identityHashCode(item))
20342                    + " " + app.toShortString() + ": changes=" + item.changes
20343                    + " procState=" + item.processState
20344                    + " foreground=" + item.foregroundActivities
20345                    + " type=" + app.adjType + " source=" + app.adjSource
20346                    + " target=" + app.adjTarget);
20347        }
20348
20349        return success;
20350    }
20351
20352    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20353        final UidRecord.ChangeItem pendingChange;
20354        if (uidRec == null || uidRec.pendingChange == null) {
20355            if (mPendingUidChanges.size() == 0) {
20356                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20357                        "*** Enqueueing dispatch uid changed!");
20358                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20359            }
20360            final int NA = mAvailUidChanges.size();
20361            if (NA > 0) {
20362                pendingChange = mAvailUidChanges.remove(NA-1);
20363                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20364                        "Retrieving available item: " + pendingChange);
20365            } else {
20366                pendingChange = new UidRecord.ChangeItem();
20367                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20368                        "Allocating new item: " + pendingChange);
20369            }
20370            if (uidRec != null) {
20371                uidRec.pendingChange = pendingChange;
20372                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20373                    // If this uid is going away, and we haven't yet reported it is gone,
20374                    // then do so now.
20375                    change = UidRecord.CHANGE_GONE_IDLE;
20376                }
20377            } else if (uid < 0) {
20378                throw new IllegalArgumentException("No UidRecord or uid");
20379            }
20380            pendingChange.uidRecord = uidRec;
20381            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20382            mPendingUidChanges.add(pendingChange);
20383        } else {
20384            pendingChange = uidRec.pendingChange;
20385            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20386                change = UidRecord.CHANGE_GONE_IDLE;
20387            }
20388        }
20389        pendingChange.change = change;
20390        pendingChange.processState = uidRec != null
20391                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20392    }
20393
20394    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20395            String authority) {
20396        if (app == null) return;
20397        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20398            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20399            if (userState == null) return;
20400            final long now = SystemClock.elapsedRealtime();
20401            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20402            if (lastReported == null || lastReported < now - 60 * 1000L) {
20403                mUsageStatsService.reportContentProviderUsage(
20404                        authority, providerPkgName, app.userId);
20405                userState.mProviderLastReportedFg.put(authority, now);
20406            }
20407        }
20408    }
20409
20410    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20411        if (DEBUG_USAGE_STATS) {
20412            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20413                    + "] state changes: old = " + app.setProcState + ", new = "
20414                    + app.curProcState);
20415        }
20416        if (mUsageStatsService == null) {
20417            return;
20418        }
20419        boolean isInteraction;
20420        // To avoid some abuse patterns, we are going to be careful about what we consider
20421        // to be an app interaction.  Being the top activity doesn't count while the display
20422        // is sleeping, nor do short foreground services.
20423        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20424            isInteraction = true;
20425            app.fgInteractionTime = 0;
20426        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20427            if (app.fgInteractionTime == 0) {
20428                app.fgInteractionTime = nowElapsed;
20429                isInteraction = false;
20430            } else {
20431                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20432            }
20433        } else {
20434            isInteraction = app.curProcState
20435                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20436            app.fgInteractionTime = 0;
20437        }
20438        if (isInteraction && (!app.reportedInteraction
20439                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20440            app.interactionEventTime = nowElapsed;
20441            String[] packages = app.getPackageList();
20442            if (packages != null) {
20443                for (int i = 0; i < packages.length; i++) {
20444                    mUsageStatsService.reportEvent(packages[i], app.userId,
20445                            UsageEvents.Event.SYSTEM_INTERACTION);
20446                }
20447            }
20448        }
20449        app.reportedInteraction = isInteraction;
20450        if (!isInteraction) {
20451            app.interactionEventTime = 0;
20452        }
20453    }
20454
20455    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20456        if (proc.thread != null) {
20457            if (proc.baseProcessTracker != null) {
20458                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20459            }
20460        }
20461    }
20462
20463    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20464            ProcessRecord TOP_APP, boolean doingAll, long now) {
20465        if (app.thread == null) {
20466            return false;
20467        }
20468
20469        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20470
20471        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20472    }
20473
20474    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20475            boolean oomAdj) {
20476        if (isForeground != proc.foregroundServices) {
20477            proc.foregroundServices = isForeground;
20478            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20479                    proc.info.uid);
20480            if (isForeground) {
20481                if (curProcs == null) {
20482                    curProcs = new ArrayList<ProcessRecord>();
20483                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20484                }
20485                if (!curProcs.contains(proc)) {
20486                    curProcs.add(proc);
20487                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20488                            proc.info.packageName, proc.info.uid);
20489                }
20490            } else {
20491                if (curProcs != null) {
20492                    if (curProcs.remove(proc)) {
20493                        mBatteryStatsService.noteEvent(
20494                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20495                                proc.info.packageName, proc.info.uid);
20496                        if (curProcs.size() <= 0) {
20497                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20498                        }
20499                    }
20500                }
20501            }
20502            if (oomAdj) {
20503                updateOomAdjLocked();
20504            }
20505        }
20506    }
20507
20508    private final ActivityRecord resumedAppLocked() {
20509        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20510        String pkg;
20511        int uid;
20512        if (act != null) {
20513            pkg = act.packageName;
20514            uid = act.info.applicationInfo.uid;
20515        } else {
20516            pkg = null;
20517            uid = -1;
20518        }
20519        // Has the UID or resumed package name changed?
20520        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20521                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20522            if (mCurResumedPackage != null) {
20523                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20524                        mCurResumedPackage, mCurResumedUid);
20525            }
20526            mCurResumedPackage = pkg;
20527            mCurResumedUid = uid;
20528            if (mCurResumedPackage != null) {
20529                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20530                        mCurResumedPackage, mCurResumedUid);
20531            }
20532        }
20533        return act;
20534    }
20535
20536    final boolean updateOomAdjLocked(ProcessRecord app) {
20537        final ActivityRecord TOP_ACT = resumedAppLocked();
20538        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20539        final boolean wasCached = app.cached;
20540
20541        mAdjSeq++;
20542
20543        // This is the desired cached adjusment we want to tell it to use.
20544        // If our app is currently cached, we know it, and that is it.  Otherwise,
20545        // we don't know it yet, and it needs to now be cached we will then
20546        // need to do a complete oom adj.
20547        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20548                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20549        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20550                SystemClock.uptimeMillis());
20551        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20552            // Changed to/from cached state, so apps after it in the LRU
20553            // list may also be changed.
20554            updateOomAdjLocked();
20555        }
20556        return success;
20557    }
20558
20559    final void updateOomAdjLocked() {
20560        final ActivityRecord TOP_ACT = resumedAppLocked();
20561        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20562        final long now = SystemClock.uptimeMillis();
20563        final long nowElapsed = SystemClock.elapsedRealtime();
20564        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20565        final int N = mLruProcesses.size();
20566
20567        if (false) {
20568            RuntimeException e = new RuntimeException();
20569            e.fillInStackTrace();
20570            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20571        }
20572
20573        // Reset state in all uid records.
20574        for (int i=mActiveUids.size()-1; i>=0; i--) {
20575            final UidRecord uidRec = mActiveUids.valueAt(i);
20576            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20577                    "Starting update of " + uidRec);
20578            uidRec.reset();
20579        }
20580
20581        mStackSupervisor.rankTaskLayersIfNeeded();
20582
20583        mAdjSeq++;
20584        mNewNumServiceProcs = 0;
20585        mNewNumAServiceProcs = 0;
20586
20587        final int emptyProcessLimit;
20588        final int cachedProcessLimit;
20589        if (mProcessLimit <= 0) {
20590            emptyProcessLimit = cachedProcessLimit = 0;
20591        } else if (mProcessLimit == 1) {
20592            emptyProcessLimit = 1;
20593            cachedProcessLimit = 0;
20594        } else {
20595            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20596            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20597        }
20598
20599        // Let's determine how many processes we have running vs.
20600        // how many slots we have for background processes; we may want
20601        // to put multiple processes in a slot of there are enough of
20602        // them.
20603        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20604                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20605        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20606        if (numEmptyProcs > cachedProcessLimit) {
20607            // If there are more empty processes than our limit on cached
20608            // processes, then use the cached process limit for the factor.
20609            // This ensures that the really old empty processes get pushed
20610            // down to the bottom, so if we are running low on memory we will
20611            // have a better chance at keeping around more cached processes
20612            // instead of a gazillion empty processes.
20613            numEmptyProcs = cachedProcessLimit;
20614        }
20615        int emptyFactor = numEmptyProcs/numSlots;
20616        if (emptyFactor < 1) emptyFactor = 1;
20617        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20618        if (cachedFactor < 1) cachedFactor = 1;
20619        int stepCached = 0;
20620        int stepEmpty = 0;
20621        int numCached = 0;
20622        int numEmpty = 0;
20623        int numTrimming = 0;
20624
20625        mNumNonCachedProcs = 0;
20626        mNumCachedHiddenProcs = 0;
20627
20628        // First update the OOM adjustment for each of the
20629        // application processes based on their current state.
20630        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20631        int nextCachedAdj = curCachedAdj+1;
20632        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20633        int nextEmptyAdj = curEmptyAdj+2;
20634        for (int i=N-1; i>=0; i--) {
20635            ProcessRecord app = mLruProcesses.get(i);
20636            if (!app.killedByAm && app.thread != null) {
20637                app.procStateChanged = false;
20638                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20639
20640                // If we haven't yet assigned the final cached adj
20641                // to the process, do that now.
20642                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20643                    switch (app.curProcState) {
20644                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20645                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20646                            // This process is a cached process holding activities...
20647                            // assign it the next cached value for that type, and then
20648                            // step that cached level.
20649                            app.curRawAdj = curCachedAdj;
20650                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20651                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20652                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20653                                    + ")");
20654                            if (curCachedAdj != nextCachedAdj) {
20655                                stepCached++;
20656                                if (stepCached >= cachedFactor) {
20657                                    stepCached = 0;
20658                                    curCachedAdj = nextCachedAdj;
20659                                    nextCachedAdj += 2;
20660                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20661                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20662                                    }
20663                                }
20664                            }
20665                            break;
20666                        default:
20667                            // For everything else, assign next empty cached process
20668                            // level and bump that up.  Note that this means that
20669                            // long-running services that have dropped down to the
20670                            // cached level will be treated as empty (since their process
20671                            // state is still as a service), which is what we want.
20672                            app.curRawAdj = curEmptyAdj;
20673                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20674                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20675                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20676                                    + ")");
20677                            if (curEmptyAdj != nextEmptyAdj) {
20678                                stepEmpty++;
20679                                if (stepEmpty >= emptyFactor) {
20680                                    stepEmpty = 0;
20681                                    curEmptyAdj = nextEmptyAdj;
20682                                    nextEmptyAdj += 2;
20683                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20684                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20685                                    }
20686                                }
20687                            }
20688                            break;
20689                    }
20690                }
20691
20692                applyOomAdjLocked(app, true, now, nowElapsed);
20693
20694                // Count the number of process types.
20695                switch (app.curProcState) {
20696                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20697                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20698                        mNumCachedHiddenProcs++;
20699                        numCached++;
20700                        if (numCached > cachedProcessLimit) {
20701                            app.kill("cached #" + numCached, true);
20702                        }
20703                        break;
20704                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20705                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20706                                && app.lastActivityTime < oldTime) {
20707                            app.kill("empty for "
20708                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20709                                    / 1000) + "s", true);
20710                        } else {
20711                            numEmpty++;
20712                            if (numEmpty > emptyProcessLimit) {
20713                                app.kill("empty #" + numEmpty, true);
20714                            }
20715                        }
20716                        break;
20717                    default:
20718                        mNumNonCachedProcs++;
20719                        break;
20720                }
20721
20722                if (app.isolated && app.services.size() <= 0) {
20723                    // If this is an isolated process, and there are no
20724                    // services running in it, then the process is no longer
20725                    // needed.  We agressively kill these because we can by
20726                    // definition not re-use the same process again, and it is
20727                    // good to avoid having whatever code was running in them
20728                    // left sitting around after no longer needed.
20729                    app.kill("isolated not needed", true);
20730                } else {
20731                    // Keeping this process, update its uid.
20732                    final UidRecord uidRec = app.uidRecord;
20733                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20734                        uidRec.curProcState = app.curProcState;
20735                    }
20736                }
20737
20738                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20739                        && !app.killedByAm) {
20740                    numTrimming++;
20741                }
20742            }
20743        }
20744
20745        mNumServiceProcs = mNewNumServiceProcs;
20746
20747        // Now determine the memory trimming level of background processes.
20748        // Unfortunately we need to start at the back of the list to do this
20749        // properly.  We only do this if the number of background apps we
20750        // are managing to keep around is less than half the maximum we desire;
20751        // if we are keeping a good number around, we'll let them use whatever
20752        // memory they want.
20753        final int numCachedAndEmpty = numCached + numEmpty;
20754        int memFactor;
20755        if (numCached <= ProcessList.TRIM_CACHED_APPS
20756                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20757            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20758                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20759            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20760                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20761            } else {
20762                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20763            }
20764        } else {
20765            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20766        }
20767        // We always allow the memory level to go up (better).  We only allow it to go
20768        // down if we are in a state where that is allowed, *and* the total number of processes
20769        // has gone down since last time.
20770        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20771                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20772                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20773        if (memFactor > mLastMemoryLevel) {
20774            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20775                memFactor = mLastMemoryLevel;
20776                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20777            }
20778        }
20779        if (memFactor != mLastMemoryLevel) {
20780            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20781        }
20782        mLastMemoryLevel = memFactor;
20783        mLastNumProcesses = mLruProcesses.size();
20784        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20785        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20786        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20787            if (mLowRamStartTime == 0) {
20788                mLowRamStartTime = now;
20789            }
20790            int step = 0;
20791            int fgTrimLevel;
20792            switch (memFactor) {
20793                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20794                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20795                    break;
20796                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20797                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20798                    break;
20799                default:
20800                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20801                    break;
20802            }
20803            int factor = numTrimming/3;
20804            int minFactor = 2;
20805            if (mHomeProcess != null) minFactor++;
20806            if (mPreviousProcess != null) minFactor++;
20807            if (factor < minFactor) factor = minFactor;
20808            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20809            for (int i=N-1; i>=0; i--) {
20810                ProcessRecord app = mLruProcesses.get(i);
20811                if (allChanged || app.procStateChanged) {
20812                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20813                    app.procStateChanged = false;
20814                }
20815                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20816                        && !app.killedByAm) {
20817                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20818                        try {
20819                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20820                                    "Trimming memory of " + app.processName + " to " + curLevel);
20821                            app.thread.scheduleTrimMemory(curLevel);
20822                        } catch (RemoteException e) {
20823                        }
20824                        if (false) {
20825                            // For now we won't do this; our memory trimming seems
20826                            // to be good enough at this point that destroying
20827                            // activities causes more harm than good.
20828                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20829                                    && app != mHomeProcess && app != mPreviousProcess) {
20830                                // Need to do this on its own message because the stack may not
20831                                // be in a consistent state at this point.
20832                                // For these apps we will also finish their activities
20833                                // to help them free memory.
20834                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20835                            }
20836                        }
20837                    }
20838                    app.trimMemoryLevel = curLevel;
20839                    step++;
20840                    if (step >= factor) {
20841                        step = 0;
20842                        switch (curLevel) {
20843                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20844                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20845                                break;
20846                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20847                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20848                                break;
20849                        }
20850                    }
20851                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20852                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20853                            && app.thread != null) {
20854                        try {
20855                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20856                                    "Trimming memory of heavy-weight " + app.processName
20857                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20858                            app.thread.scheduleTrimMemory(
20859                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20860                        } catch (RemoteException e) {
20861                        }
20862                    }
20863                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20864                } else {
20865                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20866                            || app.systemNoUi) && app.pendingUiClean) {
20867                        // If this application is now in the background and it
20868                        // had done UI, then give it the special trim level to
20869                        // have it free UI resources.
20870                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20871                        if (app.trimMemoryLevel < level && app.thread != null) {
20872                            try {
20873                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20874                                        "Trimming memory of bg-ui " + app.processName
20875                                        + " to " + level);
20876                                app.thread.scheduleTrimMemory(level);
20877                            } catch (RemoteException e) {
20878                            }
20879                        }
20880                        app.pendingUiClean = false;
20881                    }
20882                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20883                        try {
20884                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20885                                    "Trimming memory of fg " + app.processName
20886                                    + " to " + fgTrimLevel);
20887                            app.thread.scheduleTrimMemory(fgTrimLevel);
20888                        } catch (RemoteException e) {
20889                        }
20890                    }
20891                    app.trimMemoryLevel = fgTrimLevel;
20892                }
20893            }
20894        } else {
20895            if (mLowRamStartTime != 0) {
20896                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20897                mLowRamStartTime = 0;
20898            }
20899            for (int i=N-1; i>=0; i--) {
20900                ProcessRecord app = mLruProcesses.get(i);
20901                if (allChanged || app.procStateChanged) {
20902                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20903                    app.procStateChanged = false;
20904                }
20905                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20906                        || app.systemNoUi) && app.pendingUiClean) {
20907                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20908                            && app.thread != null) {
20909                        try {
20910                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20911                                    "Trimming memory of ui hidden " + app.processName
20912                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20913                            app.thread.scheduleTrimMemory(
20914                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20915                        } catch (RemoteException e) {
20916                        }
20917                    }
20918                    app.pendingUiClean = false;
20919                }
20920                app.trimMemoryLevel = 0;
20921            }
20922        }
20923
20924        if (mAlwaysFinishActivities) {
20925            // Need to do this on its own message because the stack may not
20926            // be in a consistent state at this point.
20927            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20928        }
20929
20930        if (allChanged) {
20931            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20932        }
20933
20934        // Update from any uid changes.
20935        for (int i=mActiveUids.size()-1; i>=0; i--) {
20936            final UidRecord uidRec = mActiveUids.valueAt(i);
20937            int uidChange = UidRecord.CHANGE_PROCSTATE;
20938            if (uidRec.setProcState != uidRec.curProcState) {
20939                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20940                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20941                        + " to " + uidRec.curProcState);
20942                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20943                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20944                        uidRec.lastBackgroundTime = nowElapsed;
20945                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20946                            // Note: the background settle time is in elapsed realtime, while
20947                            // the handler time base is uptime.  All this means is that we may
20948                            // stop background uids later than we had intended, but that only
20949                            // happens because the device was sleeping so we are okay anyway.
20950                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20951                        }
20952                    }
20953                } else {
20954                    if (uidRec.idle) {
20955                        uidChange = UidRecord.CHANGE_ACTIVE;
20956                        uidRec.idle = false;
20957                    }
20958                    uidRec.lastBackgroundTime = 0;
20959                }
20960                uidRec.setProcState = uidRec.curProcState;
20961                enqueueUidChangeLocked(uidRec, -1, uidChange);
20962                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20963            }
20964        }
20965
20966        if (mProcessStats.shouldWriteNowLocked(now)) {
20967            mHandler.post(new Runnable() {
20968                @Override public void run() {
20969                    synchronized (ActivityManagerService.this) {
20970                        mProcessStats.writeStateAsyncLocked();
20971                    }
20972                }
20973            });
20974        }
20975
20976        if (DEBUG_OOM_ADJ) {
20977            final long duration = SystemClock.uptimeMillis() - now;
20978            if (false) {
20979                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20980                        new RuntimeException("here").fillInStackTrace());
20981            } else {
20982                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20983            }
20984        }
20985    }
20986
20987    final void idleUids() {
20988        synchronized (this) {
20989            final long nowElapsed = SystemClock.elapsedRealtime();
20990            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20991            long nextTime = 0;
20992            for (int i=mActiveUids.size()-1; i>=0; i--) {
20993                final UidRecord uidRec = mActiveUids.valueAt(i);
20994                final long bgTime = uidRec.lastBackgroundTime;
20995                if (bgTime > 0 && !uidRec.idle) {
20996                    if (bgTime <= maxBgTime) {
20997                        uidRec.idle = true;
20998                        doStopUidLocked(uidRec.uid, uidRec);
20999                    } else {
21000                        if (nextTime == 0 || nextTime > bgTime) {
21001                            nextTime = bgTime;
21002                        }
21003                    }
21004                }
21005            }
21006            if (nextTime > 0) {
21007                mHandler.removeMessages(IDLE_UIDS_MSG);
21008                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21009                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21010            }
21011        }
21012    }
21013
21014    final void runInBackgroundDisabled(int uid) {
21015        synchronized (this) {
21016            UidRecord uidRec = mActiveUids.get(uid);
21017            if (uidRec != null) {
21018                // This uid is actually running...  should it be considered background now?
21019                if (uidRec.idle) {
21020                    doStopUidLocked(uidRec.uid, uidRec);
21021                }
21022            } else {
21023                // This uid isn't actually running...  still send a report about it being "stopped".
21024                doStopUidLocked(uid, null);
21025            }
21026        }
21027    }
21028
21029    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21030        mServices.stopInBackgroundLocked(uid);
21031        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21032    }
21033
21034    final void trimApplications() {
21035        synchronized (this) {
21036            int i;
21037
21038            // First remove any unused application processes whose package
21039            // has been removed.
21040            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21041                final ProcessRecord app = mRemovedProcesses.get(i);
21042                if (app.activities.size() == 0
21043                        && app.curReceiver == null && app.services.size() == 0) {
21044                    Slog.i(
21045                        TAG, "Exiting empty application process "
21046                        + app.toShortString() + " ("
21047                        + (app.thread != null ? app.thread.asBinder() : null)
21048                        + ")\n");
21049                    if (app.pid > 0 && app.pid != MY_PID) {
21050                        app.kill("empty", false);
21051                    } else {
21052                        try {
21053                            app.thread.scheduleExit();
21054                        } catch (Exception e) {
21055                            // Ignore exceptions.
21056                        }
21057                    }
21058                    cleanUpApplicationRecordLocked(app, false, true, -1);
21059                    mRemovedProcesses.remove(i);
21060
21061                    if (app.persistent) {
21062                        addAppLocked(app.info, false, null /* ABI override */);
21063                    }
21064                }
21065            }
21066
21067            // Now update the oom adj for all processes.
21068            updateOomAdjLocked();
21069        }
21070    }
21071
21072    /** This method sends the specified signal to each of the persistent apps */
21073    public void signalPersistentProcesses(int sig) throws RemoteException {
21074        if (sig != Process.SIGNAL_USR1) {
21075            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21076        }
21077
21078        synchronized (this) {
21079            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21080                    != PackageManager.PERMISSION_GRANTED) {
21081                throw new SecurityException("Requires permission "
21082                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21083            }
21084
21085            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21086                ProcessRecord r = mLruProcesses.get(i);
21087                if (r.thread != null && r.persistent) {
21088                    Process.sendSignal(r.pid, sig);
21089                }
21090            }
21091        }
21092    }
21093
21094    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21095        if (proc == null || proc == mProfileProc) {
21096            proc = mProfileProc;
21097            profileType = mProfileType;
21098            clearProfilerLocked();
21099        }
21100        if (proc == null) {
21101            return;
21102        }
21103        try {
21104            proc.thread.profilerControl(false, null, profileType);
21105        } catch (RemoteException e) {
21106            throw new IllegalStateException("Process disappeared");
21107        }
21108    }
21109
21110    private void clearProfilerLocked() {
21111        if (mProfileFd != null) {
21112            try {
21113                mProfileFd.close();
21114            } catch (IOException e) {
21115            }
21116        }
21117        mProfileApp = null;
21118        mProfileProc = null;
21119        mProfileFile = null;
21120        mProfileType = 0;
21121        mAutoStopProfiler = false;
21122        mSamplingInterval = 0;
21123    }
21124
21125    public boolean profileControl(String process, int userId, boolean start,
21126            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21127
21128        try {
21129            synchronized (this) {
21130                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21131                // its own permission.
21132                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21133                        != PackageManager.PERMISSION_GRANTED) {
21134                    throw new SecurityException("Requires permission "
21135                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21136                }
21137
21138                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21139                    throw new IllegalArgumentException("null profile info or fd");
21140                }
21141
21142                ProcessRecord proc = null;
21143                if (process != null) {
21144                    proc = findProcessLocked(process, userId, "profileControl");
21145                }
21146
21147                if (start && (proc == null || proc.thread == null)) {
21148                    throw new IllegalArgumentException("Unknown process: " + process);
21149                }
21150
21151                if (start) {
21152                    stopProfilerLocked(null, 0);
21153                    setProfileApp(proc.info, proc.processName, profilerInfo);
21154                    mProfileProc = proc;
21155                    mProfileType = profileType;
21156                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21157                    try {
21158                        fd = fd.dup();
21159                    } catch (IOException e) {
21160                        fd = null;
21161                    }
21162                    profilerInfo.profileFd = fd;
21163                    proc.thread.profilerControl(start, profilerInfo, profileType);
21164                    fd = null;
21165                    mProfileFd = null;
21166                } else {
21167                    stopProfilerLocked(proc, profileType);
21168                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21169                        try {
21170                            profilerInfo.profileFd.close();
21171                        } catch (IOException e) {
21172                        }
21173                    }
21174                }
21175
21176                return true;
21177            }
21178        } catch (RemoteException e) {
21179            throw new IllegalStateException("Process disappeared");
21180        } finally {
21181            if (profilerInfo != null && profilerInfo.profileFd != null) {
21182                try {
21183                    profilerInfo.profileFd.close();
21184                } catch (IOException e) {
21185                }
21186            }
21187        }
21188    }
21189
21190    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21191        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21192                userId, true, ALLOW_FULL_ONLY, callName, null);
21193        ProcessRecord proc = null;
21194        try {
21195            int pid = Integer.parseInt(process);
21196            synchronized (mPidsSelfLocked) {
21197                proc = mPidsSelfLocked.get(pid);
21198            }
21199        } catch (NumberFormatException e) {
21200        }
21201
21202        if (proc == null) {
21203            ArrayMap<String, SparseArray<ProcessRecord>> all
21204                    = mProcessNames.getMap();
21205            SparseArray<ProcessRecord> procs = all.get(process);
21206            if (procs != null && procs.size() > 0) {
21207                proc = procs.valueAt(0);
21208                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21209                    for (int i=1; i<procs.size(); i++) {
21210                        ProcessRecord thisProc = procs.valueAt(i);
21211                        if (thisProc.userId == userId) {
21212                            proc = thisProc;
21213                            break;
21214                        }
21215                    }
21216                }
21217            }
21218        }
21219
21220        return proc;
21221    }
21222
21223    public boolean dumpHeap(String process, int userId, boolean managed,
21224            String path, ParcelFileDescriptor fd) throws RemoteException {
21225
21226        try {
21227            synchronized (this) {
21228                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21229                // its own permission (same as profileControl).
21230                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21231                        != PackageManager.PERMISSION_GRANTED) {
21232                    throw new SecurityException("Requires permission "
21233                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21234                }
21235
21236                if (fd == null) {
21237                    throw new IllegalArgumentException("null fd");
21238                }
21239
21240                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21241                if (proc == null || proc.thread == null) {
21242                    throw new IllegalArgumentException("Unknown process: " + process);
21243                }
21244
21245                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21246                if (!isDebuggable) {
21247                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21248                        throw new SecurityException("Process not debuggable: " + proc);
21249                    }
21250                }
21251
21252                proc.thread.dumpHeap(managed, path, fd);
21253                fd = null;
21254                return true;
21255            }
21256        } catch (RemoteException e) {
21257            throw new IllegalStateException("Process disappeared");
21258        } finally {
21259            if (fd != null) {
21260                try {
21261                    fd.close();
21262                } catch (IOException e) {
21263                }
21264            }
21265        }
21266    }
21267
21268    @Override
21269    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21270            String reportPackage) {
21271        if (processName != null) {
21272            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21273                    "setDumpHeapDebugLimit()");
21274        } else {
21275            synchronized (mPidsSelfLocked) {
21276                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21277                if (proc == null) {
21278                    throw new SecurityException("No process found for calling pid "
21279                            + Binder.getCallingPid());
21280                }
21281                if (!Build.IS_DEBUGGABLE
21282                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21283                    throw new SecurityException("Not running a debuggable build");
21284                }
21285                processName = proc.processName;
21286                uid = proc.uid;
21287                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21288                    throw new SecurityException("Package " + reportPackage + " is not running in "
21289                            + proc);
21290                }
21291            }
21292        }
21293        synchronized (this) {
21294            if (maxMemSize > 0) {
21295                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21296            } else {
21297                if (uid != 0) {
21298                    mMemWatchProcesses.remove(processName, uid);
21299                } else {
21300                    mMemWatchProcesses.getMap().remove(processName);
21301                }
21302            }
21303        }
21304    }
21305
21306    @Override
21307    public void dumpHeapFinished(String path) {
21308        synchronized (this) {
21309            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21310                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21311                        + " does not match last pid " + mMemWatchDumpPid);
21312                return;
21313            }
21314            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21315                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21316                        + " does not match last path " + mMemWatchDumpFile);
21317                return;
21318            }
21319            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21320            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21321        }
21322    }
21323
21324    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21325    public void monitor() {
21326        synchronized (this) { }
21327    }
21328
21329    void onCoreSettingsChange(Bundle settings) {
21330        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21331            ProcessRecord processRecord = mLruProcesses.get(i);
21332            try {
21333                if (processRecord.thread != null) {
21334                    processRecord.thread.setCoreSettings(settings);
21335                }
21336            } catch (RemoteException re) {
21337                /* ignore */
21338            }
21339        }
21340    }
21341
21342    // Multi-user methods
21343
21344    /**
21345     * Start user, if its not already running, but don't bring it to foreground.
21346     */
21347    @Override
21348    public boolean startUserInBackground(final int userId) {
21349        return mUserController.startUser(userId, /* foreground */ false);
21350    }
21351
21352    @Override
21353    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21354        return mUserController.unlockUser(userId, token, secret, listener);
21355    }
21356
21357    @Override
21358    public boolean switchUser(final int targetUserId) {
21359        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21360        UserInfo currentUserInfo;
21361        UserInfo targetUserInfo;
21362        synchronized (this) {
21363            int currentUserId = mUserController.getCurrentUserIdLocked();
21364            currentUserInfo = mUserController.getUserInfo(currentUserId);
21365            targetUserInfo = mUserController.getUserInfo(targetUserId);
21366            if (targetUserInfo == null) {
21367                Slog.w(TAG, "No user info for user #" + targetUserId);
21368                return false;
21369            }
21370            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21371                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21372                        + " when device is in demo mode");
21373                return false;
21374            }
21375            if (!targetUserInfo.supportsSwitchTo()) {
21376                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21377                return false;
21378            }
21379            if (targetUserInfo.isManagedProfile()) {
21380                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21381                return false;
21382            }
21383            mUserController.setTargetUserIdLocked(targetUserId);
21384        }
21385        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21386        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21387        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21388        return true;
21389    }
21390
21391    void scheduleStartProfilesLocked() {
21392        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21393            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21394                    DateUtils.SECOND_IN_MILLIS);
21395        }
21396    }
21397
21398    @Override
21399    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21400        return mUserController.stopUser(userId, force, callback);
21401    }
21402
21403    @Override
21404    public UserInfo getCurrentUser() {
21405        return mUserController.getCurrentUser();
21406    }
21407
21408    @Override
21409    public boolean isUserRunning(int userId, int flags) {
21410        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21411                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21412            String msg = "Permission Denial: isUserRunning() from pid="
21413                    + Binder.getCallingPid()
21414                    + ", uid=" + Binder.getCallingUid()
21415                    + " requires " + INTERACT_ACROSS_USERS;
21416            Slog.w(TAG, msg);
21417            throw new SecurityException(msg);
21418        }
21419        synchronized (this) {
21420            return mUserController.isUserRunningLocked(userId, flags);
21421        }
21422    }
21423
21424    @Override
21425    public int[] getRunningUserIds() {
21426        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21427                != PackageManager.PERMISSION_GRANTED) {
21428            String msg = "Permission Denial: isUserRunning() from pid="
21429                    + Binder.getCallingPid()
21430                    + ", uid=" + Binder.getCallingUid()
21431                    + " requires " + INTERACT_ACROSS_USERS;
21432            Slog.w(TAG, msg);
21433            throw new SecurityException(msg);
21434        }
21435        synchronized (this) {
21436            return mUserController.getStartedUserArrayLocked();
21437        }
21438    }
21439
21440    @Override
21441    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21442        mUserController.registerUserSwitchObserver(observer, name);
21443    }
21444
21445    @Override
21446    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21447        mUserController.unregisterUserSwitchObserver(observer);
21448    }
21449
21450    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21451        if (info == null) return null;
21452        ApplicationInfo newInfo = new ApplicationInfo(info);
21453        newInfo.initForUser(userId);
21454        return newInfo;
21455    }
21456
21457    public boolean isUserStopped(int userId) {
21458        synchronized (this) {
21459            return mUserController.getStartedUserStateLocked(userId) == null;
21460        }
21461    }
21462
21463    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21464        if (aInfo == null
21465                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21466            return aInfo;
21467        }
21468
21469        ActivityInfo info = new ActivityInfo(aInfo);
21470        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21471        return info;
21472    }
21473
21474    private boolean processSanityChecksLocked(ProcessRecord process) {
21475        if (process == null || process.thread == null) {
21476            return false;
21477        }
21478
21479        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21480        if (!isDebuggable) {
21481            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21482                return false;
21483            }
21484        }
21485
21486        return true;
21487    }
21488
21489    public boolean startBinderTracking() throws RemoteException {
21490        synchronized (this) {
21491            mBinderTransactionTrackingEnabled = true;
21492            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21493            // permission (same as profileControl).
21494            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21495                    != PackageManager.PERMISSION_GRANTED) {
21496                throw new SecurityException("Requires permission "
21497                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21498            }
21499
21500            for (int i = 0; i < mLruProcesses.size(); i++) {
21501                ProcessRecord process = mLruProcesses.get(i);
21502                if (!processSanityChecksLocked(process)) {
21503                    continue;
21504                }
21505                try {
21506                    process.thread.startBinderTracking();
21507                } catch (RemoteException e) {
21508                    Log.v(TAG, "Process disappared");
21509                }
21510            }
21511            return true;
21512        }
21513    }
21514
21515    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21516        try {
21517            synchronized (this) {
21518                mBinderTransactionTrackingEnabled = false;
21519                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21520                // permission (same as profileControl).
21521                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21522                        != PackageManager.PERMISSION_GRANTED) {
21523                    throw new SecurityException("Requires permission "
21524                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21525                }
21526
21527                if (fd == null) {
21528                    throw new IllegalArgumentException("null fd");
21529                }
21530
21531                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21532                pw.println("Binder transaction traces for all processes.\n");
21533                for (ProcessRecord process : mLruProcesses) {
21534                    if (!processSanityChecksLocked(process)) {
21535                        continue;
21536                    }
21537
21538                    pw.println("Traces for process: " + process.processName);
21539                    pw.flush();
21540                    try {
21541                        TransferPipe tp = new TransferPipe();
21542                        try {
21543                            process.thread.stopBinderTrackingAndDump(
21544                                    tp.getWriteFd().getFileDescriptor());
21545                            tp.go(fd.getFileDescriptor());
21546                        } finally {
21547                            tp.kill();
21548                        }
21549                    } catch (IOException e) {
21550                        pw.println("Failure while dumping IPC traces from " + process +
21551                                ".  Exception: " + e);
21552                        pw.flush();
21553                    } catch (RemoteException e) {
21554                        pw.println("Got a RemoteException while dumping IPC traces from " +
21555                                process + ".  Exception: " + e);
21556                        pw.flush();
21557                    }
21558                }
21559                fd = null;
21560                return true;
21561            }
21562        } finally {
21563            if (fd != null) {
21564                try {
21565                    fd.close();
21566                } catch (IOException e) {
21567                }
21568            }
21569        }
21570    }
21571
21572    private final class LocalService extends ActivityManagerInternal {
21573        @Override
21574        public void onWakefulnessChanged(int wakefulness) {
21575            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21576        }
21577
21578        @Override
21579        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21580                String processName, String abiOverride, int uid, Runnable crashHandler) {
21581            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21582                    processName, abiOverride, uid, crashHandler);
21583        }
21584
21585        @Override
21586        public SleepToken acquireSleepToken(String tag) {
21587            Preconditions.checkNotNull(tag);
21588
21589            ComponentName requestedVrService = null;
21590            ComponentName callingVrActivity = null;
21591            int userId = -1;
21592            synchronized (ActivityManagerService.this) {
21593                if (mFocusedActivity != null) {
21594                    requestedVrService = mFocusedActivity.requestedVrComponent;
21595                    callingVrActivity = mFocusedActivity.info.getComponentName();
21596                    userId = mFocusedActivity.userId;
21597                }
21598            }
21599
21600            if (requestedVrService != null) {
21601                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21602            }
21603
21604            synchronized (ActivityManagerService.this) {
21605                SleepTokenImpl token = new SleepTokenImpl(tag);
21606                mSleepTokens.add(token);
21607                updateSleepIfNeededLocked();
21608                return token;
21609            }
21610        }
21611
21612        @Override
21613        public ComponentName getHomeActivityForUser(int userId) {
21614            synchronized (ActivityManagerService.this) {
21615                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21616                return homeActivity == null ? null : homeActivity.realActivity;
21617            }
21618        }
21619
21620        @Override
21621        public void onUserRemoved(int userId) {
21622            synchronized (ActivityManagerService.this) {
21623                ActivityManagerService.this.onUserStoppedLocked(userId);
21624            }
21625        }
21626
21627        @Override
21628        public void onLocalVoiceInteractionStarted(IBinder activity,
21629                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21630            synchronized (ActivityManagerService.this) {
21631                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21632                        voiceSession, voiceInteractor);
21633            }
21634        }
21635
21636        @Override
21637        public void notifyStartingWindowDrawn() {
21638            synchronized (ActivityManagerService.this) {
21639                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21640            }
21641        }
21642
21643        @Override
21644        public void notifyAppTransitionStarting(int reason) {
21645            synchronized (ActivityManagerService.this) {
21646                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21647            }
21648        }
21649
21650        @Override
21651        public void notifyAppTransitionFinished() {
21652            synchronized (ActivityManagerService.this) {
21653                mStackSupervisor.notifyAppTransitionDone();
21654            }
21655        }
21656
21657        @Override
21658        public void notifyAppTransitionCancelled() {
21659            synchronized (ActivityManagerService.this) {
21660                mStackSupervisor.notifyAppTransitionDone();
21661            }
21662        }
21663
21664        @Override
21665        public List<IBinder> getTopVisibleActivities() {
21666            synchronized (ActivityManagerService.this) {
21667                return mStackSupervisor.getTopVisibleActivities();
21668            }
21669        }
21670
21671        @Override
21672        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21673            synchronized (ActivityManagerService.this) {
21674                mStackSupervisor.setDockedStackMinimized(minimized);
21675            }
21676        }
21677
21678        @Override
21679        public void killForegroundAppsForUser(int userHandle) {
21680            synchronized (ActivityManagerService.this) {
21681                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21682                final int NP = mProcessNames.getMap().size();
21683                for (int ip = 0; ip < NP; ip++) {
21684                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21685                    final int NA = apps.size();
21686                    for (int ia = 0; ia < NA; ia++) {
21687                        final ProcessRecord app = apps.valueAt(ia);
21688                        if (app.persistent) {
21689                            // We don't kill persistent processes.
21690                            continue;
21691                        }
21692                        if (app.removed) {
21693                            procs.add(app);
21694                        } else if (app.userId == userHandle && app.foregroundActivities) {
21695                            app.removed = true;
21696                            procs.add(app);
21697                        }
21698                    }
21699                }
21700
21701                final int N = procs.size();
21702                for (int i = 0; i < N; i++) {
21703                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21704                }
21705            }
21706        }
21707
21708        @Override
21709        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21710            if (!(target instanceof PendingIntentRecord)) {
21711                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21712                return;
21713            }
21714            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21715        }
21716
21717        @Override
21718        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
21719                int userId) {
21720            Preconditions.checkNotNull(values, "Configuration must not be null");
21721            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
21722            synchronized (ActivityManagerService.this) {
21723                updateConfigurationLocked(values, null, false, true, userId);
21724            }
21725        }
21726    }
21727
21728    private final class SleepTokenImpl extends SleepToken {
21729        private final String mTag;
21730        private final long mAcquireTime;
21731
21732        public SleepTokenImpl(String tag) {
21733            mTag = tag;
21734            mAcquireTime = SystemClock.uptimeMillis();
21735        }
21736
21737        @Override
21738        public void release() {
21739            synchronized (ActivityManagerService.this) {
21740                if (mSleepTokens.remove(this)) {
21741                    updateSleepIfNeededLocked();
21742                }
21743            }
21744        }
21745
21746        @Override
21747        public String toString() {
21748            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21749        }
21750    }
21751
21752    /**
21753     * An implementation of IAppTask, that allows an app to manage its own tasks via
21754     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21755     * only the process that calls getAppTasks() can call the AppTask methods.
21756     */
21757    class AppTaskImpl extends IAppTask.Stub {
21758        private int mTaskId;
21759        private int mCallingUid;
21760
21761        public AppTaskImpl(int taskId, int callingUid) {
21762            mTaskId = taskId;
21763            mCallingUid = callingUid;
21764        }
21765
21766        private void checkCaller() {
21767            if (mCallingUid != Binder.getCallingUid()) {
21768                throw new SecurityException("Caller " + mCallingUid
21769                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21770            }
21771        }
21772
21773        @Override
21774        public void finishAndRemoveTask() {
21775            checkCaller();
21776
21777            synchronized (ActivityManagerService.this) {
21778                long origId = Binder.clearCallingIdentity();
21779                try {
21780                    // We remove the task from recents to preserve backwards
21781                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21782                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21783                    }
21784                } finally {
21785                    Binder.restoreCallingIdentity(origId);
21786                }
21787            }
21788        }
21789
21790        @Override
21791        public ActivityManager.RecentTaskInfo getTaskInfo() {
21792            checkCaller();
21793
21794            synchronized (ActivityManagerService.this) {
21795                long origId = Binder.clearCallingIdentity();
21796                try {
21797                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21798                    if (tr == null) {
21799                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21800                    }
21801                    return createRecentTaskInfoFromTaskRecord(tr);
21802                } finally {
21803                    Binder.restoreCallingIdentity(origId);
21804                }
21805            }
21806        }
21807
21808        @Override
21809        public void moveToFront() {
21810            checkCaller();
21811            // Will bring task to front if it already has a root activity.
21812            final long origId = Binder.clearCallingIdentity();
21813            try {
21814                synchronized (this) {
21815                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21816                }
21817            } finally {
21818                Binder.restoreCallingIdentity(origId);
21819            }
21820        }
21821
21822        @Override
21823        public int startActivity(IBinder whoThread, String callingPackage,
21824                Intent intent, String resolvedType, Bundle bOptions) {
21825            checkCaller();
21826
21827            int callingUser = UserHandle.getCallingUserId();
21828            TaskRecord tr;
21829            IApplicationThread appThread;
21830            synchronized (ActivityManagerService.this) {
21831                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21832                if (tr == null) {
21833                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21834                }
21835                appThread = ApplicationThreadNative.asInterface(whoThread);
21836                if (appThread == null) {
21837                    throw new IllegalArgumentException("Bad app thread " + appThread);
21838                }
21839            }
21840            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21841                    resolvedType, null, null, null, null, 0, 0, null, null,
21842                    null, bOptions, false, callingUser, null, tr);
21843        }
21844
21845        @Override
21846        public void setExcludeFromRecents(boolean exclude) {
21847            checkCaller();
21848
21849            synchronized (ActivityManagerService.this) {
21850                long origId = Binder.clearCallingIdentity();
21851                try {
21852                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21853                    if (tr == null) {
21854                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21855                    }
21856                    Intent intent = tr.getBaseIntent();
21857                    if (exclude) {
21858                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21859                    } else {
21860                        intent.setFlags(intent.getFlags()
21861                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21862                    }
21863                } finally {
21864                    Binder.restoreCallingIdentity(origId);
21865                }
21866            }
21867        }
21868    }
21869
21870    /**
21871     * Kill processes for the user with id userId and that depend on the package named packageName
21872     */
21873    @Override
21874    public void killPackageDependents(String packageName, int userId) {
21875        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21876        if (packageName == null) {
21877            throw new NullPointerException(
21878                    "Cannot kill the dependents of a package without its name.");
21879        }
21880
21881        long callingId = Binder.clearCallingIdentity();
21882        IPackageManager pm = AppGlobals.getPackageManager();
21883        int pkgUid = -1;
21884        try {
21885            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21886        } catch (RemoteException e) {
21887        }
21888        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21889            throw new IllegalArgumentException(
21890                    "Cannot kill dependents of non-existing package " + packageName);
21891        }
21892        try {
21893            synchronized(this) {
21894                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21895                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21896                        "dep: " + packageName);
21897            }
21898        } finally {
21899            Binder.restoreCallingIdentity(callingId);
21900        }
21901    }
21902}
21903