ActivityManagerService.java revision 744f0e0997f08f00786e4f0266d8cbdb4b2b4569
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.Manifest.permission;
67import android.annotation.NonNull;
68import android.annotation.UserIdInt;
69import android.app.Activity;
70import android.app.ActivityManager;
71import android.app.ActivityManager.RunningTaskInfo;
72import android.app.ActivityManager.StackId;
73import android.app.ActivityManager.StackInfo;
74import android.app.ActivityManager.TaskThumbnailInfo;
75import android.app.ActivityManagerInternal;
76import android.app.ActivityManagerInternal.SleepToken;
77import android.app.ActivityManagerNative;
78import android.app.ActivityOptions;
79import android.app.ActivityThread;
80import android.app.AlertDialog;
81import android.app.AppGlobals;
82import android.app.AppOpsManager;
83import android.app.ApplicationErrorReport;
84import android.app.ApplicationThreadNative;
85import android.app.BroadcastOptions;
86import android.app.Dialog;
87import android.app.IActivityContainer;
88import android.app.IActivityContainerCallback;
89import android.app.IActivityController;
90import android.app.IAppTask;
91import android.app.IApplicationThread;
92import android.app.IInstrumentationWatcher;
93import android.app.INotificationManager;
94import android.app.IProcessObserver;
95import android.app.IServiceConnection;
96import android.app.IStopUserCallback;
97import android.app.ITaskStackListener;
98import android.app.IUiAutomationConnection;
99import android.app.IUidObserver;
100import android.app.IUserSwitchObserver;
101import android.app.Instrumentation;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.ProfilerInfo;
106import android.app.admin.DevicePolicyManager;
107import android.app.assist.AssistContent;
108import android.app.assist.AssistStructure;
109import android.app.backup.IBackupManager;
110import android.app.usage.UsageEvents;
111import android.app.usage.UsageStatsManagerInternal;
112import android.appwidget.AppWidgetManager;
113import android.content.ActivityNotFoundException;
114import android.content.BroadcastReceiver;
115import android.content.ClipData;
116import android.content.ComponentCallbacks2;
117import android.content.ComponentName;
118import android.content.ContentProvider;
119import android.content.ContentResolver;
120import android.content.Context;
121import android.content.DialogInterface;
122import android.content.IContentProvider;
123import android.content.IIntentReceiver;
124import android.content.IIntentSender;
125import android.content.Intent;
126import android.content.IntentFilter;
127import android.content.IntentSender;
128import android.content.pm.ActivityInfo;
129import android.content.pm.ApplicationInfo;
130import android.content.pm.ConfigurationInfo;
131import android.content.pm.IPackageDataObserver;
132import android.content.pm.IPackageManager;
133import android.content.pm.InstrumentationInfo;
134import android.content.pm.PackageInfo;
135import android.content.pm.PackageManager;
136import android.content.pm.PackageManager.NameNotFoundException;
137import android.content.pm.PackageManagerInternal;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.PathPermission;
140import android.content.pm.PermissionInfo;
141import android.content.pm.ProviderInfo;
142import android.content.pm.ResolveInfo;
143import android.content.pm.ServiceInfo;
144import android.content.pm.UserInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.content.res.Resources;
148import android.database.ContentObserver;
149import android.graphics.Bitmap;
150import android.graphics.Point;
151import android.graphics.Rect;
152import android.location.LocationManager;
153import android.net.Proxy;
154import android.net.ProxyInfo;
155import android.net.Uri;
156import android.os.BatteryStats;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IProcessInfoService;
170import android.os.IProgressListener;
171import android.os.LocaleList;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.PersistableBundle;
177import android.os.PowerManager;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.ResultReceiver;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.Trace;
188import android.os.TransactionTooLargeException;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.os.WorkSource;
193import android.os.storage.IMountService;
194import android.os.storage.MountServiceInternal;
195import android.os.storage.StorageManager;
196import android.provider.Settings;
197import android.service.voice.IVoiceInteractionSession;
198import android.service.voice.VoiceInteractionManagerInternal;
199import android.service.voice.VoiceInteractionSession;
200import android.telecom.TelecomManager;
201import android.text.format.DateUtils;
202import android.text.format.Time;
203import android.text.style.SuggestionSpan;
204import android.util.ArrayMap;
205import android.util.ArraySet;
206import android.util.AtomicFile;
207import android.util.DebugUtils;
208import android.util.DisplayMetrics;
209import android.util.EventLog;
210import android.util.Log;
211import android.util.Pair;
212import android.util.PrintWriterPrinter;
213import android.util.Slog;
214import android.util.SparseArray;
215import android.util.TimeUtils;
216import android.util.Xml;
217import android.view.Display;
218import android.view.Gravity;
219import android.view.LayoutInflater;
220import android.view.View;
221import android.view.WindowManager;
222
223import java.io.File;
224import java.io.FileDescriptor;
225import java.io.FileInputStream;
226import java.io.FileNotFoundException;
227import java.io.FileOutputStream;
228import java.io.IOException;
229import java.io.InputStreamReader;
230import java.io.PrintWriter;
231import java.io.StringWriter;
232import java.lang.ref.WeakReference;
233import java.nio.charset.StandardCharsets;
234import java.util.ArrayList;
235import java.util.Arrays;
236import java.util.Collections;
237import java.util.Comparator;
238import java.util.HashMap;
239import java.util.HashSet;
240import java.util.Iterator;
241import java.util.List;
242import java.util.Locale;
243import java.util.Map;
244import java.util.Objects;
245import java.util.Set;
246import java.util.concurrent.atomic.AtomicBoolean;
247import java.util.concurrent.atomic.AtomicLong;
248
249import dalvik.system.VMRuntime;
250
251import libcore.io.IoUtils;
252import libcore.util.EmptyArray;
253
254import static android.Manifest.permission.INTERACT_ACROSS_USERS;
255import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
256import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
257import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
258import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
259import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
260import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
261import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
263import static android.app.ActivityManager.StackId.HOME_STACK_ID;
264import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
265import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
266import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
267import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
268import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
269import static android.content.pm.PackageManager.GET_PROVIDERS;
270import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
272import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
273import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
274import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
275import static android.content.pm.PackageManager.PERMISSION_GRANTED;
276import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
277import static android.os.Process.PROC_CHAR;
278import static android.os.Process.PROC_OUT_LONG;
279import static android.os.Process.PROC_PARENS;
280import static android.os.Process.PROC_SPACE_TERM;
281import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
282import static android.provider.Settings.Global.DEBUG_APP;
283import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
284import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
285import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
286import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
287import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
288import static android.provider.Settings.System.FONT_SCALE;
289import static com.android.internal.util.XmlUtils.readBooleanAttribute;
290import static com.android.internal.util.XmlUtils.readIntAttribute;
291import static com.android.internal.util.XmlUtils.readLongAttribute;
292import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
293import static com.android.internal.util.XmlUtils.writeIntAttribute;
294import static com.android.internal.util.XmlUtils.writeLongAttribute;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
352import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
353import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
354import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
355import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
356import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
357import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
358import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
359import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
360import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
361import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
362import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
363import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
364import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
365import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
366import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
367import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
368import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
369import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
370import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
371import static org.xmlpull.v1.XmlPullParser.START_TAG;
372
373public final class ActivityManagerService extends ActivityManagerNative
374        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
375
376    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
377    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
378    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
379    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
380    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
381    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
382    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
383    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
384    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
385    private static final String TAG_LRU = TAG + POSTFIX_LRU;
386    private static final String TAG_MU = TAG + POSTFIX_MU;
387    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
388    private static final String TAG_POWER = TAG + POSTFIX_POWER;
389    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
390    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
391    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
392    private static final String TAG_PSS = TAG + POSTFIX_PSS;
393    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
394    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
395    private static final String TAG_STACK = TAG + POSTFIX_STACK;
396    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
397    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
398    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
399    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
400    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
401
402    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
403    // here so that while the job scheduler can depend on AMS, the other way around
404    // need not be the case.
405    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
406
407    /** Control over CPU and battery monitoring */
408    // write battery stats every 30 minutes.
409    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
410    static final boolean MONITOR_CPU_USAGE = true;
411    // don't sample cpu less than every 5 seconds.
412    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
413    // wait possibly forever for next cpu sample.
414    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
415    static final boolean MONITOR_THREAD_CPU_USAGE = false;
416
417    // The flags that are set for all calls we make to the package manager.
418    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
419
420    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
421
422    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
423
424    // Amount of time after a call to stopAppSwitches() during which we will
425    // prevent further untrusted switches from happening.
426    static final long APP_SWITCH_DELAY_TIME = 5*1000;
427
428    // How long we wait for a launched process to attach to the activity manager
429    // before we decide it's never going to come up for real.
430    static final int PROC_START_TIMEOUT = 10*1000;
431    // How long we wait for an attached process to publish its content providers
432    // before we decide it must be hung.
433    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
434
435    // How long we will retain processes hosting content providers in the "last activity"
436    // state before allowing them to drop down to the regular cached LRU list.  This is
437    // to avoid thrashing of provider processes under low memory situations.
438    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
439
440    // How long we wait for a launched process to attach to the activity manager
441    // before we decide it's never going to come up for real, when the process was
442    // started with a wrapper for instrumentation (such as Valgrind) because it
443    // could take much longer than usual.
444    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
445
446    // How long to wait after going idle before forcing apps to GC.
447    static final int GC_TIMEOUT = 5*1000;
448
449    // The minimum amount of time between successive GC requests for a process.
450    static final int GC_MIN_INTERVAL = 60*1000;
451
452    // The minimum amount of time between successive PSS requests for a process.
453    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
454
455    // The minimum amount of time between successive PSS requests for a process
456    // when the request is due to the memory state being lowered.
457    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
458
459    // The rate at which we check for apps using excessive power -- 15 mins.
460    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
461
462    // The minimum sample duration we will allow before deciding we have
463    // enough data on wake locks to start killing things.
464    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
465
466    // The minimum sample duration we will allow before deciding we have
467    // enough data on CPU usage to start killing things.
468    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
469
470    // How long we allow a receiver to run before giving up on it.
471    static final int BROADCAST_FG_TIMEOUT = 10*1000;
472    static final int BROADCAST_BG_TIMEOUT = 60*1000;
473
474    // How long we wait until we timeout on key dispatching.
475    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
476
477    // How long we wait until we timeout on key dispatching during instrumentation.
478    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
479
480    // This is the amount of time an app needs to be running a foreground service before
481    // we will consider it to be doing interaction for usage stats.
482    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
483
484    // Maximum amount of time we will allow to elapse before re-reporting usage stats
485    // interaction with foreground processes.
486    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
487
488    // This is the amount of time we allow an app to settle after it goes into the background,
489    // before we start restricting what it can do.
490    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
491
492    // How long to wait in getAssistContextExtras for the activity and foreground services
493    // to respond with the result.
494    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
495
496    // How long top wait when going through the modern assist (which doesn't need to block
497    // on getting this result before starting to launch its UI).
498    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
499
500    // Maximum number of persisted Uri grants a package is allowed
501    static final int MAX_PERSISTED_URI_GRANTS = 128;
502
503    static final int MY_PID = Process.myPid();
504
505    static final String[] EMPTY_STRING_ARRAY = new String[0];
506
507    // How many bytes to write into the dropbox log before truncating
508    static final int DROPBOX_MAX_SIZE = 192 * 1024;
509    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
510    // as one line, but close enough for now.
511    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
512
513    // Access modes for handleIncomingUser.
514    static final int ALLOW_NON_FULL = 0;
515    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
516    static final int ALLOW_FULL_ONLY = 2;
517
518    // Delay in notifying task stack change listeners (in millis)
519    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
520
521    // Necessary ApplicationInfo flags to mark an app as persistent
522    private static final int PERSISTENT_MASK =
523            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
524
525    // Intent sent when remote bugreport collection has been completed
526    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
527            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
528
529    // Delay to disable app launch boost
530    static final int APP_BOOST_MESSAGE_DELAY = 3000;
531    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
532    static final int APP_BOOST_TIMEOUT = 2500;
533
534    // Used to indicate that a task is removed it should also be removed from recents.
535    private static final boolean REMOVE_FROM_RECENTS = true;
536    // Used to indicate that an app transition should be animated.
537    static final boolean ANIMATE = true;
538
539    // Determines whether to take full screen screenshots
540    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
541    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
542
543    private static native int nativeMigrateToBoost();
544    private static native int nativeMigrateFromBoost();
545    private boolean mIsBoosted = false;
546    private long mBoostStartTime = 0;
547
548    /** All system services */
549    SystemServiceManager mSystemServiceManager;
550
551    private Installer mInstaller;
552
553    /** Run all ActivityStacks through this */
554    final ActivityStackSupervisor mStackSupervisor;
555
556    final ActivityStarter mActivityStarter;
557
558    /** Task stack change listeners. */
559    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
560            new RemoteCallbackList<ITaskStackListener>();
561
562    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
563
564    public IntentFirewall mIntentFirewall;
565
566    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
567    // default actuion automatically.  Important for devices without direct input
568    // devices.
569    private boolean mShowDialogs = true;
570    private boolean mInVrMode = false;
571
572    // Whether we should use SCHED_FIFO for UI and RenderThreads.
573    private boolean mUseFifoUiScheduling = false;
574
575    BroadcastQueue mFgBroadcastQueue;
576    BroadcastQueue mBgBroadcastQueue;
577    // Convenient for easy iteration over the queues. Foreground is first
578    // so that dispatch of foreground broadcasts gets precedence.
579    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
580
581    BroadcastStats mLastBroadcastStats;
582    BroadcastStats mCurBroadcastStats;
583
584    BroadcastQueue broadcastQueueForIntent(Intent intent) {
585        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
586        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
587                "Broadcast intent " + intent + " on "
588                + (isFg ? "foreground" : "background") + " queue");
589        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
590    }
591
592    /**
593     * Activity we have told the window manager to have key focus.
594     */
595    ActivityRecord mFocusedActivity = null;
596
597    /**
598     * User id of the last activity mFocusedActivity was set to.
599     */
600    private int mLastFocusedUserId;
601
602    /**
603     * If non-null, we are tracking the time the user spends in the currently focused app.
604     */
605    private AppTimeTracker mCurAppTimeTracker;
606
607    /**
608     * List of intents that were used to start the most recent tasks.
609     */
610    final RecentTasks mRecentTasks;
611
612    /**
613     * For addAppTask: cached of the last activity component that was added.
614     */
615    ComponentName mLastAddedTaskComponent;
616
617    /**
618     * For addAppTask: cached of the last activity uid that was added.
619     */
620    int mLastAddedTaskUid;
621
622    /**
623     * For addAppTask: cached of the last ActivityInfo that was added.
624     */
625    ActivityInfo mLastAddedTaskActivity;
626
627    /**
628     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
629     */
630    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
631
632    /**
633     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
634     */
635    String mDeviceOwnerName;
636
637    final UserController mUserController;
638
639    final AppErrors mAppErrors;
640
641    boolean mDoingSetFocusedActivity;
642
643    public boolean canShowErrorDialogs() {
644        return mShowDialogs && !mSleeping && !mShuttingDown
645                && mLockScreenShown != LOCK_SCREEN_SHOWN;
646    }
647
648    private static final class PriorityState {
649        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
650        // the current thread is currently in. When it drops down to zero, we will no longer boost
651        // the thread's priority.
652        private int regionCounter = 0;
653
654        // The thread's previous priority before boosting.
655        private int prevPriority = Integer.MIN_VALUE;
656    }
657
658    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
659        @Override protected PriorityState initialValue() {
660            return new PriorityState();
661        }
662    };
663
664    static void boostPriorityForLockedSection() {
665        int tid = Process.myTid();
666        int prevPriority = Process.getThreadPriority(tid);
667        PriorityState state = sThreadPriorityState.get();
668        if (state.regionCounter == 0 && prevPriority > -2) {
669            state.prevPriority = prevPriority;
670            Process.setThreadPriority(tid, -2);
671        }
672        state.regionCounter++;
673    }
674
675    static void resetPriorityAfterLockedSection() {
676        PriorityState state = sThreadPriorityState.get();
677        state.regionCounter--;
678        if (state.regionCounter == 0 && state.prevPriority > -2) {
679            Process.setThreadPriority(Process.myTid(), state.prevPriority);
680        }
681    }
682
683    public class PendingAssistExtras extends Binder implements Runnable {
684        public final ActivityRecord activity;
685        public final Bundle extras;
686        public final Intent intent;
687        public final String hint;
688        public final IResultReceiver receiver;
689        public final int userHandle;
690        public boolean haveResult = false;
691        public Bundle result = null;
692        public AssistStructure structure = null;
693        public AssistContent content = null;
694        public Bundle receiverExtras;
695
696        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
697                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
698            activity = _activity;
699            extras = _extras;
700            intent = _intent;
701            hint = _hint;
702            receiver = _receiver;
703            receiverExtras = _receiverExtras;
704            userHandle = _userHandle;
705        }
706        @Override
707        public void run() {
708            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
709            synchronized (this) {
710                haveResult = true;
711                notifyAll();
712            }
713            pendingAssistExtrasTimedOut(this);
714        }
715    }
716
717    final ArrayList<PendingAssistExtras> mPendingAssistExtras
718            = new ArrayList<PendingAssistExtras>();
719
720    /**
721     * Process management.
722     */
723    final ProcessList mProcessList = new ProcessList();
724
725    /**
726     * All of the applications we currently have running organized by name.
727     * The keys are strings of the application package name (as
728     * returned by the package manager), and the keys are ApplicationRecord
729     * objects.
730     */
731    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
732
733    /**
734     * Tracking long-term execution of processes to look for abuse and other
735     * bad app behavior.
736     */
737    final ProcessStatsService mProcessStats;
738
739    /**
740     * The currently running isolated processes.
741     */
742    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
743
744    /**
745     * Counter for assigning isolated process uids, to avoid frequently reusing the
746     * same ones.
747     */
748    int mNextIsolatedProcessUid = 0;
749
750    /**
751     * The currently running heavy-weight process, if any.
752     */
753    ProcessRecord mHeavyWeightProcess = null;
754
755    /**
756     * All of the processes we currently have running organized by pid.
757     * The keys are the pid running the application.
758     *
759     * <p>NOTE: This object is protected by its own lock, NOT the global
760     * activity manager lock!
761     */
762    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
763
764    /**
765     * All of the processes that have been forced to be foreground.  The key
766     * is the pid of the caller who requested it (we hold a death
767     * link on it).
768     */
769    abstract class ForegroundToken implements IBinder.DeathRecipient {
770        int pid;
771        IBinder token;
772    }
773    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
774
775    /**
776     * List of records for processes that someone had tried to start before the
777     * system was ready.  We don't start them at that point, but ensure they
778     * are started by the time booting is complete.
779     */
780    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
781
782    /**
783     * List of persistent applications that are in the process
784     * of being started.
785     */
786    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
787
788    /**
789     * Processes that are being forcibly torn down.
790     */
791    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
792
793    /**
794     * List of running applications, sorted by recent usage.
795     * The first entry in the list is the least recently used.
796     */
797    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
798
799    /**
800     * Where in mLruProcesses that the processes hosting activities start.
801     */
802    int mLruProcessActivityStart = 0;
803
804    /**
805     * Where in mLruProcesses that the processes hosting services start.
806     * This is after (lower index) than mLruProcessesActivityStart.
807     */
808    int mLruProcessServiceStart = 0;
809
810    /**
811     * List of processes that should gc as soon as things are idle.
812     */
813    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
814
815    /**
816     * Processes we want to collect PSS data from.
817     */
818    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
819
820    private boolean mBinderTransactionTrackingEnabled = false;
821
822    /**
823     * Last time we requested PSS data of all processes.
824     */
825    long mLastFullPssTime = SystemClock.uptimeMillis();
826
827    /**
828     * If set, the next time we collect PSS data we should do a full collection
829     * with data from native processes and the kernel.
830     */
831    boolean mFullPssPending = false;
832
833    /**
834     * This is the process holding what we currently consider to be
835     * the "home" activity.
836     */
837    ProcessRecord mHomeProcess;
838
839    /**
840     * This is the process holding the activity the user last visited that
841     * is in a different process from the one they are currently in.
842     */
843    ProcessRecord mPreviousProcess;
844
845    /**
846     * The time at which the previous process was last visible.
847     */
848    long mPreviousProcessVisibleTime;
849
850    /**
851     * Track all uids that have actively running processes.
852     */
853    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
854
855    /**
856     * This is for verifying the UID report flow.
857     */
858    static final boolean VALIDATE_UID_STATES = true;
859    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
860
861    /**
862     * Packages that the user has asked to have run in screen size
863     * compatibility mode instead of filling the screen.
864     */
865    final CompatModePackages mCompatModePackages;
866
867    /**
868     * Set of IntentSenderRecord objects that are currently active.
869     */
870    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
871            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
872
873    /**
874     * Fingerprints (hashCode()) of stack traces that we've
875     * already logged DropBox entries for.  Guarded by itself.  If
876     * something (rogue user app) forces this over
877     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
878     */
879    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
880    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
881
882    /**
883     * Strict Mode background batched logging state.
884     *
885     * The string buffer is guarded by itself, and its lock is also
886     * used to determine if another batched write is already
887     * in-flight.
888     */
889    private final StringBuilder mStrictModeBuffer = new StringBuilder();
890
891    /**
892     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
893     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
894     */
895    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
896
897    /**
898     * Resolver for broadcast intents to registered receivers.
899     * Holds BroadcastFilter (subclass of IntentFilter).
900     */
901    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
902            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
903        @Override
904        protected boolean allowFilterResult(
905                BroadcastFilter filter, List<BroadcastFilter> dest) {
906            IBinder target = filter.receiverList.receiver.asBinder();
907            for (int i = dest.size() - 1; i >= 0; i--) {
908                if (dest.get(i).receiverList.receiver.asBinder() == target) {
909                    return false;
910                }
911            }
912            return true;
913        }
914
915        @Override
916        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
917            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
918                    || userId == filter.owningUserId) {
919                return super.newResult(filter, match, userId);
920            }
921            return null;
922        }
923
924        @Override
925        protected BroadcastFilter[] newArray(int size) {
926            return new BroadcastFilter[size];
927        }
928
929        @Override
930        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
931            return packageName.equals(filter.packageName);
932        }
933    };
934
935    /**
936     * State of all active sticky broadcasts per user.  Keys are the action of the
937     * sticky Intent, values are an ArrayList of all broadcasted intents with
938     * that action (which should usually be one).  The SparseArray is keyed
939     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
940     * for stickies that are sent to all users.
941     */
942    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
943            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
944
945    final ActiveServices mServices;
946
947    final static class Association {
948        final int mSourceUid;
949        final String mSourceProcess;
950        final int mTargetUid;
951        final ComponentName mTargetComponent;
952        final String mTargetProcess;
953
954        int mCount;
955        long mTime;
956
957        int mNesting;
958        long mStartTime;
959
960        // states of the source process when the bind occurred.
961        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
962        long mLastStateUptime;
963        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
964                - ActivityManager.MIN_PROCESS_STATE+1];
965
966        Association(int sourceUid, String sourceProcess, int targetUid,
967                ComponentName targetComponent, String targetProcess) {
968            mSourceUid = sourceUid;
969            mSourceProcess = sourceProcess;
970            mTargetUid = targetUid;
971            mTargetComponent = targetComponent;
972            mTargetProcess = targetProcess;
973        }
974    }
975
976    /**
977     * When service association tracking is enabled, this is all of the associations we
978     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
979     * -> association data.
980     */
981    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
982            mAssociations = new SparseArray<>();
983    boolean mTrackingAssociations;
984
985    /**
986     * Backup/restore process management
987     */
988    String mBackupAppName = null;
989    BackupRecord mBackupTarget = null;
990
991    final ProviderMap mProviderMap;
992
993    /**
994     * List of content providers who have clients waiting for them.  The
995     * application is currently being launched and the provider will be
996     * removed from this list once it is published.
997     */
998    final ArrayList<ContentProviderRecord> mLaunchingProviders
999            = new ArrayList<ContentProviderRecord>();
1000
1001    /**
1002     * File storing persisted {@link #mGrantedUriPermissions}.
1003     */
1004    private final AtomicFile mGrantFile;
1005
1006    /** XML constants used in {@link #mGrantFile} */
1007    private static final String TAG_URI_GRANTS = "uri-grants";
1008    private static final String TAG_URI_GRANT = "uri-grant";
1009    private static final String ATTR_USER_HANDLE = "userHandle";
1010    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1011    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1012    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1013    private static final String ATTR_TARGET_PKG = "targetPkg";
1014    private static final String ATTR_URI = "uri";
1015    private static final String ATTR_MODE_FLAGS = "modeFlags";
1016    private static final String ATTR_CREATED_TIME = "createdTime";
1017    private static final String ATTR_PREFIX = "prefix";
1018
1019    /**
1020     * Global set of specific {@link Uri} permissions that have been granted.
1021     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1022     * to {@link UriPermission#uri} to {@link UriPermission}.
1023     */
1024    @GuardedBy("this")
1025    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1026            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1027
1028    public static class GrantUri {
1029        public final int sourceUserId;
1030        public final Uri uri;
1031        public boolean prefix;
1032
1033        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1034            this.sourceUserId = sourceUserId;
1035            this.uri = uri;
1036            this.prefix = prefix;
1037        }
1038
1039        @Override
1040        public int hashCode() {
1041            int hashCode = 1;
1042            hashCode = 31 * hashCode + sourceUserId;
1043            hashCode = 31 * hashCode + uri.hashCode();
1044            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1045            return hashCode;
1046        }
1047
1048        @Override
1049        public boolean equals(Object o) {
1050            if (o instanceof GrantUri) {
1051                GrantUri other = (GrantUri) o;
1052                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1053                        && prefix == other.prefix;
1054            }
1055            return false;
1056        }
1057
1058        @Override
1059        public String toString() {
1060            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1061            if (prefix) result += " [prefix]";
1062            return result;
1063        }
1064
1065        public String toSafeString() {
1066            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1067            if (prefix) result += " [prefix]";
1068            return result;
1069        }
1070
1071        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1072            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1073                    ContentProvider.getUriWithoutUserId(uri), false);
1074        }
1075    }
1076
1077    CoreSettingsObserver mCoreSettingsObserver;
1078
1079    FontScaleSettingObserver mFontScaleSettingObserver;
1080
1081    private final class FontScaleSettingObserver extends ContentObserver {
1082        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1083
1084        public FontScaleSettingObserver() {
1085            super(mHandler);
1086            ContentResolver resolver = mContext.getContentResolver();
1087            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1088        }
1089
1090        @Override
1091        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1092            if (mFontScaleUri.equals(uri)) {
1093                updateFontScaleIfNeeded(userId);
1094            }
1095        }
1096    }
1097
1098    /**
1099     * Thread-local storage used to carry caller permissions over through
1100     * indirect content-provider access.
1101     */
1102    private class Identity {
1103        public final IBinder token;
1104        public final int pid;
1105        public final int uid;
1106
1107        Identity(IBinder _token, int _pid, int _uid) {
1108            token = _token;
1109            pid = _pid;
1110            uid = _uid;
1111        }
1112    }
1113
1114    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1115
1116    /**
1117     * All information we have collected about the runtime performance of
1118     * any user id that can impact battery performance.
1119     */
1120    final BatteryStatsService mBatteryStatsService;
1121
1122    /**
1123     * Information about component usage
1124     */
1125    UsageStatsManagerInternal mUsageStatsService;
1126
1127    /**
1128     * Access to DeviceIdleController service.
1129     */
1130    DeviceIdleController.LocalService mLocalDeviceIdleController;
1131
1132    /**
1133     * Information about and control over application operations
1134     */
1135    final AppOpsService mAppOpsService;
1136
1137    /**
1138     * Current configuration information.  HistoryRecord objects are given
1139     * a reference to this object to indicate which configuration they are
1140     * currently running in, so this object must be kept immutable.
1141     */
1142    Configuration mConfiguration = new Configuration();
1143
1144    /**
1145     * Current sequencing integer of the configuration, for skipping old
1146     * configurations.
1147     */
1148    int mConfigurationSeq = 0;
1149
1150    boolean mSuppressResizeConfigChanges = false;
1151
1152    /**
1153     * Hardware-reported OpenGLES version.
1154     */
1155    final int GL_ES_VERSION;
1156
1157    /**
1158     * List of initialization arguments to pass to all processes when binding applications to them.
1159     * For example, references to the commonly used services.
1160     */
1161    HashMap<String, IBinder> mAppBindArgs;
1162    HashMap<String, IBinder> mIsolatedAppBindArgs;
1163
1164    /**
1165     * Temporary to avoid allocations.  Protected by main lock.
1166     */
1167    final StringBuilder mStringBuilder = new StringBuilder(256);
1168
1169    /**
1170     * Used to control how we initialize the service.
1171     */
1172    ComponentName mTopComponent;
1173    String mTopAction = Intent.ACTION_MAIN;
1174    String mTopData;
1175
1176    volatile boolean mProcessesReady = false;
1177    volatile boolean mSystemReady = false;
1178    volatile boolean mOnBattery = false;
1179    volatile int mFactoryTest;
1180
1181    @GuardedBy("this") boolean mBooting = false;
1182    @GuardedBy("this") boolean mCallFinishBooting = false;
1183    @GuardedBy("this") boolean mBootAnimationComplete = false;
1184    @GuardedBy("this") boolean mLaunchWarningShown = false;
1185    @GuardedBy("this") boolean mCheckedForSetup = false;
1186
1187    Context mContext;
1188
1189    /**
1190     * The time at which we will allow normal application switches again,
1191     * after a call to {@link #stopAppSwitches()}.
1192     */
1193    long mAppSwitchesAllowedTime;
1194
1195    /**
1196     * This is set to true after the first switch after mAppSwitchesAllowedTime
1197     * is set; any switches after that will clear the time.
1198     */
1199    boolean mDidAppSwitch;
1200
1201    /**
1202     * Last time (in realtime) at which we checked for power usage.
1203     */
1204    long mLastPowerCheckRealtime;
1205
1206    /**
1207     * Last time (in uptime) at which we checked for power usage.
1208     */
1209    long mLastPowerCheckUptime;
1210
1211    /**
1212     * Set while we are wanting to sleep, to prevent any
1213     * activities from being started/resumed.
1214     */
1215    private boolean mSleeping = false;
1216
1217    /**
1218     * The process state used for processes that are running the top activities.
1219     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1220     */
1221    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1222
1223    /**
1224     * Set while we are running a voice interaction.  This overrides
1225     * sleeping while it is active.
1226     */
1227    private IVoiceInteractionSession mRunningVoice;
1228
1229    /**
1230     * For some direct access we need to power manager.
1231     */
1232    PowerManagerInternal mLocalPowerManager;
1233
1234    /**
1235     * We want to hold a wake lock while running a voice interaction session, since
1236     * this may happen with the screen off and we need to keep the CPU running to
1237     * be able to continue to interact with the user.
1238     */
1239    PowerManager.WakeLock mVoiceWakeLock;
1240
1241    /**
1242     * State of external calls telling us if the device is awake or asleep.
1243     */
1244    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1245
1246    /**
1247     * A list of tokens that cause the top activity to be put to sleep.
1248     * They are used by components that may hide and block interaction with underlying
1249     * activities.
1250     */
1251    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1252
1253    static final int LOCK_SCREEN_HIDDEN = 0;
1254    static final int LOCK_SCREEN_LEAVING = 1;
1255    static final int LOCK_SCREEN_SHOWN = 2;
1256    /**
1257     * State of external call telling us if the lock screen is shown.
1258     */
1259    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1260
1261    /**
1262     * Set if we are shutting down the system, similar to sleeping.
1263     */
1264    boolean mShuttingDown = false;
1265
1266    /**
1267     * Current sequence id for oom_adj computation traversal.
1268     */
1269    int mAdjSeq = 0;
1270
1271    /**
1272     * Current sequence id for process LRU updating.
1273     */
1274    int mLruSeq = 0;
1275
1276    /**
1277     * Keep track of the non-cached/empty process we last found, to help
1278     * determine how to distribute cached/empty processes next time.
1279     */
1280    int mNumNonCachedProcs = 0;
1281
1282    /**
1283     * Keep track of the number of cached hidden procs, to balance oom adj
1284     * distribution between those and empty procs.
1285     */
1286    int mNumCachedHiddenProcs = 0;
1287
1288    /**
1289     * Keep track of the number of service processes we last found, to
1290     * determine on the next iteration which should be B services.
1291     */
1292    int mNumServiceProcs = 0;
1293    int mNewNumAServiceProcs = 0;
1294    int mNewNumServiceProcs = 0;
1295
1296    /**
1297     * Allow the current computed overall memory level of the system to go down?
1298     * This is set to false when we are killing processes for reasons other than
1299     * memory management, so that the now smaller process list will not be taken as
1300     * an indication that memory is tighter.
1301     */
1302    boolean mAllowLowerMemLevel = false;
1303
1304    /**
1305     * The last computed memory level, for holding when we are in a state that
1306     * processes are going away for other reasons.
1307     */
1308    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1309
1310    /**
1311     * The last total number of process we have, to determine if changes actually look
1312     * like a shrinking number of process due to lower RAM.
1313     */
1314    int mLastNumProcesses;
1315
1316    /**
1317     * The uptime of the last time we performed idle maintenance.
1318     */
1319    long mLastIdleTime = SystemClock.uptimeMillis();
1320
1321    /**
1322     * Total time spent with RAM that has been added in the past since the last idle time.
1323     */
1324    long mLowRamTimeSinceLastIdle = 0;
1325
1326    /**
1327     * If RAM is currently low, when that horrible situation started.
1328     */
1329    long mLowRamStartTime = 0;
1330
1331    /**
1332     * For reporting to battery stats the current top application.
1333     */
1334    private String mCurResumedPackage = null;
1335    private int mCurResumedUid = -1;
1336
1337    /**
1338     * For reporting to battery stats the apps currently running foreground
1339     * service.  The ProcessMap is package/uid tuples; each of these contain
1340     * an array of the currently foreground processes.
1341     */
1342    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1343            = new ProcessMap<ArrayList<ProcessRecord>>();
1344
1345    /**
1346     * This is set if we had to do a delayed dexopt of an app before launching
1347     * it, to increase the ANR timeouts in that case.
1348     */
1349    boolean mDidDexOpt;
1350
1351    /**
1352     * Set if the systemServer made a call to enterSafeMode.
1353     */
1354    boolean mSafeMode;
1355
1356    /**
1357     * If true, we are running under a test environment so will sample PSS from processes
1358     * much more rapidly to try to collect better data when the tests are rapidly
1359     * running through apps.
1360     */
1361    boolean mTestPssMode = false;
1362
1363    String mDebugApp = null;
1364    boolean mWaitForDebugger = false;
1365    boolean mDebugTransient = false;
1366    String mOrigDebugApp = null;
1367    boolean mOrigWaitForDebugger = false;
1368    boolean mAlwaysFinishActivities = false;
1369    boolean mLenientBackgroundCheck = false;
1370    boolean mForceResizableActivities;
1371    boolean mSupportsMultiWindow;
1372    boolean mSupportsFreeformWindowManagement;
1373    boolean mSupportsPictureInPicture;
1374    boolean mSupportsLeanbackOnly;
1375    Rect mDefaultPinnedStackBounds;
1376    IActivityController mController = null;
1377    boolean mControllerIsAMonkey = false;
1378    String mProfileApp = null;
1379    ProcessRecord mProfileProc = null;
1380    String mProfileFile;
1381    ParcelFileDescriptor mProfileFd;
1382    int mSamplingInterval = 0;
1383    boolean mAutoStopProfiler = false;
1384    int mProfileType = 0;
1385    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1386    String mMemWatchDumpProcName;
1387    String mMemWatchDumpFile;
1388    int mMemWatchDumpPid;
1389    int mMemWatchDumpUid;
1390    String mTrackAllocationApp = null;
1391    String mNativeDebuggingApp = null;
1392
1393    final long[] mTmpLong = new long[2];
1394
1395    static final class ProcessChangeItem {
1396        static final int CHANGE_ACTIVITIES = 1<<0;
1397        static final int CHANGE_PROCESS_STATE = 1<<1;
1398        int changes;
1399        int uid;
1400        int pid;
1401        int processState;
1402        boolean foregroundActivities;
1403    }
1404
1405    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1406    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1407
1408    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1409    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1410
1411    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1412    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1413
1414    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1415    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1416
1417    /**
1418     * Runtime CPU use collection thread.  This object's lock is used to
1419     * perform synchronization with the thread (notifying it to run).
1420     */
1421    final Thread mProcessCpuThread;
1422
1423    /**
1424     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1425     * Must acquire this object's lock when accessing it.
1426     * NOTE: this lock will be held while doing long operations (trawling
1427     * through all processes in /proc), so it should never be acquired by
1428     * any critical paths such as when holding the main activity manager lock.
1429     */
1430    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1431            MONITOR_THREAD_CPU_USAGE);
1432    final AtomicLong mLastCpuTime = new AtomicLong(0);
1433    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1434
1435    long mLastWriteTime = 0;
1436
1437    /**
1438     * Used to retain an update lock when the foreground activity is in
1439     * immersive mode.
1440     */
1441    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1442
1443    /**
1444     * Set to true after the system has finished booting.
1445     */
1446    boolean mBooted = false;
1447
1448    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1449    int mProcessLimitOverride = -1;
1450
1451    WindowManagerService mWindowManager;
1452    final ActivityThread mSystemThread;
1453
1454    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1455        final ProcessRecord mApp;
1456        final int mPid;
1457        final IApplicationThread mAppThread;
1458
1459        AppDeathRecipient(ProcessRecord app, int pid,
1460                IApplicationThread thread) {
1461            if (DEBUG_ALL) Slog.v(
1462                TAG, "New death recipient " + this
1463                + " for thread " + thread.asBinder());
1464            mApp = app;
1465            mPid = pid;
1466            mAppThread = thread;
1467        }
1468
1469        @Override
1470        public void binderDied() {
1471            if (DEBUG_ALL) Slog.v(
1472                TAG, "Death received in " + this
1473                + " for thread " + mAppThread.asBinder());
1474            synchronized(ActivityManagerService.this) {
1475                appDiedLocked(mApp, mPid, mAppThread, true);
1476            }
1477        }
1478    }
1479
1480    static final int SHOW_ERROR_UI_MSG = 1;
1481    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1482    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1483    static final int UPDATE_CONFIGURATION_MSG = 4;
1484    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1485    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1486    static final int SERVICE_TIMEOUT_MSG = 12;
1487    static final int UPDATE_TIME_ZONE = 13;
1488    static final int SHOW_UID_ERROR_UI_MSG = 14;
1489    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1490    static final int PROC_START_TIMEOUT_MSG = 20;
1491    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1492    static final int KILL_APPLICATION_MSG = 22;
1493    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1494    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1495    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1496    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1497    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1498    static final int CLEAR_DNS_CACHE_MSG = 28;
1499    static final int UPDATE_HTTP_PROXY_MSG = 29;
1500    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1501    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1502    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1503    static final int REPORT_MEM_USAGE_MSG = 33;
1504    static final int REPORT_USER_SWITCH_MSG = 34;
1505    static final int CONTINUE_USER_SWITCH_MSG = 35;
1506    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1507    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1508    static final int PERSIST_URI_GRANTS_MSG = 38;
1509    static final int REQUEST_ALL_PSS_MSG = 39;
1510    static final int START_PROFILES_MSG = 40;
1511    static final int UPDATE_TIME = 41;
1512    static final int SYSTEM_USER_START_MSG = 42;
1513    static final int SYSTEM_USER_CURRENT_MSG = 43;
1514    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1515    static final int FINISH_BOOTING_MSG = 45;
1516    static final int START_USER_SWITCH_UI_MSG = 46;
1517    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1518    static final int DISMISS_DIALOG_UI_MSG = 48;
1519    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1520    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1521    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1522    static final int DELETE_DUMPHEAP_MSG = 52;
1523    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1524    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1525    static final int REPORT_TIME_TRACKER_MSG = 55;
1526    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1527    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1528    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1529    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1530    static final int IDLE_UIDS_MSG = 60;
1531    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1532    static final int LOG_STACK_STATE = 62;
1533    static final int VR_MODE_CHANGE_MSG = 63;
1534    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1535    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1536    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1537    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1538    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1539    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1540    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1541
1542    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1543    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1544    static final int FIRST_COMPAT_MODE_MSG = 300;
1545    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1546
1547    static ServiceThread sKillThread = null;
1548    static KillHandler sKillHandler = null;
1549
1550    CompatModeDialog mCompatModeDialog;
1551    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1552    long mLastMemUsageReportTime = 0;
1553
1554    /**
1555     * Flag whether the current user is a "monkey", i.e. whether
1556     * the UI is driven by a UI automation tool.
1557     */
1558    private boolean mUserIsMonkey;
1559
1560    /** Flag whether the device has a Recents UI */
1561    boolean mHasRecents;
1562
1563    /** The dimensions of the thumbnails in the Recents UI. */
1564    int mThumbnailWidth;
1565    int mThumbnailHeight;
1566    float mFullscreenThumbnailScale;
1567
1568    final ServiceThread mHandlerThread;
1569    final MainHandler mHandler;
1570    final UiHandler mUiHandler;
1571
1572    PackageManagerInternal mPackageManagerInt;
1573
1574    // VoiceInteraction session ID that changes for each new request except when
1575    // being called for multiwindow assist in a single session.
1576    private int mViSessionId = 1000;
1577
1578    final class KillHandler extends Handler {
1579        static final int KILL_PROCESS_GROUP_MSG = 4000;
1580
1581        public KillHandler(Looper looper) {
1582            super(looper, null, true);
1583        }
1584
1585        @Override
1586        public void handleMessage(Message msg) {
1587            switch (msg.what) {
1588                case KILL_PROCESS_GROUP_MSG:
1589                {
1590                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1591                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1592                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1593                }
1594                break;
1595
1596                default:
1597                    super.handleMessage(msg);
1598            }
1599        }
1600    }
1601
1602    final class UiHandler extends Handler {
1603        public UiHandler() {
1604            super(com.android.server.UiThread.get().getLooper(), null, true);
1605        }
1606
1607        @Override
1608        public void handleMessage(Message msg) {
1609            switch (msg.what) {
1610            case SHOW_ERROR_UI_MSG: {
1611                mAppErrors.handleShowAppErrorUi(msg);
1612                ensureBootCompleted();
1613            } break;
1614            case SHOW_NOT_RESPONDING_UI_MSG: {
1615                mAppErrors.handleShowAnrUi(msg);
1616                ensureBootCompleted();
1617            } break;
1618            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1619                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1620                synchronized (ActivityManagerService.this) {
1621                    ProcessRecord proc = (ProcessRecord) data.get("app");
1622                    if (proc == null) {
1623                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1624                        break;
1625                    }
1626                    if (proc.crashDialog != null) {
1627                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1628                        return;
1629                    }
1630                    AppErrorResult res = (AppErrorResult) data.get("result");
1631                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1632                        Dialog d = new StrictModeViolationDialog(mContext,
1633                                ActivityManagerService.this, res, proc);
1634                        d.show();
1635                        proc.crashDialog = d;
1636                    } else {
1637                        // The device is asleep, so just pretend that the user
1638                        // saw a crash dialog and hit "force quit".
1639                        res.set(0);
1640                    }
1641                }
1642                ensureBootCompleted();
1643            } break;
1644            case SHOW_FACTORY_ERROR_UI_MSG: {
1645                Dialog d = new FactoryErrorDialog(
1646                    mContext, msg.getData().getCharSequence("msg"));
1647                d.show();
1648                ensureBootCompleted();
1649            } break;
1650            case WAIT_FOR_DEBUGGER_UI_MSG: {
1651                synchronized (ActivityManagerService.this) {
1652                    ProcessRecord app = (ProcessRecord)msg.obj;
1653                    if (msg.arg1 != 0) {
1654                        if (!app.waitedForDebugger) {
1655                            Dialog d = new AppWaitingForDebuggerDialog(
1656                                    ActivityManagerService.this,
1657                                    mContext, app);
1658                            app.waitDialog = d;
1659                            app.waitedForDebugger = true;
1660                            d.show();
1661                        }
1662                    } else {
1663                        if (app.waitDialog != null) {
1664                            app.waitDialog.dismiss();
1665                            app.waitDialog = null;
1666                        }
1667                    }
1668                }
1669            } break;
1670            case SHOW_UID_ERROR_UI_MSG: {
1671                if (mShowDialogs) {
1672                    AlertDialog d = new BaseErrorDialog(mContext);
1673                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1674                    d.setCancelable(false);
1675                    d.setTitle(mContext.getText(R.string.android_system_label));
1676                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1677                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1678                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1679                    d.show();
1680                }
1681            } break;
1682            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1683                if (mShowDialogs) {
1684                    AlertDialog d = new BaseErrorDialog(mContext);
1685                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1686                    d.setCancelable(false);
1687                    d.setTitle(mContext.getText(R.string.android_system_label));
1688                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1689                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1690                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1691                    d.show();
1692                }
1693            } break;
1694            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1695                synchronized (ActivityManagerService.this) {
1696                    ActivityRecord ar = (ActivityRecord) msg.obj;
1697                    if (mCompatModeDialog != null) {
1698                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1699                                ar.info.applicationInfo.packageName)) {
1700                            return;
1701                        }
1702                        mCompatModeDialog.dismiss();
1703                        mCompatModeDialog = null;
1704                    }
1705                    if (ar != null && false) {
1706                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1707                                ar.packageName)) {
1708                            int mode = mCompatModePackages.computeCompatModeLocked(
1709                                    ar.info.applicationInfo);
1710                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1711                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1712                                mCompatModeDialog = new CompatModeDialog(
1713                                        ActivityManagerService.this, mContext,
1714                                        ar.info.applicationInfo);
1715                                mCompatModeDialog.show();
1716                            }
1717                        }
1718                    }
1719                }
1720                break;
1721            }
1722            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1723                synchronized (ActivityManagerService.this) {
1724                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1725                    if (mUnsupportedDisplaySizeDialog != null) {
1726                        mUnsupportedDisplaySizeDialog.dismiss();
1727                        mUnsupportedDisplaySizeDialog = null;
1728                    }
1729                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1730                            ar.packageName)) {
1731                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1732                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1733                        mUnsupportedDisplaySizeDialog.show();
1734                    }
1735                }
1736                break;
1737            }
1738            case START_USER_SWITCH_UI_MSG: {
1739                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1740                break;
1741            }
1742            case DISMISS_DIALOG_UI_MSG: {
1743                final Dialog d = (Dialog) msg.obj;
1744                d.dismiss();
1745                break;
1746            }
1747            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1748                dispatchProcessesChanged();
1749                break;
1750            }
1751            case DISPATCH_PROCESS_DIED_UI_MSG: {
1752                final int pid = msg.arg1;
1753                final int uid = msg.arg2;
1754                dispatchProcessDied(pid, uid);
1755                break;
1756            }
1757            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1758                dispatchUidsChanged();
1759            } break;
1760            }
1761        }
1762    }
1763
1764    final class MainHandler extends Handler {
1765        public MainHandler(Looper looper) {
1766            super(looper, null, true);
1767        }
1768
1769        @Override
1770        public void handleMessage(Message msg) {
1771            switch (msg.what) {
1772            case UPDATE_CONFIGURATION_MSG: {
1773                final ContentResolver resolver = mContext.getContentResolver();
1774                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1775                        msg.arg1);
1776            } break;
1777            case GC_BACKGROUND_PROCESSES_MSG: {
1778                synchronized (ActivityManagerService.this) {
1779                    performAppGcsIfAppropriateLocked();
1780                }
1781            } break;
1782            case SERVICE_TIMEOUT_MSG: {
1783                if (mDidDexOpt) {
1784                    mDidDexOpt = false;
1785                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1786                    nmsg.obj = msg.obj;
1787                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1788                    return;
1789                }
1790                mServices.serviceTimeout((ProcessRecord)msg.obj);
1791            } break;
1792            case UPDATE_TIME_ZONE: {
1793                synchronized (ActivityManagerService.this) {
1794                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1795                        ProcessRecord r = mLruProcesses.get(i);
1796                        if (r.thread != null) {
1797                            try {
1798                                r.thread.updateTimeZone();
1799                            } catch (RemoteException ex) {
1800                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1801                            }
1802                        }
1803                    }
1804                }
1805            } break;
1806            case CLEAR_DNS_CACHE_MSG: {
1807                synchronized (ActivityManagerService.this) {
1808                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1809                        ProcessRecord r = mLruProcesses.get(i);
1810                        if (r.thread != null) {
1811                            try {
1812                                r.thread.clearDnsCache();
1813                            } catch (RemoteException ex) {
1814                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1815                            }
1816                        }
1817                    }
1818                }
1819            } break;
1820            case UPDATE_HTTP_PROXY_MSG: {
1821                ProxyInfo proxy = (ProxyInfo)msg.obj;
1822                String host = "";
1823                String port = "";
1824                String exclList = "";
1825                Uri pacFileUrl = Uri.EMPTY;
1826                if (proxy != null) {
1827                    host = proxy.getHost();
1828                    port = Integer.toString(proxy.getPort());
1829                    exclList = proxy.getExclusionListAsString();
1830                    pacFileUrl = proxy.getPacFileUrl();
1831                }
1832                synchronized (ActivityManagerService.this) {
1833                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1834                        ProcessRecord r = mLruProcesses.get(i);
1835                        if (r.thread != null) {
1836                            try {
1837                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1838                            } catch (RemoteException ex) {
1839                                Slog.w(TAG, "Failed to update http proxy for: " +
1840                                        r.info.processName);
1841                            }
1842                        }
1843                    }
1844                }
1845            } break;
1846            case PROC_START_TIMEOUT_MSG: {
1847                if (mDidDexOpt) {
1848                    mDidDexOpt = false;
1849                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1850                    nmsg.obj = msg.obj;
1851                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1852                    return;
1853                }
1854                ProcessRecord app = (ProcessRecord)msg.obj;
1855                synchronized (ActivityManagerService.this) {
1856                    processStartTimedOutLocked(app);
1857                }
1858            } break;
1859            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1860                ProcessRecord app = (ProcessRecord)msg.obj;
1861                synchronized (ActivityManagerService.this) {
1862                    processContentProviderPublishTimedOutLocked(app);
1863                }
1864            } break;
1865            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1866                synchronized (ActivityManagerService.this) {
1867                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1868                }
1869            } break;
1870            case KILL_APPLICATION_MSG: {
1871                synchronized (ActivityManagerService.this) {
1872                    final int appId = msg.arg1;
1873                    final int userId = msg.arg2;
1874                    Bundle bundle = (Bundle)msg.obj;
1875                    String pkg = bundle.getString("pkg");
1876                    String reason = bundle.getString("reason");
1877                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1878                            false, userId, reason);
1879                }
1880            } break;
1881            case FINALIZE_PENDING_INTENT_MSG: {
1882                ((PendingIntentRecord)msg.obj).completeFinalize();
1883            } break;
1884            case POST_HEAVY_NOTIFICATION_MSG: {
1885                INotificationManager inm = NotificationManager.getService();
1886                if (inm == null) {
1887                    return;
1888                }
1889
1890                ActivityRecord root = (ActivityRecord)msg.obj;
1891                ProcessRecord process = root.app;
1892                if (process == null) {
1893                    return;
1894                }
1895
1896                try {
1897                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1898                    String text = mContext.getString(R.string.heavy_weight_notification,
1899                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1900                    Notification notification = new Notification.Builder(context)
1901                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1902                            .setWhen(0)
1903                            .setOngoing(true)
1904                            .setTicker(text)
1905                            .setColor(mContext.getColor(
1906                                    com.android.internal.R.color.system_notification_accent_color))
1907                            .setContentTitle(text)
1908                            .setContentText(
1909                                    mContext.getText(R.string.heavy_weight_notification_detail))
1910                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1911                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1912                                    new UserHandle(root.userId)))
1913                            .build();
1914                    try {
1915                        int[] outId = new int[1];
1916                        inm.enqueueNotificationWithTag("android", "android", null,
1917                                R.string.heavy_weight_notification,
1918                                notification, outId, root.userId);
1919                    } catch (RuntimeException e) {
1920                        Slog.w(ActivityManagerService.TAG,
1921                                "Error showing notification for heavy-weight app", e);
1922                    } catch (RemoteException e) {
1923                    }
1924                } catch (NameNotFoundException e) {
1925                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1926                }
1927            } break;
1928            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1929                INotificationManager inm = NotificationManager.getService();
1930                if (inm == null) {
1931                    return;
1932                }
1933                try {
1934                    inm.cancelNotificationWithTag("android", null,
1935                            R.string.heavy_weight_notification,  msg.arg1);
1936                } catch (RuntimeException e) {
1937                    Slog.w(ActivityManagerService.TAG,
1938                            "Error canceling notification for service", e);
1939                } catch (RemoteException e) {
1940                }
1941            } break;
1942            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1943                synchronized (ActivityManagerService.this) {
1944                    checkExcessivePowerUsageLocked(true);
1945                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1946                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1947                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1948                }
1949            } break;
1950            case REPORT_MEM_USAGE_MSG: {
1951                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1952                Thread thread = new Thread() {
1953                    @Override public void run() {
1954                        reportMemUsage(memInfos);
1955                    }
1956                };
1957                thread.start();
1958                break;
1959            }
1960            case REPORT_USER_SWITCH_MSG: {
1961                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1962                break;
1963            }
1964            case CONTINUE_USER_SWITCH_MSG: {
1965                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1966                break;
1967            }
1968            case USER_SWITCH_TIMEOUT_MSG: {
1969                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1970                break;
1971            }
1972            case IMMERSIVE_MODE_LOCK_MSG: {
1973                final boolean nextState = (msg.arg1 != 0);
1974                if (mUpdateLock.isHeld() != nextState) {
1975                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1976                            "Applying new update lock state '" + nextState
1977                            + "' for " + (ActivityRecord)msg.obj);
1978                    if (nextState) {
1979                        mUpdateLock.acquire();
1980                    } else {
1981                        mUpdateLock.release();
1982                    }
1983                }
1984                break;
1985            }
1986            case PERSIST_URI_GRANTS_MSG: {
1987                writeGrantedUriPermissions();
1988                break;
1989            }
1990            case REQUEST_ALL_PSS_MSG: {
1991                synchronized (ActivityManagerService.this) {
1992                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1993                }
1994                break;
1995            }
1996            case START_PROFILES_MSG: {
1997                synchronized (ActivityManagerService.this) {
1998                    mUserController.startProfilesLocked();
1999                }
2000                break;
2001            }
2002            case UPDATE_TIME: {
2003                synchronized (ActivityManagerService.this) {
2004                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2005                        ProcessRecord r = mLruProcesses.get(i);
2006                        if (r.thread != null) {
2007                            try {
2008                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2009                            } catch (RemoteException ex) {
2010                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2011                            }
2012                        }
2013                    }
2014                }
2015                break;
2016            }
2017            case SYSTEM_USER_START_MSG: {
2018                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2019                        Integer.toString(msg.arg1), msg.arg1);
2020                mSystemServiceManager.startUser(msg.arg1);
2021                break;
2022            }
2023            case SYSTEM_USER_UNLOCK_MSG: {
2024                final int userId = msg.arg1;
2025                mSystemServiceManager.unlockUser(userId);
2026                synchronized (ActivityManagerService.this) {
2027                    mRecentTasks.loadUserRecentsLocked(userId);
2028                }
2029                if (userId == UserHandle.USER_SYSTEM) {
2030                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2031                }
2032                installEncryptionUnawareProviders(userId);
2033                mUserController.finishUserUnlocked((UserState) msg.obj);
2034                break;
2035            }
2036            case SYSTEM_USER_CURRENT_MSG: {
2037                mBatteryStatsService.noteEvent(
2038                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2039                        Integer.toString(msg.arg2), msg.arg2);
2040                mBatteryStatsService.noteEvent(
2041                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2042                        Integer.toString(msg.arg1), msg.arg1);
2043                mSystemServiceManager.switchUser(msg.arg1);
2044                break;
2045            }
2046            case ENTER_ANIMATION_COMPLETE_MSG: {
2047                synchronized (ActivityManagerService.this) {
2048                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2049                    if (r != null && r.app != null && r.app.thread != null) {
2050                        try {
2051                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2052                        } catch (RemoteException e) {
2053                        }
2054                    }
2055                }
2056                break;
2057            }
2058            case FINISH_BOOTING_MSG: {
2059                if (msg.arg1 != 0) {
2060                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2061                    finishBooting();
2062                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2063                }
2064                if (msg.arg2 != 0) {
2065                    enableScreenAfterBoot();
2066                }
2067                break;
2068            }
2069            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2070                try {
2071                    Locale l = (Locale) msg.obj;
2072                    IBinder service = ServiceManager.getService("mount");
2073                    IMountService mountService = IMountService.Stub.asInterface(service);
2074                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2075                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2076                } catch (RemoteException e) {
2077                    Log.e(TAG, "Error storing locale for decryption UI", e);
2078                }
2079                break;
2080            }
2081            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2082                synchronized (ActivityManagerService.this) {
2083                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2084                        try {
2085                            // Make a one-way callback to the listener
2086                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2087                        } catch (RemoteException e){
2088                            // Handled by the RemoteCallbackList
2089                        }
2090                    }
2091                    mTaskStackListeners.finishBroadcast();
2092                }
2093                break;
2094            }
2095            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2096                synchronized (ActivityManagerService.this) {
2097                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2098                        try {
2099                            // Make a one-way callback to the listener
2100                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2101                        } catch (RemoteException e){
2102                            // Handled by the RemoteCallbackList
2103                        }
2104                    }
2105                    mTaskStackListeners.finishBroadcast();
2106                }
2107                break;
2108            }
2109            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2110                synchronized (ActivityManagerService.this) {
2111                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2112                        try {
2113                            // Make a one-way callback to the listener
2114                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2115                        } catch (RemoteException e){
2116                            // Handled by the RemoteCallbackList
2117                        }
2118                    }
2119                    mTaskStackListeners.finishBroadcast();
2120                }
2121                break;
2122            }
2123            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2124                synchronized (ActivityManagerService.this) {
2125                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2126                        try {
2127                            // Make a one-way callback to the listener
2128                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2129                        } catch (RemoteException e){
2130                            // Handled by the RemoteCallbackList
2131                        }
2132                    }
2133                    mTaskStackListeners.finishBroadcast();
2134                }
2135                break;
2136            }
2137            case NOTIFY_FORCED_RESIZABLE_MSG: {
2138                synchronized (ActivityManagerService.this) {
2139                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2140                        try {
2141                            // Make a one-way callback to the listener
2142                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2143                                    (String) msg.obj, msg.arg1);
2144                        } catch (RemoteException e){
2145                            // Handled by the RemoteCallbackList
2146                        }
2147                    }
2148                    mTaskStackListeners.finishBroadcast();
2149                }
2150                break;
2151            }
2152                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2153                    synchronized (ActivityManagerService.this) {
2154                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2155                            try {
2156                                // Make a one-way callback to the listener
2157                                mTaskStackListeners.getBroadcastItem(i)
2158                                        .onActivityDismissingDockedStack();
2159                            } catch (RemoteException e){
2160                                // Handled by the RemoteCallbackList
2161                            }
2162                        }
2163                        mTaskStackListeners.finishBroadcast();
2164                    }
2165                    break;
2166                }
2167            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2168                final int uid = msg.arg1;
2169                final byte[] firstPacket = (byte[]) msg.obj;
2170
2171                synchronized (mPidsSelfLocked) {
2172                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2173                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2174                        if (p.uid == uid) {
2175                            try {
2176                                p.thread.notifyCleartextNetwork(firstPacket);
2177                            } catch (RemoteException ignored) {
2178                            }
2179                        }
2180                    }
2181                }
2182                break;
2183            }
2184            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2185                final String procName;
2186                final int uid;
2187                final long memLimit;
2188                final String reportPackage;
2189                synchronized (ActivityManagerService.this) {
2190                    procName = mMemWatchDumpProcName;
2191                    uid = mMemWatchDumpUid;
2192                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2193                    if (val == null) {
2194                        val = mMemWatchProcesses.get(procName, 0);
2195                    }
2196                    if (val != null) {
2197                        memLimit = val.first;
2198                        reportPackage = val.second;
2199                    } else {
2200                        memLimit = 0;
2201                        reportPackage = null;
2202                    }
2203                }
2204                if (procName == null) {
2205                    return;
2206                }
2207
2208                if (DEBUG_PSS) Slog.d(TAG_PSS,
2209                        "Showing dump heap notification from " + procName + "/" + uid);
2210
2211                INotificationManager inm = NotificationManager.getService();
2212                if (inm == null) {
2213                    return;
2214                }
2215
2216                String text = mContext.getString(R.string.dump_heap_notification, procName);
2217
2218
2219                Intent deleteIntent = new Intent();
2220                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2221                Intent intent = new Intent();
2222                intent.setClassName("android", DumpHeapActivity.class.getName());
2223                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2224                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2225                if (reportPackage != null) {
2226                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2227                }
2228                int userId = UserHandle.getUserId(uid);
2229                Notification notification = new Notification.Builder(mContext)
2230                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2231                        .setWhen(0)
2232                        .setOngoing(true)
2233                        .setAutoCancel(true)
2234                        .setTicker(text)
2235                        .setColor(mContext.getColor(
2236                                com.android.internal.R.color.system_notification_accent_color))
2237                        .setContentTitle(text)
2238                        .setContentText(
2239                                mContext.getText(R.string.dump_heap_notification_detail))
2240                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2241                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2242                                new UserHandle(userId)))
2243                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2244                                deleteIntent, 0, UserHandle.SYSTEM))
2245                        .build();
2246
2247                try {
2248                    int[] outId = new int[1];
2249                    inm.enqueueNotificationWithTag("android", "android", null,
2250                            R.string.dump_heap_notification,
2251                            notification, outId, userId);
2252                } catch (RuntimeException e) {
2253                    Slog.w(ActivityManagerService.TAG,
2254                            "Error showing notification for dump heap", e);
2255                } catch (RemoteException e) {
2256                }
2257            } break;
2258            case DELETE_DUMPHEAP_MSG: {
2259                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2260                        DumpHeapActivity.JAVA_URI,
2261                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2262                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2263                        UserHandle.myUserId());
2264                synchronized (ActivityManagerService.this) {
2265                    mMemWatchDumpFile = null;
2266                    mMemWatchDumpProcName = null;
2267                    mMemWatchDumpPid = -1;
2268                    mMemWatchDumpUid = -1;
2269                }
2270            } break;
2271            case FOREGROUND_PROFILE_CHANGED_MSG: {
2272                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2273            } break;
2274            case REPORT_TIME_TRACKER_MSG: {
2275                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2276                tracker.deliverResult(mContext);
2277            } break;
2278            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2279                mUserController.dispatchUserSwitchComplete(msg.arg1);
2280            } break;
2281            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2282                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2283                try {
2284                    connection.shutdown();
2285                } catch (RemoteException e) {
2286                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2287                }
2288                // Only a UiAutomation can set this flag and now that
2289                // it is finished we make sure it is reset to its default.
2290                mUserIsMonkey = false;
2291            } break;
2292            case APP_BOOST_DEACTIVATE_MSG: {
2293                synchronized(ActivityManagerService.this) {
2294                    if (mIsBoosted) {
2295                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2296                            nativeMigrateFromBoost();
2297                            mIsBoosted = false;
2298                            mBoostStartTime = 0;
2299                        } else {
2300                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2301                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2302                        }
2303                    }
2304                }
2305            } break;
2306            case IDLE_UIDS_MSG: {
2307                idleUids();
2308            } break;
2309            case LOG_STACK_STATE: {
2310                synchronized (ActivityManagerService.this) {
2311                    mStackSupervisor.logStackState();
2312                }
2313            } break;
2314            case VR_MODE_CHANGE_MSG: {
2315                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2316                if (vrService == null) {
2317                    break;
2318                }
2319                final ActivityRecord r = (ActivityRecord) msg.obj;
2320                boolean vrMode;
2321                ComponentName requestedPackage;
2322                ComponentName callingPackage;
2323                int userId;
2324                synchronized (ActivityManagerService.this) {
2325                    vrMode = r.requestedVrComponent != null;
2326                    requestedPackage = r.requestedVrComponent;
2327                    userId = r.userId;
2328                    callingPackage = r.info.getComponentName();
2329                    if (mInVrMode != vrMode) {
2330                        mInVrMode = vrMode;
2331                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2332                        if (r.app != null) {
2333                            ProcessRecord proc = r.app;
2334                            if (proc.vrThreadTid > 0) {
2335                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2336                                    try {
2337                                        if (mInVrMode == true) {
2338                                            Process.setThreadScheduler(proc.vrThreadTid,
2339                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2340                                        } else {
2341                                            Process.setThreadScheduler(proc.vrThreadTid,
2342                                                Process.SCHED_OTHER, 0);
2343                                        }
2344                                    } catch (IllegalArgumentException e) {
2345                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2346                                                + " not exist:\n" + e);
2347                                    }
2348                                }
2349                            }
2350                        }
2351                    }
2352                }
2353                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2354            } break;
2355            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2356                final ActivityRecord r = (ActivityRecord) msg.obj;
2357                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2358                if (needsVrMode) {
2359                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2360                            r.info.getComponentName(), false);
2361                }
2362            } break;
2363            }
2364        }
2365    };
2366
2367    static final int COLLECT_PSS_BG_MSG = 1;
2368
2369    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2370        @Override
2371        public void handleMessage(Message msg) {
2372            switch (msg.what) {
2373            case COLLECT_PSS_BG_MSG: {
2374                long start = SystemClock.uptimeMillis();
2375                MemInfoReader memInfo = null;
2376                synchronized (ActivityManagerService.this) {
2377                    if (mFullPssPending) {
2378                        mFullPssPending = false;
2379                        memInfo = new MemInfoReader();
2380                    }
2381                }
2382                if (memInfo != null) {
2383                    updateCpuStatsNow();
2384                    long nativeTotalPss = 0;
2385                    final List<ProcessCpuTracker.Stats> stats;
2386                    synchronized (mProcessCpuTracker) {
2387                        stats = mProcessCpuTracker.getStats( (st)-> {
2388                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2389                        });
2390                    }
2391                    final int N = stats.size();
2392                    for (int j = 0; j < N; j++) {
2393                        synchronized (mPidsSelfLocked) {
2394                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2395                                // This is one of our own processes; skip it.
2396                                continue;
2397                            }
2398                        }
2399                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2400                    }
2401                    memInfo.readMemInfo();
2402                    synchronized (ActivityManagerService.this) {
2403                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2404                                + (SystemClock.uptimeMillis()-start) + "ms");
2405                        final long cachedKb = memInfo.getCachedSizeKb();
2406                        final long freeKb = memInfo.getFreeSizeKb();
2407                        final long zramKb = memInfo.getZramTotalSizeKb();
2408                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2409                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2410                                kernelKb*1024, nativeTotalPss*1024);
2411                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2412                                nativeTotalPss);
2413                    }
2414                }
2415
2416                int num = 0;
2417                long[] tmp = new long[2];
2418                do {
2419                    ProcessRecord proc;
2420                    int procState;
2421                    int pid;
2422                    long lastPssTime;
2423                    synchronized (ActivityManagerService.this) {
2424                        if (mPendingPssProcesses.size() <= 0) {
2425                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2426                                    "Collected PSS of " + num + " processes in "
2427                                    + (SystemClock.uptimeMillis() - start) + "ms");
2428                            mPendingPssProcesses.clear();
2429                            return;
2430                        }
2431                        proc = mPendingPssProcesses.remove(0);
2432                        procState = proc.pssProcState;
2433                        lastPssTime = proc.lastPssTime;
2434                        if (proc.thread != null && procState == proc.setProcState
2435                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2436                                        < SystemClock.uptimeMillis()) {
2437                            pid = proc.pid;
2438                        } else {
2439                            proc = null;
2440                            pid = 0;
2441                        }
2442                    }
2443                    if (proc != null) {
2444                        long pss = Debug.getPss(pid, tmp, null);
2445                        synchronized (ActivityManagerService.this) {
2446                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2447                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2448                                num++;
2449                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2450                                        SystemClock.uptimeMillis());
2451                            }
2452                        }
2453                    }
2454                } while (true);
2455            }
2456            }
2457        }
2458    };
2459
2460    public void setSystemProcess() {
2461        try {
2462            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2463            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2464            ServiceManager.addService("meminfo", new MemBinder(this));
2465            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2466            ServiceManager.addService("dbinfo", new DbBinder(this));
2467            if (MONITOR_CPU_USAGE) {
2468                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2469            }
2470            ServiceManager.addService("permission", new PermissionController(this));
2471            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2472
2473            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2474                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2475            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2476
2477            synchronized (this) {
2478                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2479                app.persistent = true;
2480                app.pid = MY_PID;
2481                app.maxAdj = ProcessList.SYSTEM_ADJ;
2482                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2483                synchronized (mPidsSelfLocked) {
2484                    mPidsSelfLocked.put(app.pid, app);
2485                }
2486                updateLruProcessLocked(app, false, null);
2487                updateOomAdjLocked();
2488            }
2489        } catch (PackageManager.NameNotFoundException e) {
2490            throw new RuntimeException(
2491                    "Unable to find android system package", e);
2492        }
2493    }
2494
2495    public void setWindowManager(WindowManagerService wm) {
2496        mWindowManager = wm;
2497        mStackSupervisor.setWindowManager(wm);
2498        mActivityStarter.setWindowManager(wm);
2499    }
2500
2501    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2502        mUsageStatsService = usageStatsManager;
2503    }
2504
2505    public void startObservingNativeCrashes() {
2506        final NativeCrashListener ncl = new NativeCrashListener(this);
2507        ncl.start();
2508    }
2509
2510    public IAppOpsService getAppOpsService() {
2511        return mAppOpsService;
2512    }
2513
2514    static class MemBinder extends Binder {
2515        ActivityManagerService mActivityManagerService;
2516        MemBinder(ActivityManagerService activityManagerService) {
2517            mActivityManagerService = activityManagerService;
2518        }
2519
2520        @Override
2521        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2522            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2523                    != PackageManager.PERMISSION_GRANTED) {
2524                pw.println("Permission Denial: can't dump meminfo from from pid="
2525                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2526                        + " without permission " + android.Manifest.permission.DUMP);
2527                return;
2528            }
2529
2530            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2531        }
2532    }
2533
2534    static class GraphicsBinder extends Binder {
2535        ActivityManagerService mActivityManagerService;
2536        GraphicsBinder(ActivityManagerService activityManagerService) {
2537            mActivityManagerService = activityManagerService;
2538        }
2539
2540        @Override
2541        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2542            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2543                    != PackageManager.PERMISSION_GRANTED) {
2544                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2545                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2546                        + " without permission " + android.Manifest.permission.DUMP);
2547                return;
2548            }
2549
2550            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2551        }
2552    }
2553
2554    static class DbBinder extends Binder {
2555        ActivityManagerService mActivityManagerService;
2556        DbBinder(ActivityManagerService activityManagerService) {
2557            mActivityManagerService = activityManagerService;
2558        }
2559
2560        @Override
2561        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2562            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2563                    != PackageManager.PERMISSION_GRANTED) {
2564                pw.println("Permission Denial: can't dump dbinfo from from pid="
2565                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2566                        + " without permission " + android.Manifest.permission.DUMP);
2567                return;
2568            }
2569
2570            mActivityManagerService.dumpDbInfo(fd, pw, args);
2571        }
2572    }
2573
2574    static class CpuBinder extends Binder {
2575        ActivityManagerService mActivityManagerService;
2576        CpuBinder(ActivityManagerService activityManagerService) {
2577            mActivityManagerService = activityManagerService;
2578        }
2579
2580        @Override
2581        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2582            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2583                    != PackageManager.PERMISSION_GRANTED) {
2584                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2585                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2586                        + " without permission " + android.Manifest.permission.DUMP);
2587                return;
2588            }
2589
2590            synchronized (mActivityManagerService.mProcessCpuTracker) {
2591                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2592                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2593                        SystemClock.uptimeMillis()));
2594            }
2595        }
2596    }
2597
2598    public static final class Lifecycle extends SystemService {
2599        private final ActivityManagerService mService;
2600
2601        public Lifecycle(Context context) {
2602            super(context);
2603            mService = new ActivityManagerService(context);
2604        }
2605
2606        @Override
2607        public void onStart() {
2608            mService.start();
2609        }
2610
2611        public ActivityManagerService getService() {
2612            return mService;
2613        }
2614    }
2615
2616    // Note: This method is invoked on the main thread but may need to attach various
2617    // handlers to other threads.  So take care to be explicit about the looper.
2618    public ActivityManagerService(Context systemContext) {
2619        mContext = systemContext;
2620        mFactoryTest = FactoryTest.getMode();
2621        mSystemThread = ActivityThread.currentActivityThread();
2622
2623        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2624
2625        mHandlerThread = new ServiceThread(TAG,
2626                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2627        mHandlerThread.start();
2628        mHandler = new MainHandler(mHandlerThread.getLooper());
2629        mUiHandler = new UiHandler();
2630
2631        /* static; one-time init here */
2632        if (sKillHandler == null) {
2633            sKillThread = new ServiceThread(TAG + ":kill",
2634                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2635            sKillThread.start();
2636            sKillHandler = new KillHandler(sKillThread.getLooper());
2637        }
2638
2639        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2640                "foreground", BROADCAST_FG_TIMEOUT, false);
2641        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2642                "background", BROADCAST_BG_TIMEOUT, true);
2643        mBroadcastQueues[0] = mFgBroadcastQueue;
2644        mBroadcastQueues[1] = mBgBroadcastQueue;
2645
2646        mServices = new ActiveServices(this);
2647        mProviderMap = new ProviderMap(this);
2648        mAppErrors = new AppErrors(mContext, this);
2649
2650        // TODO: Move creation of battery stats service outside of activity manager service.
2651        File dataDir = Environment.getDataDirectory();
2652        File systemDir = new File(dataDir, "system");
2653        systemDir.mkdirs();
2654        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2655        mBatteryStatsService.getActiveStatistics().readLocked();
2656        mBatteryStatsService.scheduleWriteToDisk();
2657        mOnBattery = DEBUG_POWER ? true
2658                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2659        mBatteryStatsService.getActiveStatistics().setCallback(this);
2660
2661        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2662
2663        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2664        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2665                new IAppOpsCallback.Stub() {
2666                    @Override public void opChanged(int op, int uid, String packageName) {
2667                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2668                            if (mAppOpsService.checkOperation(op, uid, packageName)
2669                                    != AppOpsManager.MODE_ALLOWED) {
2670                                runInBackgroundDisabled(uid);
2671                            }
2672                        }
2673                    }
2674                });
2675
2676        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2677
2678        mUserController = new UserController(this);
2679
2680        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2681            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2682
2683        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2684            mUseFifoUiScheduling = true;
2685        }
2686
2687        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2688
2689        mConfiguration.setToDefaults();
2690        mConfiguration.setLocales(LocaleList.getDefault());
2691
2692        mConfigurationSeq = mConfiguration.seq = 1;
2693        mProcessCpuTracker.init();
2694
2695        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2696        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2697        mStackSupervisor = new ActivityStackSupervisor(this);
2698        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2699        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2700
2701        mProcessCpuThread = new Thread("CpuTracker") {
2702            @Override
2703            public void run() {
2704                while (true) {
2705                    try {
2706                        try {
2707                            synchronized(this) {
2708                                final long now = SystemClock.uptimeMillis();
2709                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2710                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2711                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2712                                //        + ", write delay=" + nextWriteDelay);
2713                                if (nextWriteDelay < nextCpuDelay) {
2714                                    nextCpuDelay = nextWriteDelay;
2715                                }
2716                                if (nextCpuDelay > 0) {
2717                                    mProcessCpuMutexFree.set(true);
2718                                    this.wait(nextCpuDelay);
2719                                }
2720                            }
2721                        } catch (InterruptedException e) {
2722                        }
2723                        updateCpuStatsNow();
2724                    } catch (Exception e) {
2725                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2726                    }
2727                }
2728            }
2729        };
2730
2731        Watchdog.getInstance().addMonitor(this);
2732        Watchdog.getInstance().addThread(mHandler);
2733    }
2734
2735    public void setSystemServiceManager(SystemServiceManager mgr) {
2736        mSystemServiceManager = mgr;
2737    }
2738
2739    public void setInstaller(Installer installer) {
2740        mInstaller = installer;
2741    }
2742
2743    private void start() {
2744        Process.removeAllProcessGroups();
2745        mProcessCpuThread.start();
2746
2747        mBatteryStatsService.publish(mContext);
2748        mAppOpsService.publish(mContext);
2749        Slog.d("AppOps", "AppOpsService published");
2750        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2751    }
2752
2753    void onUserStoppedLocked(int userId) {
2754        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2755    }
2756
2757    public void initPowerManagement() {
2758        mStackSupervisor.initPowerManagement();
2759        mBatteryStatsService.initPowerManagement();
2760        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2761        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2762        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2763        mVoiceWakeLock.setReferenceCounted(false);
2764    }
2765
2766    @Override
2767    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2768            throws RemoteException {
2769        if (code == SYSPROPS_TRANSACTION) {
2770            // We need to tell all apps about the system property change.
2771            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2772            synchronized(this) {
2773                final int NP = mProcessNames.getMap().size();
2774                for (int ip=0; ip<NP; ip++) {
2775                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2776                    final int NA = apps.size();
2777                    for (int ia=0; ia<NA; ia++) {
2778                        ProcessRecord app = apps.valueAt(ia);
2779                        if (app.thread != null) {
2780                            procs.add(app.thread.asBinder());
2781                        }
2782                    }
2783                }
2784            }
2785
2786            int N = procs.size();
2787            for (int i=0; i<N; i++) {
2788                Parcel data2 = Parcel.obtain();
2789                try {
2790                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2791                } catch (RemoteException e) {
2792                }
2793                data2.recycle();
2794            }
2795        }
2796        try {
2797            return super.onTransact(code, data, reply, flags);
2798        } catch (RuntimeException e) {
2799            // The activity manager only throws security exceptions, so let's
2800            // log all others.
2801            if (!(e instanceof SecurityException)) {
2802                Slog.wtf(TAG, "Activity Manager Crash", e);
2803            }
2804            throw e;
2805        }
2806    }
2807
2808    void updateCpuStats() {
2809        final long now = SystemClock.uptimeMillis();
2810        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2811            return;
2812        }
2813        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2814            synchronized (mProcessCpuThread) {
2815                mProcessCpuThread.notify();
2816            }
2817        }
2818    }
2819
2820    void updateCpuStatsNow() {
2821        synchronized (mProcessCpuTracker) {
2822            mProcessCpuMutexFree.set(false);
2823            final long now = SystemClock.uptimeMillis();
2824            boolean haveNewCpuStats = false;
2825
2826            if (MONITOR_CPU_USAGE &&
2827                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2828                mLastCpuTime.set(now);
2829                mProcessCpuTracker.update();
2830                if (mProcessCpuTracker.hasGoodLastStats()) {
2831                    haveNewCpuStats = true;
2832                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2833                    //Slog.i(TAG, "Total CPU usage: "
2834                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2835
2836                    // Slog the cpu usage if the property is set.
2837                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2838                        int user = mProcessCpuTracker.getLastUserTime();
2839                        int system = mProcessCpuTracker.getLastSystemTime();
2840                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2841                        int irq = mProcessCpuTracker.getLastIrqTime();
2842                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2843                        int idle = mProcessCpuTracker.getLastIdleTime();
2844
2845                        int total = user + system + iowait + irq + softIrq + idle;
2846                        if (total == 0) total = 1;
2847
2848                        EventLog.writeEvent(EventLogTags.CPU,
2849                                ((user+system+iowait+irq+softIrq) * 100) / total,
2850                                (user * 100) / total,
2851                                (system * 100) / total,
2852                                (iowait * 100) / total,
2853                                (irq * 100) / total,
2854                                (softIrq * 100) / total);
2855                    }
2856                }
2857            }
2858
2859            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2860            synchronized(bstats) {
2861                synchronized(mPidsSelfLocked) {
2862                    if (haveNewCpuStats) {
2863                        if (bstats.startAddingCpuLocked()) {
2864                            int totalUTime = 0;
2865                            int totalSTime = 0;
2866                            final int N = mProcessCpuTracker.countStats();
2867                            for (int i=0; i<N; i++) {
2868                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2869                                if (!st.working) {
2870                                    continue;
2871                                }
2872                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2873                                totalUTime += st.rel_utime;
2874                                totalSTime += st.rel_stime;
2875                                if (pr != null) {
2876                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2877                                    if (ps == null || !ps.isActive()) {
2878                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2879                                                pr.info.uid, pr.processName);
2880                                    }
2881                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2882                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2883                                } else {
2884                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2885                                    if (ps == null || !ps.isActive()) {
2886                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2887                                                bstats.mapUid(st.uid), st.name);
2888                                    }
2889                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2890                                }
2891                            }
2892                            final int userTime = mProcessCpuTracker.getLastUserTime();
2893                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2894                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2895                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2896                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2897                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2898                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2899                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2900                        }
2901                    }
2902                }
2903
2904                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2905                    mLastWriteTime = now;
2906                    mBatteryStatsService.scheduleWriteToDisk();
2907                }
2908            }
2909        }
2910    }
2911
2912    @Override
2913    public void batteryNeedsCpuUpdate() {
2914        updateCpuStatsNow();
2915    }
2916
2917    @Override
2918    public void batteryPowerChanged(boolean onBattery) {
2919        // When plugging in, update the CPU stats first before changing
2920        // the plug state.
2921        updateCpuStatsNow();
2922        synchronized (this) {
2923            synchronized(mPidsSelfLocked) {
2924                mOnBattery = DEBUG_POWER ? true : onBattery;
2925            }
2926        }
2927    }
2928
2929    @Override
2930    public void batterySendBroadcast(Intent intent) {
2931        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2932                AppOpsManager.OP_NONE, null, false, false,
2933                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2934    }
2935
2936    /**
2937     * Initialize the application bind args. These are passed to each
2938     * process when the bindApplication() IPC is sent to the process. They're
2939     * lazily setup to make sure the services are running when they're asked for.
2940     */
2941    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2942        // Isolated processes won't get this optimization, so that we don't
2943        // violate the rules about which services they have access to.
2944        if (isolated) {
2945            if (mIsolatedAppBindArgs == null) {
2946                mIsolatedAppBindArgs = new HashMap<>();
2947                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2948            }
2949            return mIsolatedAppBindArgs;
2950        }
2951
2952        if (mAppBindArgs == null) {
2953            mAppBindArgs = new HashMap<>();
2954
2955            // Setup the application init args
2956            mAppBindArgs.put("package", ServiceManager.getService("package"));
2957            mAppBindArgs.put("window", ServiceManager.getService("window"));
2958            mAppBindArgs.put(Context.ALARM_SERVICE,
2959                    ServiceManager.getService(Context.ALARM_SERVICE));
2960        }
2961        return mAppBindArgs;
2962    }
2963
2964    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2965        if (r == null || mFocusedActivity == r) {
2966            return false;
2967        }
2968
2969        if (!r.isFocusable()) {
2970            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2971            return false;
2972        }
2973
2974        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2975
2976        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2977        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2978                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2979        mDoingSetFocusedActivity = true;
2980
2981        final ActivityRecord last = mFocusedActivity;
2982        mFocusedActivity = r;
2983        if (r.task.isApplicationTask()) {
2984            if (mCurAppTimeTracker != r.appTimeTracker) {
2985                // We are switching app tracking.  Complete the current one.
2986                if (mCurAppTimeTracker != null) {
2987                    mCurAppTimeTracker.stop();
2988                    mHandler.obtainMessage(
2989                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2990                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2991                    mCurAppTimeTracker = null;
2992                }
2993                if (r.appTimeTracker != null) {
2994                    mCurAppTimeTracker = r.appTimeTracker;
2995                    startTimeTrackingFocusedActivityLocked();
2996                }
2997            } else {
2998                startTimeTrackingFocusedActivityLocked();
2999            }
3000        } else {
3001            r.appTimeTracker = null;
3002        }
3003        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3004        // TODO: Probably not, because we don't want to resume voice on switching
3005        // back to this activity
3006        if (r.task.voiceInteractor != null) {
3007            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3008        } else {
3009            finishRunningVoiceLocked();
3010            IVoiceInteractionSession session;
3011            if (last != null && ((session = last.task.voiceSession) != null
3012                    || (session = last.voiceSession) != null)) {
3013                // We had been in a voice interaction session, but now focused has
3014                // move to something different.  Just finish the session, we can't
3015                // return to it and retain the proper state and synchronization with
3016                // the voice interaction service.
3017                finishVoiceTask(session);
3018            }
3019        }
3020        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3021            mWindowManager.setFocusedApp(r.appToken, true);
3022        }
3023        applyUpdateLockStateLocked(r);
3024        applyUpdateVrModeLocked(r);
3025        if (mFocusedActivity.userId != mLastFocusedUserId) {
3026            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3027            mHandler.obtainMessage(
3028                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3029            mLastFocusedUserId = mFocusedActivity.userId;
3030        }
3031
3032        // Log a warning if the focused app is changed during the process. This could
3033        // indicate a problem of the focus setting logic!
3034        if (mFocusedActivity != r) Slog.w(TAG,
3035                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3036        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3037
3038        EventLogTags.writeAmFocusedActivity(
3039                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3040                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3041                reason);
3042        return true;
3043    }
3044
3045    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3046        if (mFocusedActivity != goingAway) {
3047            return;
3048        }
3049
3050        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3051        if (focusedStack != null) {
3052            final ActivityRecord top = focusedStack.topActivity();
3053            if (top != null && top.userId != mLastFocusedUserId) {
3054                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3055                mHandler.sendMessage(
3056                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3057                mLastFocusedUserId = top.userId;
3058            }
3059        }
3060
3061        // Try to move focus to another activity if possible.
3062        if (setFocusedActivityLocked(
3063                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3064            return;
3065        }
3066
3067        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3068                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3069        mFocusedActivity = null;
3070        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3071    }
3072
3073    @Override
3074    public void setFocusedStack(int stackId) {
3075        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3076        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3077        final long callingId = Binder.clearCallingIdentity();
3078        try {
3079            synchronized (this) {
3080                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3081                if (stack == null) {
3082                    return;
3083                }
3084                final ActivityRecord r = stack.topRunningActivityLocked();
3085                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3086                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3087                }
3088            }
3089        } finally {
3090            Binder.restoreCallingIdentity(callingId);
3091        }
3092    }
3093
3094    @Override
3095    public void setFocusedTask(int taskId) {
3096        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3097        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3098        final long callingId = Binder.clearCallingIdentity();
3099        try {
3100            synchronized (this) {
3101                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3102                if (task == null) {
3103                    return;
3104                }
3105                if (mUserController.shouldConfirmCredentials(task.userId)) {
3106                    mActivityStarter.showConfirmDeviceCredential(task.userId);
3107                    if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3108                        mStackSupervisor.moveTaskToStackLocked(task.taskId,
3109                                FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3110                                "setFocusedTask", ANIMATE);
3111                    }
3112                    return;
3113                }
3114                final ActivityRecord r = task.topRunningActivityLocked();
3115                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3116                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3117                }
3118            }
3119        } finally {
3120            Binder.restoreCallingIdentity(callingId);
3121        }
3122    }
3123
3124    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3125    @Override
3126    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3127        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3128        synchronized (this) {
3129            if (listener != null) {
3130                mTaskStackListeners.register(listener);
3131            }
3132        }
3133    }
3134
3135    @Override
3136    public void notifyActivityDrawn(IBinder token) {
3137        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3138        synchronized (this) {
3139            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3140            if (r != null) {
3141                r.task.stack.notifyActivityDrawnLocked(r);
3142            }
3143        }
3144    }
3145
3146    final void applyUpdateLockStateLocked(ActivityRecord r) {
3147        // Modifications to the UpdateLock state are done on our handler, outside
3148        // the activity manager's locks.  The new state is determined based on the
3149        // state *now* of the relevant activity record.  The object is passed to
3150        // the handler solely for logging detail, not to be consulted/modified.
3151        final boolean nextState = r != null && r.immersive;
3152        mHandler.sendMessage(
3153                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3154    }
3155
3156    final void applyUpdateVrModeLocked(ActivityRecord r) {
3157        mHandler.sendMessage(
3158                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3159    }
3160
3161    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3162        mHandler.sendMessage(
3163                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3164    }
3165
3166    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3167            ComponentName callingPackage, boolean immediate) {
3168        VrManagerInternal vrService =
3169                LocalServices.getService(VrManagerInternal.class);
3170        if (immediate) {
3171            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3172        } else {
3173            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3174        }
3175    }
3176
3177    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3178        Message msg = Message.obtain();
3179        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3180        msg.obj = r.task.askedCompatMode ? null : r;
3181        mUiHandler.sendMessage(msg);
3182    }
3183
3184    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3185        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3186                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3187            final Message msg = Message.obtain();
3188            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3189            msg.obj = r;
3190            mUiHandler.sendMessage(msg);
3191        }
3192    }
3193
3194    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3195            String what, Object obj, ProcessRecord srcApp) {
3196        app.lastActivityTime = now;
3197
3198        if (app.activities.size() > 0) {
3199            // Don't want to touch dependent processes that are hosting activities.
3200            return index;
3201        }
3202
3203        int lrui = mLruProcesses.lastIndexOf(app);
3204        if (lrui < 0) {
3205            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3206                    + what + " " + obj + " from " + srcApp);
3207            return index;
3208        }
3209
3210        if (lrui >= index) {
3211            // Don't want to cause this to move dependent processes *back* in the
3212            // list as if they were less frequently used.
3213            return index;
3214        }
3215
3216        if (lrui >= mLruProcessActivityStart) {
3217            // Don't want to touch dependent processes that are hosting activities.
3218            return index;
3219        }
3220
3221        mLruProcesses.remove(lrui);
3222        if (index > 0) {
3223            index--;
3224        }
3225        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3226                + " in LRU list: " + app);
3227        mLruProcesses.add(index, app);
3228        return index;
3229    }
3230
3231    static void killProcessGroup(int uid, int pid) {
3232        if (sKillHandler != null) {
3233            sKillHandler.sendMessage(
3234                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3235        } else {
3236            Slog.w(TAG, "Asked to kill process group before system bringup!");
3237            Process.killProcessGroup(uid, pid);
3238        }
3239    }
3240
3241    final void removeLruProcessLocked(ProcessRecord app) {
3242        int lrui = mLruProcesses.lastIndexOf(app);
3243        if (lrui >= 0) {
3244            if (!app.killed) {
3245                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3246                Process.killProcessQuiet(app.pid);
3247                killProcessGroup(app.uid, app.pid);
3248            }
3249            if (lrui <= mLruProcessActivityStart) {
3250                mLruProcessActivityStart--;
3251            }
3252            if (lrui <= mLruProcessServiceStart) {
3253                mLruProcessServiceStart--;
3254            }
3255            mLruProcesses.remove(lrui);
3256        }
3257    }
3258
3259    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3260            ProcessRecord client) {
3261        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3262                || app.treatLikeActivity;
3263        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3264        if (!activityChange && hasActivity) {
3265            // The process has activities, so we are only allowing activity-based adjustments
3266            // to move it.  It should be kept in the front of the list with other
3267            // processes that have activities, and we don't want those to change their
3268            // order except due to activity operations.
3269            return;
3270        }
3271
3272        mLruSeq++;
3273        final long now = SystemClock.uptimeMillis();
3274        app.lastActivityTime = now;
3275
3276        // First a quick reject: if the app is already at the position we will
3277        // put it, then there is nothing to do.
3278        if (hasActivity) {
3279            final int N = mLruProcesses.size();
3280            if (N > 0 && mLruProcesses.get(N-1) == app) {
3281                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3282                return;
3283            }
3284        } else {
3285            if (mLruProcessServiceStart > 0
3286                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3287                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3288                return;
3289            }
3290        }
3291
3292        int lrui = mLruProcesses.lastIndexOf(app);
3293
3294        if (app.persistent && lrui >= 0) {
3295            // We don't care about the position of persistent processes, as long as
3296            // they are in the list.
3297            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3298            return;
3299        }
3300
3301        /* In progress: compute new position first, so we can avoid doing work
3302           if the process is not actually going to move.  Not yet working.
3303        int addIndex;
3304        int nextIndex;
3305        boolean inActivity = false, inService = false;
3306        if (hasActivity) {
3307            // Process has activities, put it at the very tipsy-top.
3308            addIndex = mLruProcesses.size();
3309            nextIndex = mLruProcessServiceStart;
3310            inActivity = true;
3311        } else if (hasService) {
3312            // Process has services, put it at the top of the service list.
3313            addIndex = mLruProcessActivityStart;
3314            nextIndex = mLruProcessServiceStart;
3315            inActivity = true;
3316            inService = true;
3317        } else  {
3318            // Process not otherwise of interest, it goes to the top of the non-service area.
3319            addIndex = mLruProcessServiceStart;
3320            if (client != null) {
3321                int clientIndex = mLruProcesses.lastIndexOf(client);
3322                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3323                        + app);
3324                if (clientIndex >= 0 && addIndex > clientIndex) {
3325                    addIndex = clientIndex;
3326                }
3327            }
3328            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3329        }
3330
3331        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3332                + mLruProcessActivityStart + "): " + app);
3333        */
3334
3335        if (lrui >= 0) {
3336            if (lrui < mLruProcessActivityStart) {
3337                mLruProcessActivityStart--;
3338            }
3339            if (lrui < mLruProcessServiceStart) {
3340                mLruProcessServiceStart--;
3341            }
3342            /*
3343            if (addIndex > lrui) {
3344                addIndex--;
3345            }
3346            if (nextIndex > lrui) {
3347                nextIndex--;
3348            }
3349            */
3350            mLruProcesses.remove(lrui);
3351        }
3352
3353        /*
3354        mLruProcesses.add(addIndex, app);
3355        if (inActivity) {
3356            mLruProcessActivityStart++;
3357        }
3358        if (inService) {
3359            mLruProcessActivityStart++;
3360        }
3361        */
3362
3363        int nextIndex;
3364        if (hasActivity) {
3365            final int N = mLruProcesses.size();
3366            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3367                // Process doesn't have activities, but has clients with
3368                // activities...  move it up, but one below the top (the top
3369                // should always have a real activity).
3370                if (DEBUG_LRU) Slog.d(TAG_LRU,
3371                        "Adding to second-top of LRU activity list: " + app);
3372                mLruProcesses.add(N - 1, app);
3373                // To keep it from spamming the LRU list (by making a bunch of clients),
3374                // we will push down any other entries owned by the app.
3375                final int uid = app.info.uid;
3376                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3377                    ProcessRecord subProc = mLruProcesses.get(i);
3378                    if (subProc.info.uid == uid) {
3379                        // We want to push this one down the list.  If the process after
3380                        // it is for the same uid, however, don't do so, because we don't
3381                        // want them internally to be re-ordered.
3382                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3383                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3384                                    "Pushing uid " + uid + " swapping at " + i + ": "
3385                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3386                            ProcessRecord tmp = mLruProcesses.get(i);
3387                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3388                            mLruProcesses.set(i - 1, tmp);
3389                            i--;
3390                        }
3391                    } else {
3392                        // A gap, we can stop here.
3393                        break;
3394                    }
3395                }
3396            } else {
3397                // Process has activities, put it at the very tipsy-top.
3398                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3399                mLruProcesses.add(app);
3400            }
3401            nextIndex = mLruProcessServiceStart;
3402        } else if (hasService) {
3403            // Process has services, put it at the top of the service list.
3404            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3405            mLruProcesses.add(mLruProcessActivityStart, app);
3406            nextIndex = mLruProcessServiceStart;
3407            mLruProcessActivityStart++;
3408        } else  {
3409            // Process not otherwise of interest, it goes to the top of the non-service area.
3410            int index = mLruProcessServiceStart;
3411            if (client != null) {
3412                // If there is a client, don't allow the process to be moved up higher
3413                // in the list than that client.
3414                int clientIndex = mLruProcesses.lastIndexOf(client);
3415                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3416                        + " when updating " + app);
3417                if (clientIndex <= lrui) {
3418                    // Don't allow the client index restriction to push it down farther in the
3419                    // list than it already is.
3420                    clientIndex = lrui;
3421                }
3422                if (clientIndex >= 0 && index > clientIndex) {
3423                    index = clientIndex;
3424                }
3425            }
3426            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3427            mLruProcesses.add(index, app);
3428            nextIndex = index-1;
3429            mLruProcessActivityStart++;
3430            mLruProcessServiceStart++;
3431        }
3432
3433        // If the app is currently using a content provider or service,
3434        // bump those processes as well.
3435        for (int j=app.connections.size()-1; j>=0; j--) {
3436            ConnectionRecord cr = app.connections.valueAt(j);
3437            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3438                    && cr.binding.service.app != null
3439                    && cr.binding.service.app.lruSeq != mLruSeq
3440                    && !cr.binding.service.app.persistent) {
3441                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3442                        "service connection", cr, app);
3443            }
3444        }
3445        for (int j=app.conProviders.size()-1; j>=0; j--) {
3446            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3447            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3448                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3449                        "provider reference", cpr, app);
3450            }
3451        }
3452    }
3453
3454    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3455        if (uid == Process.SYSTEM_UID) {
3456            // The system gets to run in any process.  If there are multiple
3457            // processes with the same uid, just pick the first (this
3458            // should never happen).
3459            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3460            if (procs == null) return null;
3461            final int procCount = procs.size();
3462            for (int i = 0; i < procCount; i++) {
3463                final int procUid = procs.keyAt(i);
3464                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3465                    // Don't use an app process or different user process for system component.
3466                    continue;
3467                }
3468                return procs.valueAt(i);
3469            }
3470        }
3471        ProcessRecord proc = mProcessNames.get(processName, uid);
3472        if (false && proc != null && !keepIfLarge
3473                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3474                && proc.lastCachedPss >= 4000) {
3475            // Turn this condition on to cause killing to happen regularly, for testing.
3476            if (proc.baseProcessTracker != null) {
3477                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3478            }
3479            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3480        } else if (proc != null && !keepIfLarge
3481                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3482                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3483            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3484            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3485                if (proc.baseProcessTracker != null) {
3486                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3487                }
3488                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3489            }
3490        }
3491        return proc;
3492    }
3493
3494    void notifyPackageUse(String packageName, int reason) {
3495        IPackageManager pm = AppGlobals.getPackageManager();
3496        try {
3497            pm.notifyPackageUse(packageName, reason);
3498        } catch (RemoteException e) {
3499        }
3500    }
3501
3502    boolean isNextTransitionForward() {
3503        int transit = mWindowManager.getPendingAppTransition();
3504        return transit == TRANSIT_ACTIVITY_OPEN
3505                || transit == TRANSIT_TASK_OPEN
3506                || transit == TRANSIT_TASK_TO_FRONT;
3507    }
3508
3509    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3510            String processName, String abiOverride, int uid, Runnable crashHandler) {
3511        synchronized(this) {
3512            ApplicationInfo info = new ApplicationInfo();
3513            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3514            // For isolated processes, the former contains the parent's uid and the latter the
3515            // actual uid of the isolated process.
3516            // In the special case introduced by this method (which is, starting an isolated
3517            // process directly from the SystemServer without an actual parent app process) the
3518            // closest thing to a parent's uid is SYSTEM_UID.
3519            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3520            // the |isolated| logic in the ProcessRecord constructor.
3521            info.uid = Process.SYSTEM_UID;
3522            info.processName = processName;
3523            info.className = entryPoint;
3524            info.packageName = "android";
3525            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3526                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3527                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3528                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3529                    crashHandler);
3530            return proc != null ? proc.pid : 0;
3531        }
3532    }
3533
3534    final ProcessRecord startProcessLocked(String processName,
3535            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3536            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3537            boolean isolated, boolean keepIfLarge) {
3538        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3539                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3540                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3541                null /* crashHandler */);
3542    }
3543
3544    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3545            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3546            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3547            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3548        long startTime = SystemClock.elapsedRealtime();
3549        ProcessRecord app;
3550        if (!isolated) {
3551            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3552            checkTime(startTime, "startProcess: after getProcessRecord");
3553
3554            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3555                // If we are in the background, then check to see if this process
3556                // is bad.  If so, we will just silently fail.
3557                if (mAppErrors.isBadProcessLocked(info)) {
3558                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3559                            + "/" + info.processName);
3560                    return null;
3561                }
3562            } else {
3563                // When the user is explicitly starting a process, then clear its
3564                // crash count so that we won't make it bad until they see at
3565                // least one crash dialog again, and make the process good again
3566                // if it had been bad.
3567                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3568                        + "/" + info.processName);
3569                mAppErrors.resetProcessCrashTimeLocked(info);
3570                if (mAppErrors.isBadProcessLocked(info)) {
3571                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3572                            UserHandle.getUserId(info.uid), info.uid,
3573                            info.processName);
3574                    mAppErrors.clearBadProcessLocked(info);
3575                    if (app != null) {
3576                        app.bad = false;
3577                    }
3578                }
3579            }
3580        } else {
3581            // If this is an isolated process, it can't re-use an existing process.
3582            app = null;
3583        }
3584
3585        // app launch boost for big.little configurations
3586        // use cpusets to migrate freshly launched tasks to big cores
3587        nativeMigrateToBoost();
3588        mIsBoosted = true;
3589        mBoostStartTime = SystemClock.uptimeMillis();
3590        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3591        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3592
3593        // We don't have to do anything more if:
3594        // (1) There is an existing application record; and
3595        // (2) The caller doesn't think it is dead, OR there is no thread
3596        //     object attached to it so we know it couldn't have crashed; and
3597        // (3) There is a pid assigned to it, so it is either starting or
3598        //     already running.
3599        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3600                + " app=" + app + " knownToBeDead=" + knownToBeDead
3601                + " thread=" + (app != null ? app.thread : null)
3602                + " pid=" + (app != null ? app.pid : -1));
3603        if (app != null && app.pid > 0) {
3604            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3605                // We already have the app running, or are waiting for it to
3606                // come up (we have a pid but not yet its thread), so keep it.
3607                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3608                // If this is a new package in the process, add the package to the list
3609                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3610                checkTime(startTime, "startProcess: done, added package to proc");
3611                return app;
3612            }
3613
3614            // An application record is attached to a previous process,
3615            // clean it up now.
3616            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3617            checkTime(startTime, "startProcess: bad proc running, killing");
3618            killProcessGroup(app.uid, app.pid);
3619            handleAppDiedLocked(app, true, true);
3620            checkTime(startTime, "startProcess: done killing old proc");
3621        }
3622
3623        String hostingNameStr = hostingName != null
3624                ? hostingName.flattenToShortString() : null;
3625
3626        if (app == null) {
3627            checkTime(startTime, "startProcess: creating new process record");
3628            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3629            if (app == null) {
3630                Slog.w(TAG, "Failed making new process record for "
3631                        + processName + "/" + info.uid + " isolated=" + isolated);
3632                return null;
3633            }
3634            app.crashHandler = crashHandler;
3635            checkTime(startTime, "startProcess: done creating new process record");
3636        } else {
3637            // If this is a new package in the process, add the package to the list
3638            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3639            checkTime(startTime, "startProcess: added package to existing proc");
3640        }
3641
3642        // If the system is not ready yet, then hold off on starting this
3643        // process until it is.
3644        if (!mProcessesReady
3645                && !isAllowedWhileBooting(info)
3646                && !allowWhileBooting) {
3647            if (!mProcessesOnHold.contains(app)) {
3648                mProcessesOnHold.add(app);
3649            }
3650            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3651                    "System not ready, putting on hold: " + app);
3652            checkTime(startTime, "startProcess: returning with proc on hold");
3653            return app;
3654        }
3655
3656        checkTime(startTime, "startProcess: stepping in to startProcess");
3657        startProcessLocked(
3658                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3659        checkTime(startTime, "startProcess: done starting proc!");
3660        return (app.pid != 0) ? app : null;
3661    }
3662
3663    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3664        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3665    }
3666
3667    private final void startProcessLocked(ProcessRecord app,
3668            String hostingType, String hostingNameStr) {
3669        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3670                null /* entryPoint */, null /* entryPointArgs */);
3671    }
3672
3673    private final void startProcessLocked(ProcessRecord app, String hostingType,
3674            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3675        long startTime = SystemClock.elapsedRealtime();
3676        if (app.pid > 0 && app.pid != MY_PID) {
3677            checkTime(startTime, "startProcess: removing from pids map");
3678            synchronized (mPidsSelfLocked) {
3679                mPidsSelfLocked.remove(app.pid);
3680                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3681            }
3682            checkTime(startTime, "startProcess: done removing from pids map");
3683            app.setPid(0);
3684        }
3685
3686        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3687                "startProcessLocked removing on hold: " + app);
3688        mProcessesOnHold.remove(app);
3689
3690        checkTime(startTime, "startProcess: starting to update cpu stats");
3691        updateCpuStats();
3692        checkTime(startTime, "startProcess: done updating cpu stats");
3693
3694        try {
3695            try {
3696                final int userId = UserHandle.getUserId(app.uid);
3697                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3698            } catch (RemoteException e) {
3699                throw e.rethrowAsRuntimeException();
3700            }
3701
3702            int uid = app.uid;
3703            int[] gids = null;
3704            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3705            if (!app.isolated) {
3706                int[] permGids = null;
3707                try {
3708                    checkTime(startTime, "startProcess: getting gids from package manager");
3709                    final IPackageManager pm = AppGlobals.getPackageManager();
3710                    permGids = pm.getPackageGids(app.info.packageName,
3711                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3712                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3713                            MountServiceInternal.class);
3714                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3715                            app.info.packageName);
3716                } catch (RemoteException e) {
3717                    throw e.rethrowAsRuntimeException();
3718                }
3719
3720                /*
3721                 * Add shared application and profile GIDs so applications can share some
3722                 * resources like shared libraries and access user-wide resources
3723                 */
3724                if (ArrayUtils.isEmpty(permGids)) {
3725                    gids = new int[2];
3726                } else {
3727                    gids = new int[permGids.length + 2];
3728                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3729                }
3730                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3731                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3732            }
3733            checkTime(startTime, "startProcess: building args");
3734            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3735                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3736                        && mTopComponent != null
3737                        && app.processName.equals(mTopComponent.getPackageName())) {
3738                    uid = 0;
3739                }
3740                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3741                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3742                    uid = 0;
3743                }
3744            }
3745            int debugFlags = 0;
3746            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3747                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3748                // Also turn on CheckJNI for debuggable apps. It's quite
3749                // awkward to turn on otherwise.
3750                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3751            }
3752            // Run the app in safe mode if its manifest requests so or the
3753            // system is booted in safe mode.
3754            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3755                mSafeMode == true) {
3756                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3757            }
3758            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3759                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3760            }
3761            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3762            if ("true".equals(genDebugInfoProperty)) {
3763                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3764            }
3765            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3766                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3767            }
3768            if ("1".equals(SystemProperties.get("debug.assert"))) {
3769                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3770            }
3771            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3772                // Enable all debug flags required by the native debugger.
3773                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3774                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3775                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3776                mNativeDebuggingApp = null;
3777            }
3778
3779            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3780            if (requiredAbi == null) {
3781                requiredAbi = Build.SUPPORTED_ABIS[0];
3782            }
3783
3784            String instructionSet = null;
3785            if (app.info.primaryCpuAbi != null) {
3786                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3787            }
3788
3789            app.gids = gids;
3790            app.requiredAbi = requiredAbi;
3791            app.instructionSet = instructionSet;
3792
3793            // Start the process.  It will either succeed and return a result containing
3794            // the PID of the new process, or else throw a RuntimeException.
3795            boolean isActivityProcess = (entryPoint == null);
3796            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3797            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3798                    app.processName);
3799            checkTime(startTime, "startProcess: asking zygote to start proc");
3800            Process.ProcessStartResult startResult = Process.start(entryPoint,
3801                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3802                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3803                    app.info.dataDir, entryPointArgs);
3804            checkTime(startTime, "startProcess: returned from zygote!");
3805            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3806
3807            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3808            checkTime(startTime, "startProcess: done updating battery stats");
3809
3810            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3811                    UserHandle.getUserId(uid), startResult.pid, uid,
3812                    app.processName, hostingType,
3813                    hostingNameStr != null ? hostingNameStr : "");
3814
3815            try {
3816                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3817                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3818            } catch (RemoteException ex) {
3819                // Ignore
3820            }
3821
3822            if (app.persistent) {
3823                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3824            }
3825
3826            checkTime(startTime, "startProcess: building log message");
3827            StringBuilder buf = mStringBuilder;
3828            buf.setLength(0);
3829            buf.append("Start proc ");
3830            buf.append(startResult.pid);
3831            buf.append(':');
3832            buf.append(app.processName);
3833            buf.append('/');
3834            UserHandle.formatUid(buf, uid);
3835            if (!isActivityProcess) {
3836                buf.append(" [");
3837                buf.append(entryPoint);
3838                buf.append("]");
3839            }
3840            buf.append(" for ");
3841            buf.append(hostingType);
3842            if (hostingNameStr != null) {
3843                buf.append(" ");
3844                buf.append(hostingNameStr);
3845            }
3846            Slog.i(TAG, buf.toString());
3847            app.setPid(startResult.pid);
3848            app.usingWrapper = startResult.usingWrapper;
3849            app.removed = false;
3850            app.killed = false;
3851            app.killedByAm = false;
3852            checkTime(startTime, "startProcess: starting to update pids map");
3853            ProcessRecord oldApp;
3854            synchronized (mPidsSelfLocked) {
3855                oldApp = mPidsSelfLocked.get(startResult.pid);
3856            }
3857            // If there is already an app occupying that pid that hasn't been cleaned up
3858            if (oldApp != null && !app.isolated) {
3859                // Clean up anything relating to this pid first
3860                Slog.w(TAG, "Reusing pid " + startResult.pid
3861                        + " while app is still mapped to it");
3862                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3863                        true /*replacingPid*/);
3864            }
3865            synchronized (mPidsSelfLocked) {
3866                this.mPidsSelfLocked.put(startResult.pid, app);
3867                if (isActivityProcess) {
3868                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3869                    msg.obj = app;
3870                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3871                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3872                }
3873            }
3874            checkTime(startTime, "startProcess: done updating pids map");
3875        } catch (RuntimeException e) {
3876            Slog.e(TAG, "Failure starting process " + app.processName, e);
3877
3878            // Something went very wrong while trying to start this process; one
3879            // common case is when the package is frozen due to an active
3880            // upgrade. To recover, clean up any active bookkeeping related to
3881            // starting this process. (We already invoked this method once when
3882            // the package was initially frozen through KILL_APPLICATION_MSG, so
3883            // it doesn't hurt to use it again.)
3884            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3885                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3886        }
3887    }
3888
3889    void updateUsageStats(ActivityRecord component, boolean resumed) {
3890        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3891                "updateUsageStats: comp=" + component + "res=" + resumed);
3892        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3893        if (resumed) {
3894            if (mUsageStatsService != null) {
3895                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3896                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3897            }
3898            synchronized (stats) {
3899                stats.noteActivityResumedLocked(component.app.uid);
3900            }
3901        } else {
3902            if (mUsageStatsService != null) {
3903                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3904                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3905            }
3906            synchronized (stats) {
3907                stats.noteActivityPausedLocked(component.app.uid);
3908            }
3909        }
3910    }
3911
3912    Intent getHomeIntent() {
3913        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3914        intent.setComponent(mTopComponent);
3915        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3916        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3917            intent.addCategory(Intent.CATEGORY_HOME);
3918        }
3919        return intent;
3920    }
3921
3922    boolean startHomeActivityLocked(int userId, String reason) {
3923        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3924                && mTopAction == null) {
3925            // We are running in factory test mode, but unable to find
3926            // the factory test app, so just sit around displaying the
3927            // error message and don't try to start anything.
3928            return false;
3929        }
3930        Intent intent = getHomeIntent();
3931        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3932        if (aInfo != null) {
3933            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3934            // Don't do this if the home app is currently being
3935            // instrumented.
3936            aInfo = new ActivityInfo(aInfo);
3937            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3938            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3939                    aInfo.applicationInfo.uid, true);
3940            if (app == null || app.instrumentationClass == null) {
3941                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3942                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3943            }
3944        } else {
3945            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3946        }
3947
3948        return true;
3949    }
3950
3951    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3952        ActivityInfo ai = null;
3953        ComponentName comp = intent.getComponent();
3954        try {
3955            if (comp != null) {
3956                // Factory test.
3957                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3958            } else {
3959                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3960                        intent,
3961                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3962                        flags, userId);
3963
3964                if (info != null) {
3965                    ai = info.activityInfo;
3966                }
3967            }
3968        } catch (RemoteException e) {
3969            // ignore
3970        }
3971
3972        return ai;
3973    }
3974
3975    /**
3976     * Starts the "new version setup screen" if appropriate.
3977     */
3978    void startSetupActivityLocked() {
3979        // Only do this once per boot.
3980        if (mCheckedForSetup) {
3981            return;
3982        }
3983
3984        // We will show this screen if the current one is a different
3985        // version than the last one shown, and we are not running in
3986        // low-level factory test mode.
3987        final ContentResolver resolver = mContext.getContentResolver();
3988        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3989                Settings.Global.getInt(resolver,
3990                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3991            mCheckedForSetup = true;
3992
3993            // See if we should be showing the platform update setup UI.
3994            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3995            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3996                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3997            if (!ris.isEmpty()) {
3998                final ResolveInfo ri = ris.get(0);
3999                String vers = ri.activityInfo.metaData != null
4000                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4001                        : null;
4002                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4003                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4004                            Intent.METADATA_SETUP_VERSION);
4005                }
4006                String lastVers = Settings.Secure.getString(
4007                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4008                if (vers != null && !vers.equals(lastVers)) {
4009                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4010                    intent.setComponent(new ComponentName(
4011                            ri.activityInfo.packageName, ri.activityInfo.name));
4012                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4013                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4014                            null, 0, 0, 0, null, false, false, null, null, null);
4015                }
4016            }
4017        }
4018    }
4019
4020    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4021        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4022    }
4023
4024    void enforceNotIsolatedCaller(String caller) {
4025        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4026            throw new SecurityException("Isolated process not allowed to call " + caller);
4027        }
4028    }
4029
4030    void enforceShellRestriction(String restriction, int userHandle) {
4031        if (Binder.getCallingUid() == Process.SHELL_UID) {
4032            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4033                throw new SecurityException("Shell does not have permission to access user "
4034                        + userHandle);
4035            }
4036        }
4037    }
4038
4039    @Override
4040    public int getFrontActivityScreenCompatMode() {
4041        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4042        synchronized (this) {
4043            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4044        }
4045    }
4046
4047    @Override
4048    public void setFrontActivityScreenCompatMode(int mode) {
4049        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4050                "setFrontActivityScreenCompatMode");
4051        synchronized (this) {
4052            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4053        }
4054    }
4055
4056    @Override
4057    public int getPackageScreenCompatMode(String packageName) {
4058        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4059        synchronized (this) {
4060            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4061        }
4062    }
4063
4064    @Override
4065    public void setPackageScreenCompatMode(String packageName, int mode) {
4066        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4067                "setPackageScreenCompatMode");
4068        synchronized (this) {
4069            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4070        }
4071    }
4072
4073    @Override
4074    public boolean getPackageAskScreenCompat(String packageName) {
4075        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4076        synchronized (this) {
4077            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4078        }
4079    }
4080
4081    @Override
4082    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4083        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4084                "setPackageAskScreenCompat");
4085        synchronized (this) {
4086            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4087        }
4088    }
4089
4090    private boolean hasUsageStatsPermission(String callingPackage) {
4091        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4092                Binder.getCallingUid(), callingPackage);
4093        if (mode == AppOpsManager.MODE_DEFAULT) {
4094            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4095                    == PackageManager.PERMISSION_GRANTED;
4096        }
4097        return mode == AppOpsManager.MODE_ALLOWED;
4098    }
4099
4100    @Override
4101    public int getPackageProcessState(String packageName, String callingPackage) {
4102        if (!hasUsageStatsPermission(callingPackage)) {
4103            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4104                    "getPackageProcessState");
4105        }
4106
4107        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4108        synchronized (this) {
4109            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4110                final ProcessRecord proc = mLruProcesses.get(i);
4111                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4112                        || procState > proc.setProcState) {
4113                    boolean found = false;
4114                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4115                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4116                            procState = proc.setProcState;
4117                            found = true;
4118                        }
4119                    }
4120                    if (proc.pkgDeps != null && !found) {
4121                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4122                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4123                                procState = proc.setProcState;
4124                                break;
4125                            }
4126                        }
4127                    }
4128                }
4129            }
4130        }
4131        return procState;
4132    }
4133
4134    @Override
4135    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4136        synchronized (this) {
4137            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4138            if (app == null) {
4139                return false;
4140            }
4141            if (app.trimMemoryLevel < level && app.thread != null &&
4142                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4143                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4144                try {
4145                    app.thread.scheduleTrimMemory(level);
4146                    app.trimMemoryLevel = level;
4147                    return true;
4148                } catch (RemoteException e) {
4149                    // Fallthrough to failure case.
4150                }
4151            }
4152        }
4153        return false;
4154    }
4155
4156    private void dispatchProcessesChanged() {
4157        int N;
4158        synchronized (this) {
4159            N = mPendingProcessChanges.size();
4160            if (mActiveProcessChanges.length < N) {
4161                mActiveProcessChanges = new ProcessChangeItem[N];
4162            }
4163            mPendingProcessChanges.toArray(mActiveProcessChanges);
4164            mPendingProcessChanges.clear();
4165            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4166                    "*** Delivering " + N + " process changes");
4167        }
4168
4169        int i = mProcessObservers.beginBroadcast();
4170        while (i > 0) {
4171            i--;
4172            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4173            if (observer != null) {
4174                try {
4175                    for (int j=0; j<N; j++) {
4176                        ProcessChangeItem item = mActiveProcessChanges[j];
4177                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4178                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4179                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4180                                    + item.uid + ": " + item.foregroundActivities);
4181                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4182                                    item.foregroundActivities);
4183                        }
4184                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4185                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4186                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4187                                    + ": " + item.processState);
4188                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4189                        }
4190                    }
4191                } catch (RemoteException e) {
4192                }
4193            }
4194        }
4195        mProcessObservers.finishBroadcast();
4196
4197        synchronized (this) {
4198            for (int j=0; j<N; j++) {
4199                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4200            }
4201        }
4202    }
4203
4204    private void dispatchProcessDied(int pid, int uid) {
4205        int i = mProcessObservers.beginBroadcast();
4206        while (i > 0) {
4207            i--;
4208            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4209            if (observer != null) {
4210                try {
4211                    observer.onProcessDied(pid, uid);
4212                } catch (RemoteException e) {
4213                }
4214            }
4215        }
4216        mProcessObservers.finishBroadcast();
4217    }
4218
4219    private void dispatchUidsChanged() {
4220        int N;
4221        synchronized (this) {
4222            N = mPendingUidChanges.size();
4223            if (mActiveUidChanges.length < N) {
4224                mActiveUidChanges = new UidRecord.ChangeItem[N];
4225            }
4226            for (int i=0; i<N; i++) {
4227                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4228                mActiveUidChanges[i] = change;
4229                if (change.uidRecord != null) {
4230                    change.uidRecord.pendingChange = null;
4231                    change.uidRecord = null;
4232                }
4233            }
4234            mPendingUidChanges.clear();
4235            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4236                    "*** Delivering " + N + " uid changes");
4237        }
4238
4239        if (mLocalPowerManager != null) {
4240            for (int j=0; j<N; j++) {
4241                UidRecord.ChangeItem item = mActiveUidChanges[j];
4242                if (item.change == UidRecord.CHANGE_GONE
4243                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4244                    mLocalPowerManager.uidGone(item.uid);
4245                } else {
4246                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4247                }
4248            }
4249        }
4250
4251        int i = mUidObservers.beginBroadcast();
4252        while (i > 0) {
4253            i--;
4254            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4255            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4256            if (observer != null) {
4257                try {
4258                    for (int j=0; j<N; j++) {
4259                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4260                        final int change = item.change;
4261                        UidRecord validateUid = null;
4262                        if (VALIDATE_UID_STATES && i == 0) {
4263                            validateUid = mValidateUids.get(item.uid);
4264                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4265                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4266                                validateUid = new UidRecord(item.uid);
4267                                mValidateUids.put(item.uid, validateUid);
4268                            }
4269                        }
4270                        if (change == UidRecord.CHANGE_IDLE
4271                                || change == UidRecord.CHANGE_GONE_IDLE) {
4272                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4273                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4274                                        "UID idle uid=" + item.uid);
4275                                observer.onUidIdle(item.uid);
4276                            }
4277                            if (VALIDATE_UID_STATES && i == 0) {
4278                                if (validateUid != null) {
4279                                    validateUid.idle = true;
4280                                }
4281                            }
4282                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4283                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4284                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4285                                        "UID active uid=" + item.uid);
4286                                observer.onUidActive(item.uid);
4287                            }
4288                            if (VALIDATE_UID_STATES && i == 0) {
4289                                validateUid.idle = false;
4290                            }
4291                        }
4292                        if (change == UidRecord.CHANGE_GONE
4293                                || change == UidRecord.CHANGE_GONE_IDLE) {
4294                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4295                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4296                                        "UID gone uid=" + item.uid);
4297                                observer.onUidGone(item.uid);
4298                            }
4299                            if (VALIDATE_UID_STATES && i == 0) {
4300                                if (validateUid != null) {
4301                                    mValidateUids.remove(item.uid);
4302                                }
4303                            }
4304                        } else {
4305                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4306                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4307                                        "UID CHANGED uid=" + item.uid
4308                                                + ": " + item.processState);
4309                                observer.onUidStateChanged(item.uid, item.processState);
4310                            }
4311                            if (VALIDATE_UID_STATES && i == 0) {
4312                                validateUid.curProcState = validateUid.setProcState
4313                                        = item.processState;
4314                            }
4315                        }
4316                    }
4317                } catch (RemoteException e) {
4318                }
4319            }
4320        }
4321        mUidObservers.finishBroadcast();
4322
4323        synchronized (this) {
4324            for (int j=0; j<N; j++) {
4325                mAvailUidChanges.add(mActiveUidChanges[j]);
4326            }
4327        }
4328    }
4329
4330    @Override
4331    public final int startActivity(IApplicationThread caller, String callingPackage,
4332            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4333            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4334        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4335                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4336                UserHandle.getCallingUserId());
4337    }
4338
4339    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4340        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4341        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4342                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4343                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4344
4345        // TODO: Switch to user app stacks here.
4346        String mimeType = intent.getType();
4347        final Uri data = intent.getData();
4348        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4349            mimeType = getProviderMimeType(data, userId);
4350        }
4351        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4352
4353        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4354        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4355                null, 0, 0, null, null, null, null, false, userId, container, null);
4356    }
4357
4358    @Override
4359    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4360            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4361            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4362        enforceNotIsolatedCaller("startActivity");
4363        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4364                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4365        // TODO: Switch to user app stacks here.
4366        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4367                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4368                profilerInfo, null, null, bOptions, false, userId, null, null);
4369    }
4370
4371    @Override
4372    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4373            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4374            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4375            int userId) {
4376
4377        // This is very dangerous -- it allows you to perform a start activity (including
4378        // permission grants) as any app that may launch one of your own activities.  So
4379        // we will only allow this to be done from activities that are part of the core framework,
4380        // and then only when they are running as the system.
4381        final ActivityRecord sourceRecord;
4382        final int targetUid;
4383        final String targetPackage;
4384        synchronized (this) {
4385            if (resultTo == null) {
4386                throw new SecurityException("Must be called from an activity");
4387            }
4388            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4389            if (sourceRecord == null) {
4390                throw new SecurityException("Called with bad activity token: " + resultTo);
4391            }
4392            if (!sourceRecord.info.packageName.equals("android")) {
4393                throw new SecurityException(
4394                        "Must be called from an activity that is declared in the android package");
4395            }
4396            if (sourceRecord.app == null) {
4397                throw new SecurityException("Called without a process attached to activity");
4398            }
4399            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4400                // This is still okay, as long as this activity is running under the
4401                // uid of the original calling activity.
4402                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4403                    throw new SecurityException(
4404                            "Calling activity in uid " + sourceRecord.app.uid
4405                                    + " must be system uid or original calling uid "
4406                                    + sourceRecord.launchedFromUid);
4407                }
4408            }
4409            if (ignoreTargetSecurity) {
4410                if (intent.getComponent() == null) {
4411                    throw new SecurityException(
4412                            "Component must be specified with ignoreTargetSecurity");
4413                }
4414                if (intent.getSelector() != null) {
4415                    throw new SecurityException(
4416                            "Selector not allowed with ignoreTargetSecurity");
4417                }
4418            }
4419            targetUid = sourceRecord.launchedFromUid;
4420            targetPackage = sourceRecord.launchedFromPackage;
4421        }
4422
4423        if (userId == UserHandle.USER_NULL) {
4424            userId = UserHandle.getUserId(sourceRecord.app.uid);
4425        }
4426
4427        // TODO: Switch to user app stacks here.
4428        try {
4429            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4430                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4431                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4432            return ret;
4433        } catch (SecurityException e) {
4434            // XXX need to figure out how to propagate to original app.
4435            // A SecurityException here is generally actually a fault of the original
4436            // calling activity (such as a fairly granting permissions), so propagate it
4437            // back to them.
4438            /*
4439            StringBuilder msg = new StringBuilder();
4440            msg.append("While launching");
4441            msg.append(intent.toString());
4442            msg.append(": ");
4443            msg.append(e.getMessage());
4444            */
4445            throw e;
4446        }
4447    }
4448
4449    @Override
4450    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4451            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4452            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4453        enforceNotIsolatedCaller("startActivityAndWait");
4454        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4455                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4456        WaitResult res = new WaitResult();
4457        // TODO: Switch to user app stacks here.
4458        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4459                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4460                bOptions, false, userId, null, null);
4461        return res;
4462    }
4463
4464    @Override
4465    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4466            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4467            int startFlags, Configuration config, Bundle bOptions, int userId) {
4468        enforceNotIsolatedCaller("startActivityWithConfig");
4469        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4470                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4471        // TODO: Switch to user app stacks here.
4472        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4473                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4474                null, null, config, bOptions, false, userId, null, null);
4475        return ret;
4476    }
4477
4478    @Override
4479    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4480            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4481            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4482            throws TransactionTooLargeException {
4483        enforceNotIsolatedCaller("startActivityIntentSender");
4484        // Refuse possible leaked file descriptors
4485        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4486            throw new IllegalArgumentException("File descriptors passed in Intent");
4487        }
4488
4489        IIntentSender sender = intent.getTarget();
4490        if (!(sender instanceof PendingIntentRecord)) {
4491            throw new IllegalArgumentException("Bad PendingIntent object");
4492        }
4493
4494        PendingIntentRecord pir = (PendingIntentRecord)sender;
4495
4496        synchronized (this) {
4497            // If this is coming from the currently resumed activity, it is
4498            // effectively saying that app switches are allowed at this point.
4499            final ActivityStack stack = getFocusedStack();
4500            if (stack.mResumedActivity != null &&
4501                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4502                mAppSwitchesAllowedTime = 0;
4503            }
4504        }
4505        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4506                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4507        return ret;
4508    }
4509
4510    @Override
4511    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4512            Intent intent, String resolvedType, IVoiceInteractionSession session,
4513            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4514            Bundle bOptions, int userId) {
4515        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4516                != PackageManager.PERMISSION_GRANTED) {
4517            String msg = "Permission Denial: startVoiceActivity() from pid="
4518                    + Binder.getCallingPid()
4519                    + ", uid=" + Binder.getCallingUid()
4520                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4521            Slog.w(TAG, msg);
4522            throw new SecurityException(msg);
4523        }
4524        if (session == null || interactor == null) {
4525            throw new NullPointerException("null session or interactor");
4526        }
4527        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4528                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4529        // TODO: Switch to user app stacks here.
4530        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4531                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4532                null, bOptions, false, userId, null, null);
4533    }
4534
4535    @Override
4536    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4537            throws RemoteException {
4538        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4539        synchronized (this) {
4540            ActivityRecord activity = getFocusedStack().topActivity();
4541            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4542                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4543            }
4544            if (mRunningVoice != null || activity.task.voiceSession != null
4545                    || activity.voiceSession != null) {
4546                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4547                return;
4548            }
4549            if (activity.pendingVoiceInteractionStart) {
4550                Slog.w(TAG, "Pending start of voice interaction already.");
4551                return;
4552            }
4553            activity.pendingVoiceInteractionStart = true;
4554        }
4555        LocalServices.getService(VoiceInteractionManagerInternal.class)
4556                .startLocalVoiceInteraction(callingActivity, options);
4557    }
4558
4559    @Override
4560    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4561        LocalServices.getService(VoiceInteractionManagerInternal.class)
4562                .stopLocalVoiceInteraction(callingActivity);
4563    }
4564
4565    @Override
4566    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4567        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4568                .supportsLocalVoiceInteraction();
4569    }
4570
4571    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4572            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4573        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4574        if (activityToCallback == null) return;
4575        activityToCallback.setVoiceSessionLocked(voiceSession);
4576
4577        // Inform the activity
4578        try {
4579            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4580                    voiceInteractor);
4581            long token = Binder.clearCallingIdentity();
4582            try {
4583                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4584            } finally {
4585                Binder.restoreCallingIdentity(token);
4586            }
4587            // TODO: VI Should we cache the activity so that it's easier to find later
4588            // rather than scan through all the stacks and activities?
4589        } catch (RemoteException re) {
4590            activityToCallback.clearVoiceSessionLocked();
4591            // TODO: VI Should this terminate the voice session?
4592        }
4593    }
4594
4595    @Override
4596    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4597        synchronized (this) {
4598            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4599                if (keepAwake) {
4600                    mVoiceWakeLock.acquire();
4601                } else {
4602                    mVoiceWakeLock.release();
4603                }
4604            }
4605        }
4606    }
4607
4608    @Override
4609    public boolean startNextMatchingActivity(IBinder callingActivity,
4610            Intent intent, Bundle bOptions) {
4611        // Refuse possible leaked file descriptors
4612        if (intent != null && intent.hasFileDescriptors() == true) {
4613            throw new IllegalArgumentException("File descriptors passed in Intent");
4614        }
4615        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4616
4617        synchronized (this) {
4618            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4619            if (r == null) {
4620                ActivityOptions.abort(options);
4621                return false;
4622            }
4623            if (r.app == null || r.app.thread == null) {
4624                // The caller is not running...  d'oh!
4625                ActivityOptions.abort(options);
4626                return false;
4627            }
4628            intent = new Intent(intent);
4629            // The caller is not allowed to change the data.
4630            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4631            // And we are resetting to find the next component...
4632            intent.setComponent(null);
4633
4634            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4635
4636            ActivityInfo aInfo = null;
4637            try {
4638                List<ResolveInfo> resolves =
4639                    AppGlobals.getPackageManager().queryIntentActivities(
4640                            intent, r.resolvedType,
4641                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4642                            UserHandle.getCallingUserId()).getList();
4643
4644                // Look for the original activity in the list...
4645                final int N = resolves != null ? resolves.size() : 0;
4646                for (int i=0; i<N; i++) {
4647                    ResolveInfo rInfo = resolves.get(i);
4648                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4649                            && rInfo.activityInfo.name.equals(r.info.name)) {
4650                        // We found the current one...  the next matching is
4651                        // after it.
4652                        i++;
4653                        if (i<N) {
4654                            aInfo = resolves.get(i).activityInfo;
4655                        }
4656                        if (debug) {
4657                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4658                                    + "/" + r.info.name);
4659                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4660                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4661                        }
4662                        break;
4663                    }
4664                }
4665            } catch (RemoteException e) {
4666            }
4667
4668            if (aInfo == null) {
4669                // Nobody who is next!
4670                ActivityOptions.abort(options);
4671                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4672                return false;
4673            }
4674
4675            intent.setComponent(new ComponentName(
4676                    aInfo.applicationInfo.packageName, aInfo.name));
4677            intent.setFlags(intent.getFlags()&~(
4678                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4679                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4680                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4681                    Intent.FLAG_ACTIVITY_NEW_TASK));
4682
4683            // Okay now we need to start the new activity, replacing the
4684            // currently running activity.  This is a little tricky because
4685            // we want to start the new one as if the current one is finished,
4686            // but not finish the current one first so that there is no flicker.
4687            // And thus...
4688            final boolean wasFinishing = r.finishing;
4689            r.finishing = true;
4690
4691            // Propagate reply information over to the new activity.
4692            final ActivityRecord resultTo = r.resultTo;
4693            final String resultWho = r.resultWho;
4694            final int requestCode = r.requestCode;
4695            r.resultTo = null;
4696            if (resultTo != null) {
4697                resultTo.removeResultsLocked(r, resultWho, requestCode);
4698            }
4699
4700            final long origId = Binder.clearCallingIdentity();
4701            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4702                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4703                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4704                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4705                    false, false, null, null, null);
4706            Binder.restoreCallingIdentity(origId);
4707
4708            r.finishing = wasFinishing;
4709            if (res != ActivityManager.START_SUCCESS) {
4710                return false;
4711            }
4712            return true;
4713        }
4714    }
4715
4716    @Override
4717    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4718        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4719            String msg = "Permission Denial: startActivityFromRecents called without " +
4720                    START_TASKS_FROM_RECENTS;
4721            Slog.w(TAG, msg);
4722            throw new SecurityException(msg);
4723        }
4724        final long origId = Binder.clearCallingIdentity();
4725        try {
4726            synchronized (this) {
4727                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4728            }
4729        } finally {
4730            Binder.restoreCallingIdentity(origId);
4731        }
4732    }
4733
4734    final int startActivityInPackage(int uid, String callingPackage,
4735            Intent intent, String resolvedType, IBinder resultTo,
4736            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4737            IActivityContainer container, TaskRecord inTask) {
4738
4739        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4740                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4741
4742        // TODO: Switch to user app stacks here.
4743        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4744                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4745                null, null, null, bOptions, false, userId, container, inTask);
4746        return ret;
4747    }
4748
4749    @Override
4750    public final int startActivities(IApplicationThread caller, String callingPackage,
4751            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4752            int userId) {
4753        enforceNotIsolatedCaller("startActivities");
4754        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4755                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4756        // TODO: Switch to user app stacks here.
4757        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4758                resolvedTypes, resultTo, bOptions, userId);
4759        return ret;
4760    }
4761
4762    final int startActivitiesInPackage(int uid, String callingPackage,
4763            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4764            Bundle bOptions, int userId) {
4765
4766        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4767                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4768        // TODO: Switch to user app stacks here.
4769        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4770                resultTo, bOptions, userId);
4771        return ret;
4772    }
4773
4774    @Override
4775    public void reportActivityFullyDrawn(IBinder token) {
4776        synchronized (this) {
4777            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4778            if (r == null) {
4779                return;
4780            }
4781            r.reportFullyDrawnLocked();
4782        }
4783    }
4784
4785    @Override
4786    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4787        synchronized (this) {
4788            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4789            if (r == null) {
4790                return;
4791            }
4792            TaskRecord task = r.task;
4793            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4794                // Fixed screen orientation isn't supported when activities aren't in full screen
4795                // mode.
4796                return;
4797            }
4798            final long origId = Binder.clearCallingIdentity();
4799            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4800            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4801                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4802            if (config != null) {
4803                r.frozenBeforeDestroy = true;
4804                if (!updateConfigurationLocked(config, r, false)) {
4805                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4806                }
4807            }
4808            Binder.restoreCallingIdentity(origId);
4809        }
4810    }
4811
4812    @Override
4813    public int getRequestedOrientation(IBinder token) {
4814        synchronized (this) {
4815            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4816            if (r == null) {
4817                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4818            }
4819            return mWindowManager.getAppOrientation(r.appToken);
4820        }
4821    }
4822
4823    /**
4824     * This is the internal entry point for handling Activity.finish().
4825     *
4826     * @param token The Binder token referencing the Activity we want to finish.
4827     * @param resultCode Result code, if any, from this Activity.
4828     * @param resultData Result data (Intent), if any, from this Activity.
4829     * @param finishTask Whether to finish the task associated with this Activity.
4830     *
4831     * @return Returns true if the activity successfully finished, or false if it is still running.
4832     */
4833    @Override
4834    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4835            int finishTask) {
4836        // Refuse possible leaked file descriptors
4837        if (resultData != null && resultData.hasFileDescriptors() == true) {
4838            throw new IllegalArgumentException("File descriptors passed in Intent");
4839        }
4840
4841        synchronized(this) {
4842            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4843            if (r == null) {
4844                return true;
4845            }
4846            // Keep track of the root activity of the task before we finish it
4847            TaskRecord tr = r.task;
4848            ActivityRecord rootR = tr.getRootActivity();
4849            if (rootR == null) {
4850                Slog.w(TAG, "Finishing task with all activities already finished");
4851            }
4852            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4853            // finish.
4854            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4855                    mStackSupervisor.isLastLockedTask(tr)) {
4856                Slog.i(TAG, "Not finishing task in lock task mode");
4857                mStackSupervisor.showLockTaskToast();
4858                return false;
4859            }
4860            if (mController != null) {
4861                // Find the first activity that is not finishing.
4862                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4863                if (next != null) {
4864                    // ask watcher if this is allowed
4865                    boolean resumeOK = true;
4866                    try {
4867                        resumeOK = mController.activityResuming(next.packageName);
4868                    } catch (RemoteException e) {
4869                        mController = null;
4870                        Watchdog.getInstance().setActivityController(null);
4871                    }
4872
4873                    if (!resumeOK) {
4874                        Slog.i(TAG, "Not finishing activity because controller resumed");
4875                        return false;
4876                    }
4877                }
4878            }
4879            final long origId = Binder.clearCallingIdentity();
4880            try {
4881                boolean res;
4882                final boolean finishWithRootActivity =
4883                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4884                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4885                        || (finishWithRootActivity && r == rootR)) {
4886                    // If requested, remove the task that is associated to this activity only if it
4887                    // was the root activity in the task. The result code and data is ignored
4888                    // because we don't support returning them across task boundaries. Also, to
4889                    // keep backwards compatibility we remove the task from recents when finishing
4890                    // task with root activity.
4891                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4892                    if (!res) {
4893                        Slog.i(TAG, "Removing task failed to finish activity");
4894                    }
4895                } else {
4896                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4897                            resultData, "app-request", true);
4898                    if (!res) {
4899                        Slog.i(TAG, "Failed to finish by app-request");
4900                    }
4901                }
4902                return res;
4903            } finally {
4904                Binder.restoreCallingIdentity(origId);
4905            }
4906        }
4907    }
4908
4909    @Override
4910    public final void finishHeavyWeightApp() {
4911        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4912                != PackageManager.PERMISSION_GRANTED) {
4913            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4914                    + Binder.getCallingPid()
4915                    + ", uid=" + Binder.getCallingUid()
4916                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4917            Slog.w(TAG, msg);
4918            throw new SecurityException(msg);
4919        }
4920
4921        synchronized(this) {
4922            if (mHeavyWeightProcess == null) {
4923                return;
4924            }
4925
4926            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4927            for (int i = 0; i < activities.size(); i++) {
4928                ActivityRecord r = activities.get(i);
4929                if (!r.finishing && r.isInStackLocked()) {
4930                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4931                            null, "finish-heavy", true);
4932                }
4933            }
4934
4935            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4936                    mHeavyWeightProcess.userId, 0));
4937            mHeavyWeightProcess = null;
4938        }
4939    }
4940
4941    @Override
4942    public void crashApplication(int uid, int initialPid, String packageName,
4943            String message) {
4944        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4945                != PackageManager.PERMISSION_GRANTED) {
4946            String msg = "Permission Denial: crashApplication() from pid="
4947                    + Binder.getCallingPid()
4948                    + ", uid=" + Binder.getCallingUid()
4949                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4950            Slog.w(TAG, msg);
4951            throw new SecurityException(msg);
4952        }
4953
4954        synchronized(this) {
4955            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4956        }
4957    }
4958
4959    @Override
4960    public final void finishSubActivity(IBinder token, String resultWho,
4961            int requestCode) {
4962        synchronized(this) {
4963            final long origId = Binder.clearCallingIdentity();
4964            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4965            if (r != null) {
4966                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4967            }
4968            Binder.restoreCallingIdentity(origId);
4969        }
4970    }
4971
4972    @Override
4973    public boolean finishActivityAffinity(IBinder token) {
4974        synchronized(this) {
4975            final long origId = Binder.clearCallingIdentity();
4976            try {
4977                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4978                if (r == null) {
4979                    return false;
4980                }
4981
4982                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4983                // can finish.
4984                final TaskRecord task = r.task;
4985                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4986                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4987                    mStackSupervisor.showLockTaskToast();
4988                    return false;
4989                }
4990                return task.stack.finishActivityAffinityLocked(r);
4991            } finally {
4992                Binder.restoreCallingIdentity(origId);
4993            }
4994        }
4995    }
4996
4997    @Override
4998    public void finishVoiceTask(IVoiceInteractionSession session) {
4999        synchronized (this) {
5000            final long origId = Binder.clearCallingIdentity();
5001            try {
5002                // TODO: VI Consider treating local voice interactions and voice tasks
5003                // differently here
5004                mStackSupervisor.finishVoiceTask(session);
5005            } finally {
5006                Binder.restoreCallingIdentity(origId);
5007            }
5008        }
5009
5010    }
5011
5012    @Override
5013    public boolean releaseActivityInstance(IBinder token) {
5014        synchronized(this) {
5015            final long origId = Binder.clearCallingIdentity();
5016            try {
5017                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5018                if (r == null) {
5019                    return false;
5020                }
5021                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5022            } finally {
5023                Binder.restoreCallingIdentity(origId);
5024            }
5025        }
5026    }
5027
5028    @Override
5029    public void releaseSomeActivities(IApplicationThread appInt) {
5030        synchronized(this) {
5031            final long origId = Binder.clearCallingIdentity();
5032            try {
5033                ProcessRecord app = getRecordForAppLocked(appInt);
5034                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5035            } finally {
5036                Binder.restoreCallingIdentity(origId);
5037            }
5038        }
5039    }
5040
5041    @Override
5042    public boolean willActivityBeVisible(IBinder token) {
5043        synchronized(this) {
5044            ActivityStack stack = ActivityRecord.getStackLocked(token);
5045            if (stack != null) {
5046                return stack.willActivityBeVisibleLocked(token);
5047            }
5048            return false;
5049        }
5050    }
5051
5052    @Override
5053    public void overridePendingTransition(IBinder token, String packageName,
5054            int enterAnim, int exitAnim) {
5055        synchronized(this) {
5056            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5057            if (self == null) {
5058                return;
5059            }
5060
5061            final long origId = Binder.clearCallingIdentity();
5062
5063            if (self.state == ActivityState.RESUMED
5064                    || self.state == ActivityState.PAUSING) {
5065                mWindowManager.overridePendingAppTransition(packageName,
5066                        enterAnim, exitAnim, null);
5067            }
5068
5069            Binder.restoreCallingIdentity(origId);
5070        }
5071    }
5072
5073    /**
5074     * Main function for removing an existing process from the activity manager
5075     * as a result of that process going away.  Clears out all connections
5076     * to the process.
5077     */
5078    private final void handleAppDiedLocked(ProcessRecord app,
5079            boolean restarting, boolean allowRestart) {
5080        int pid = app.pid;
5081        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5082                false /*replacingPid*/);
5083        if (!kept && !restarting) {
5084            removeLruProcessLocked(app);
5085            if (pid > 0) {
5086                ProcessList.remove(pid);
5087            }
5088        }
5089
5090        if (mProfileProc == app) {
5091            clearProfilerLocked();
5092        }
5093
5094        // Remove this application's activities from active lists.
5095        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5096
5097        app.activities.clear();
5098
5099        if (app.instrumentationClass != null) {
5100            Slog.w(TAG, "Crash of app " + app.processName
5101                  + " running instrumentation " + app.instrumentationClass);
5102            Bundle info = new Bundle();
5103            info.putString("shortMsg", "Process crashed.");
5104            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5105        }
5106
5107        if (!restarting && hasVisibleActivities
5108                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5109            // If there was nothing to resume, and we are not already restarting this process, but
5110            // there is a visible activity that is hosted by the process...  then make sure all
5111            // visible activities are running, taking care of restarting this process.
5112            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5113        }
5114    }
5115
5116    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5117        IBinder threadBinder = thread.asBinder();
5118        // Find the application record.
5119        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5120            ProcessRecord rec = mLruProcesses.get(i);
5121            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5122                return i;
5123            }
5124        }
5125        return -1;
5126    }
5127
5128    final ProcessRecord getRecordForAppLocked(
5129            IApplicationThread thread) {
5130        if (thread == null) {
5131            return null;
5132        }
5133
5134        int appIndex = getLRURecordIndexForAppLocked(thread);
5135        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5136    }
5137
5138    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5139        // If there are no longer any background processes running,
5140        // and the app that died was not running instrumentation,
5141        // then tell everyone we are now low on memory.
5142        boolean haveBg = false;
5143        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5144            ProcessRecord rec = mLruProcesses.get(i);
5145            if (rec.thread != null
5146                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5147                haveBg = true;
5148                break;
5149            }
5150        }
5151
5152        if (!haveBg) {
5153            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5154            if (doReport) {
5155                long now = SystemClock.uptimeMillis();
5156                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5157                    doReport = false;
5158                } else {
5159                    mLastMemUsageReportTime = now;
5160                }
5161            }
5162            final ArrayList<ProcessMemInfo> memInfos
5163                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5164            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5165            long now = SystemClock.uptimeMillis();
5166            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5167                ProcessRecord rec = mLruProcesses.get(i);
5168                if (rec == dyingProc || rec.thread == null) {
5169                    continue;
5170                }
5171                if (doReport) {
5172                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5173                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5174                }
5175                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5176                    // The low memory report is overriding any current
5177                    // state for a GC request.  Make sure to do
5178                    // heavy/important/visible/foreground processes first.
5179                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5180                        rec.lastRequestedGc = 0;
5181                    } else {
5182                        rec.lastRequestedGc = rec.lastLowMemory;
5183                    }
5184                    rec.reportLowMemory = true;
5185                    rec.lastLowMemory = now;
5186                    mProcessesToGc.remove(rec);
5187                    addProcessToGcListLocked(rec);
5188                }
5189            }
5190            if (doReport) {
5191                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5192                mHandler.sendMessage(msg);
5193            }
5194            scheduleAppGcsLocked();
5195        }
5196    }
5197
5198    final void appDiedLocked(ProcessRecord app) {
5199       appDiedLocked(app, app.pid, app.thread, false);
5200    }
5201
5202    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5203            boolean fromBinderDied) {
5204        // First check if this ProcessRecord is actually active for the pid.
5205        synchronized (mPidsSelfLocked) {
5206            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5207            if (curProc != app) {
5208                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5209                return;
5210            }
5211        }
5212
5213        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5214        synchronized (stats) {
5215            stats.noteProcessDiedLocked(app.info.uid, pid);
5216        }
5217
5218        if (!app.killed) {
5219            if (!fromBinderDied) {
5220                Process.killProcessQuiet(pid);
5221            }
5222            killProcessGroup(app.uid, pid);
5223            app.killed = true;
5224        }
5225
5226        // Clean up already done if the process has been re-started.
5227        if (app.pid == pid && app.thread != null &&
5228                app.thread.asBinder() == thread.asBinder()) {
5229            boolean doLowMem = app.instrumentationClass == null;
5230            boolean doOomAdj = doLowMem;
5231            if (!app.killedByAm) {
5232                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5233                        + ") has died");
5234                mAllowLowerMemLevel = true;
5235            } else {
5236                // Note that we always want to do oom adj to update our state with the
5237                // new number of procs.
5238                mAllowLowerMemLevel = false;
5239                doLowMem = false;
5240            }
5241            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5242            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5243                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5244            handleAppDiedLocked(app, false, true);
5245
5246            if (doOomAdj) {
5247                updateOomAdjLocked();
5248            }
5249            if (doLowMem) {
5250                doLowMemReportIfNeededLocked(app);
5251            }
5252        } else if (app.pid != pid) {
5253            // A new process has already been started.
5254            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5255                    + ") has died and restarted (pid " + app.pid + ").");
5256            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5257        } else if (DEBUG_PROCESSES) {
5258            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5259                    + thread.asBinder());
5260        }
5261    }
5262
5263    /**
5264     * If a stack trace dump file is configured, dump process stack traces.
5265     * @param clearTraces causes the dump file to be erased prior to the new
5266     *    traces being written, if true; when false, the new traces will be
5267     *    appended to any existing file content.
5268     * @param firstPids of dalvik VM processes to dump stack traces for first
5269     * @param lastPids of dalvik VM processes to dump stack traces for last
5270     * @param nativeProcs optional list of native process names to dump stack crawls
5271     * @return file containing stack traces, or null if no dump file is configured
5272     */
5273    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5274            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5275        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5276        if (tracesPath == null || tracesPath.length() == 0) {
5277            return null;
5278        }
5279
5280        File tracesFile = new File(tracesPath);
5281        try {
5282            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5283            tracesFile.createNewFile();
5284            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5285        } catch (IOException e) {
5286            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5287            return null;
5288        }
5289
5290        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5291        return tracesFile;
5292    }
5293
5294    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5295            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5296        // Use a FileObserver to detect when traces finish writing.
5297        // The order of traces is considered important to maintain for legibility.
5298        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5299            @Override
5300            public synchronized void onEvent(int event, String path) { notify(); }
5301        };
5302
5303        try {
5304            observer.startWatching();
5305
5306            // First collect all of the stacks of the most important pids.
5307            if (firstPids != null) {
5308                try {
5309                    int num = firstPids.size();
5310                    for (int i = 0; i < num; i++) {
5311                        synchronized (observer) {
5312                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5313                                    + firstPids.get(i));
5314                            final long sime = SystemClock.elapsedRealtime();
5315                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5316                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5317                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5318                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5319                        }
5320                    }
5321                } catch (InterruptedException e) {
5322                    Slog.wtf(TAG, e);
5323                }
5324            }
5325
5326            // Next collect the stacks of the native pids
5327            if (nativeProcs != null) {
5328                int[] pids = Process.getPidsForCommands(nativeProcs);
5329                if (pids != null) {
5330                    for (int pid : pids) {
5331                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5332                        final long sime = SystemClock.elapsedRealtime();
5333                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5334                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5335                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5336                    }
5337                }
5338            }
5339
5340            // Lastly, measure CPU usage.
5341            if (processCpuTracker != null) {
5342                processCpuTracker.init();
5343                System.gc();
5344                processCpuTracker.update();
5345                try {
5346                    synchronized (processCpuTracker) {
5347                        processCpuTracker.wait(500); // measure over 1/2 second.
5348                    }
5349                } catch (InterruptedException e) {
5350                }
5351                processCpuTracker.update();
5352
5353                // We'll take the stack crawls of just the top apps using CPU.
5354                final int N = processCpuTracker.countWorkingStats();
5355                int numProcs = 0;
5356                for (int i=0; i<N && numProcs<5; i++) {
5357                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5358                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5359                        numProcs++;
5360                        try {
5361                            synchronized (observer) {
5362                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5363                                        + stats.pid);
5364                                final long stime = SystemClock.elapsedRealtime();
5365                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5366                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5367                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5368                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5369                            }
5370                        } catch (InterruptedException e) {
5371                            Slog.wtf(TAG, e);
5372                        }
5373                    } else if (DEBUG_ANR) {
5374                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5375                                + stats.pid);
5376                    }
5377                }
5378            }
5379        } finally {
5380            observer.stopWatching();
5381        }
5382    }
5383
5384    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5385        if (true || IS_USER_BUILD) {
5386            return;
5387        }
5388        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5389        if (tracesPath == null || tracesPath.length() == 0) {
5390            return;
5391        }
5392
5393        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5394        StrictMode.allowThreadDiskWrites();
5395        try {
5396            final File tracesFile = new File(tracesPath);
5397            final File tracesDir = tracesFile.getParentFile();
5398            final File tracesTmp = new File(tracesDir, "__tmp__");
5399            try {
5400                if (tracesFile.exists()) {
5401                    tracesTmp.delete();
5402                    tracesFile.renameTo(tracesTmp);
5403                }
5404                StringBuilder sb = new StringBuilder();
5405                Time tobj = new Time();
5406                tobj.set(System.currentTimeMillis());
5407                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5408                sb.append(": ");
5409                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5410                sb.append(" since ");
5411                sb.append(msg);
5412                FileOutputStream fos = new FileOutputStream(tracesFile);
5413                fos.write(sb.toString().getBytes());
5414                if (app == null) {
5415                    fos.write("\n*** No application process!".getBytes());
5416                }
5417                fos.close();
5418                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5419            } catch (IOException e) {
5420                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5421                return;
5422            }
5423
5424            if (app != null) {
5425                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5426                firstPids.add(app.pid);
5427                dumpStackTraces(tracesPath, firstPids, null, null, null);
5428            }
5429
5430            File lastTracesFile = null;
5431            File curTracesFile = null;
5432            for (int i=9; i>=0; i--) {
5433                String name = String.format(Locale.US, "slow%02d.txt", i);
5434                curTracesFile = new File(tracesDir, name);
5435                if (curTracesFile.exists()) {
5436                    if (lastTracesFile != null) {
5437                        curTracesFile.renameTo(lastTracesFile);
5438                    } else {
5439                        curTracesFile.delete();
5440                    }
5441                }
5442                lastTracesFile = curTracesFile;
5443            }
5444            tracesFile.renameTo(curTracesFile);
5445            if (tracesTmp.exists()) {
5446                tracesTmp.renameTo(tracesFile);
5447            }
5448        } finally {
5449            StrictMode.setThreadPolicy(oldPolicy);
5450        }
5451    }
5452
5453    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5454        if (!mLaunchWarningShown) {
5455            mLaunchWarningShown = true;
5456            mUiHandler.post(new Runnable() {
5457                @Override
5458                public void run() {
5459                    synchronized (ActivityManagerService.this) {
5460                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5461                        d.show();
5462                        mUiHandler.postDelayed(new Runnable() {
5463                            @Override
5464                            public void run() {
5465                                synchronized (ActivityManagerService.this) {
5466                                    d.dismiss();
5467                                    mLaunchWarningShown = false;
5468                                }
5469                            }
5470                        }, 4000);
5471                    }
5472                }
5473            });
5474        }
5475    }
5476
5477    @Override
5478    public boolean clearApplicationUserData(final String packageName,
5479            final IPackageDataObserver observer, int userId) {
5480        enforceNotIsolatedCaller("clearApplicationUserData");
5481        int uid = Binder.getCallingUid();
5482        int pid = Binder.getCallingPid();
5483        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5484                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5485
5486
5487        long callingId = Binder.clearCallingIdentity();
5488        try {
5489            IPackageManager pm = AppGlobals.getPackageManager();
5490            int pkgUid = -1;
5491            synchronized(this) {
5492                if (getPackageManagerInternalLocked().isPackageDataProtected(
5493                        userId, packageName)) {
5494                    throw new SecurityException(
5495                            "Cannot clear data for a protected package: " + packageName);
5496                }
5497
5498                try {
5499                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5500                } catch (RemoteException e) {
5501                }
5502                if (pkgUid == -1) {
5503                    Slog.w(TAG, "Invalid packageName: " + packageName);
5504                    if (observer != null) {
5505                        try {
5506                            observer.onRemoveCompleted(packageName, false);
5507                        } catch (RemoteException e) {
5508                            Slog.i(TAG, "Observer no longer exists.");
5509                        }
5510                    }
5511                    return false;
5512                }
5513                if (uid == pkgUid || checkComponentPermission(
5514                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5515                        pid, uid, -1, true)
5516                        == PackageManager.PERMISSION_GRANTED) {
5517                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5518                } else {
5519                    throw new SecurityException("PID " + pid + " does not have permission "
5520                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5521                                    + " of package " + packageName);
5522                }
5523
5524                // Remove all tasks match the cleared application package and user
5525                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5526                    final TaskRecord tr = mRecentTasks.get(i);
5527                    final String taskPackageName =
5528                            tr.getBaseIntent().getComponent().getPackageName();
5529                    if (tr.userId != userId) continue;
5530                    if (!taskPackageName.equals(packageName)) continue;
5531                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5532                }
5533            }
5534
5535            final int pkgUidF = pkgUid;
5536            final int userIdF = userId;
5537            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5538                @Override
5539                public void onRemoveCompleted(String packageName, boolean succeeded)
5540                        throws RemoteException {
5541                    synchronized (ActivityManagerService.this) {
5542                        finishForceStopPackageLocked(packageName, pkgUidF);
5543                    }
5544
5545                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5546                            Uri.fromParts("package", packageName, null));
5547                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5548                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5549                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5550                            null, null, 0, null, null, null, null, false, false, userIdF);
5551
5552                    if (observer != null) {
5553                        observer.onRemoveCompleted(packageName, succeeded);
5554                    }
5555                }
5556            };
5557
5558            try {
5559                // Clear application user data
5560                pm.clearApplicationUserData(packageName, localObserver, userId);
5561
5562                synchronized(this) {
5563                    // Remove all permissions granted from/to this package
5564                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5565                }
5566
5567                // Remove all zen rules created by this package; revoke it's zen access.
5568                INotificationManager inm = NotificationManager.getService();
5569                inm.removeAutomaticZenRules(packageName);
5570                inm.setNotificationPolicyAccessGranted(packageName, false);
5571
5572            } catch (RemoteException e) {
5573            }
5574        } finally {
5575            Binder.restoreCallingIdentity(callingId);
5576        }
5577        return true;
5578    }
5579
5580    @Override
5581    public void killBackgroundProcesses(final String packageName, int userId) {
5582        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5583                != PackageManager.PERMISSION_GRANTED &&
5584                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5585                        != PackageManager.PERMISSION_GRANTED) {
5586            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5587                    + Binder.getCallingPid()
5588                    + ", uid=" + Binder.getCallingUid()
5589                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5590            Slog.w(TAG, msg);
5591            throw new SecurityException(msg);
5592        }
5593
5594        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5595                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5596        long callingId = Binder.clearCallingIdentity();
5597        try {
5598            IPackageManager pm = AppGlobals.getPackageManager();
5599            synchronized(this) {
5600                int appId = -1;
5601                try {
5602                    appId = UserHandle.getAppId(
5603                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5604                } catch (RemoteException e) {
5605                }
5606                if (appId == -1) {
5607                    Slog.w(TAG, "Invalid packageName: " + packageName);
5608                    return;
5609                }
5610                killPackageProcessesLocked(packageName, appId, userId,
5611                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5612            }
5613        } finally {
5614            Binder.restoreCallingIdentity(callingId);
5615        }
5616    }
5617
5618    @Override
5619    public void killAllBackgroundProcesses() {
5620        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5621                != PackageManager.PERMISSION_GRANTED) {
5622            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5623                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5624                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5625            Slog.w(TAG, msg);
5626            throw new SecurityException(msg);
5627        }
5628
5629        final long callingId = Binder.clearCallingIdentity();
5630        try {
5631            synchronized (this) {
5632                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5633                final int NP = mProcessNames.getMap().size();
5634                for (int ip = 0; ip < NP; ip++) {
5635                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5636                    final int NA = apps.size();
5637                    for (int ia = 0; ia < NA; ia++) {
5638                        final ProcessRecord app = apps.valueAt(ia);
5639                        if (app.persistent) {
5640                            // We don't kill persistent processes.
5641                            continue;
5642                        }
5643                        if (app.removed) {
5644                            procs.add(app);
5645                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5646                            app.removed = true;
5647                            procs.add(app);
5648                        }
5649                    }
5650                }
5651
5652                final int N = procs.size();
5653                for (int i = 0; i < N; i++) {
5654                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5655                }
5656
5657                mAllowLowerMemLevel = true;
5658
5659                updateOomAdjLocked();
5660                doLowMemReportIfNeededLocked(null);
5661            }
5662        } finally {
5663            Binder.restoreCallingIdentity(callingId);
5664        }
5665    }
5666
5667    /**
5668     * Kills all background processes, except those matching any of the
5669     * specified properties.
5670     *
5671     * @param minTargetSdk the target SDK version at or above which to preserve
5672     *                     processes, or {@code -1} to ignore the target SDK
5673     * @param maxProcState the process state at or below which to preserve
5674     *                     processes, or {@code -1} to ignore the process state
5675     */
5676    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5677        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5678                != PackageManager.PERMISSION_GRANTED) {
5679            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5680                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5681                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5682            Slog.w(TAG, msg);
5683            throw new SecurityException(msg);
5684        }
5685
5686        final long callingId = Binder.clearCallingIdentity();
5687        try {
5688            synchronized (this) {
5689                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5690                final int NP = mProcessNames.getMap().size();
5691                for (int ip = 0; ip < NP; ip++) {
5692                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5693                    final int NA = apps.size();
5694                    for (int ia = 0; ia < NA; ia++) {
5695                        final ProcessRecord app = apps.valueAt(ia);
5696                        if (app.removed) {
5697                            procs.add(app);
5698                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5699                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5700                            app.removed = true;
5701                            procs.add(app);
5702                        }
5703                    }
5704                }
5705
5706                final int N = procs.size();
5707                for (int i = 0; i < N; i++) {
5708                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5709                }
5710            }
5711        } finally {
5712            Binder.restoreCallingIdentity(callingId);
5713        }
5714    }
5715
5716    @Override
5717    public void forceStopPackage(final String packageName, int userId) {
5718        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5719                != PackageManager.PERMISSION_GRANTED) {
5720            String msg = "Permission Denial: forceStopPackage() from pid="
5721                    + Binder.getCallingPid()
5722                    + ", uid=" + Binder.getCallingUid()
5723                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5724            Slog.w(TAG, msg);
5725            throw new SecurityException(msg);
5726        }
5727        final int callingPid = Binder.getCallingPid();
5728        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5729                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5730        long callingId = Binder.clearCallingIdentity();
5731        try {
5732            IPackageManager pm = AppGlobals.getPackageManager();
5733            synchronized(this) {
5734                int[] users = userId == UserHandle.USER_ALL
5735                        ? mUserController.getUsers() : new int[] { userId };
5736                for (int user : users) {
5737                    int pkgUid = -1;
5738                    try {
5739                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5740                                user);
5741                    } catch (RemoteException e) {
5742                    }
5743                    if (pkgUid == -1) {
5744                        Slog.w(TAG, "Invalid packageName: " + packageName);
5745                        continue;
5746                    }
5747                    try {
5748                        pm.setPackageStoppedState(packageName, true, user);
5749                    } catch (RemoteException e) {
5750                    } catch (IllegalArgumentException e) {
5751                        Slog.w(TAG, "Failed trying to unstop package "
5752                                + packageName + ": " + e);
5753                    }
5754                    if (mUserController.isUserRunningLocked(user, 0)) {
5755                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5756                        finishForceStopPackageLocked(packageName, pkgUid);
5757                    }
5758                }
5759            }
5760        } finally {
5761            Binder.restoreCallingIdentity(callingId);
5762        }
5763    }
5764
5765    @Override
5766    public void addPackageDependency(String packageName) {
5767        synchronized (this) {
5768            int callingPid = Binder.getCallingPid();
5769            if (callingPid == Process.myPid()) {
5770                //  Yeah, um, no.
5771                return;
5772            }
5773            ProcessRecord proc;
5774            synchronized (mPidsSelfLocked) {
5775                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5776            }
5777            if (proc != null) {
5778                if (proc.pkgDeps == null) {
5779                    proc.pkgDeps = new ArraySet<String>(1);
5780                }
5781                proc.pkgDeps.add(packageName);
5782            }
5783        }
5784    }
5785
5786    /*
5787     * The pkg name and app id have to be specified.
5788     */
5789    @Override
5790    public void killApplication(String pkg, int appId, int userId, String reason) {
5791        if (pkg == null) {
5792            return;
5793        }
5794        // Make sure the uid is valid.
5795        if (appId < 0) {
5796            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5797            return;
5798        }
5799        int callerUid = Binder.getCallingUid();
5800        // Only the system server can kill an application
5801        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5802            // Post an aysnc message to kill the application
5803            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5804            msg.arg1 = appId;
5805            msg.arg2 = userId;
5806            Bundle bundle = new Bundle();
5807            bundle.putString("pkg", pkg);
5808            bundle.putString("reason", reason);
5809            msg.obj = bundle;
5810            mHandler.sendMessage(msg);
5811        } else {
5812            throw new SecurityException(callerUid + " cannot kill pkg: " +
5813                    pkg);
5814        }
5815    }
5816
5817    @Override
5818    public void closeSystemDialogs(String reason) {
5819        enforceNotIsolatedCaller("closeSystemDialogs");
5820
5821        final int pid = Binder.getCallingPid();
5822        final int uid = Binder.getCallingUid();
5823        final long origId = Binder.clearCallingIdentity();
5824        try {
5825            synchronized (this) {
5826                // Only allow this from foreground processes, so that background
5827                // applications can't abuse it to prevent system UI from being shown.
5828                if (uid >= Process.FIRST_APPLICATION_UID) {
5829                    ProcessRecord proc;
5830                    synchronized (mPidsSelfLocked) {
5831                        proc = mPidsSelfLocked.get(pid);
5832                    }
5833                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5834                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5835                                + " from background process " + proc);
5836                        return;
5837                    }
5838                }
5839                closeSystemDialogsLocked(reason);
5840            }
5841        } finally {
5842            Binder.restoreCallingIdentity(origId);
5843        }
5844    }
5845
5846    void closeSystemDialogsLocked(String reason) {
5847        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5848        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5849                | Intent.FLAG_RECEIVER_FOREGROUND);
5850        if (reason != null) {
5851            intent.putExtra("reason", reason);
5852        }
5853        mWindowManager.closeSystemDialogs(reason);
5854
5855        mStackSupervisor.closeSystemDialogsLocked();
5856
5857        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5858                AppOpsManager.OP_NONE, null, false, false,
5859                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5860    }
5861
5862    @Override
5863    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5864        enforceNotIsolatedCaller("getProcessMemoryInfo");
5865        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5866        for (int i=pids.length-1; i>=0; i--) {
5867            ProcessRecord proc;
5868            int oomAdj;
5869            synchronized (this) {
5870                synchronized (mPidsSelfLocked) {
5871                    proc = mPidsSelfLocked.get(pids[i]);
5872                    oomAdj = proc != null ? proc.setAdj : 0;
5873                }
5874            }
5875            infos[i] = new Debug.MemoryInfo();
5876            Debug.getMemoryInfo(pids[i], infos[i]);
5877            if (proc != null) {
5878                synchronized (this) {
5879                    if (proc.thread != null && proc.setAdj == oomAdj) {
5880                        // Record this for posterity if the process has been stable.
5881                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5882                                infos[i].getTotalUss(), false, proc.pkgList);
5883                    }
5884                }
5885            }
5886        }
5887        return infos;
5888    }
5889
5890    @Override
5891    public long[] getProcessPss(int[] pids) {
5892        enforceNotIsolatedCaller("getProcessPss");
5893        long[] pss = new long[pids.length];
5894        for (int i=pids.length-1; i>=0; i--) {
5895            ProcessRecord proc;
5896            int oomAdj;
5897            synchronized (this) {
5898                synchronized (mPidsSelfLocked) {
5899                    proc = mPidsSelfLocked.get(pids[i]);
5900                    oomAdj = proc != null ? proc.setAdj : 0;
5901                }
5902            }
5903            long[] tmpUss = new long[1];
5904            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5905            if (proc != null) {
5906                synchronized (this) {
5907                    if (proc.thread != null && proc.setAdj == oomAdj) {
5908                        // Record this for posterity if the process has been stable.
5909                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5910                    }
5911                }
5912            }
5913        }
5914        return pss;
5915    }
5916
5917    @Override
5918    public void killApplicationProcess(String processName, int uid) {
5919        if (processName == null) {
5920            return;
5921        }
5922
5923        int callerUid = Binder.getCallingUid();
5924        // Only the system server can kill an application
5925        if (callerUid == Process.SYSTEM_UID) {
5926            synchronized (this) {
5927                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5928                if (app != null && app.thread != null) {
5929                    try {
5930                        app.thread.scheduleSuicide();
5931                    } catch (RemoteException e) {
5932                        // If the other end already died, then our work here is done.
5933                    }
5934                } else {
5935                    Slog.w(TAG, "Process/uid not found attempting kill of "
5936                            + processName + " / " + uid);
5937                }
5938            }
5939        } else {
5940            throw new SecurityException(callerUid + " cannot kill app process: " +
5941                    processName);
5942        }
5943    }
5944
5945    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5946        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5947                false, true, false, false, UserHandle.getUserId(uid), reason);
5948    }
5949
5950    private void finishForceStopPackageLocked(final String packageName, int uid) {
5951        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5952                Uri.fromParts("package", packageName, null));
5953        if (!mProcessesReady) {
5954            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5955                    | Intent.FLAG_RECEIVER_FOREGROUND);
5956        }
5957        intent.putExtra(Intent.EXTRA_UID, uid);
5958        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5959        broadcastIntentLocked(null, null, intent,
5960                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5961                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5962    }
5963
5964
5965    private final boolean killPackageProcessesLocked(String packageName, int appId,
5966            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5967            boolean doit, boolean evenPersistent, String reason) {
5968        ArrayList<ProcessRecord> procs = new ArrayList<>();
5969
5970        // Remove all processes this package may have touched: all with the
5971        // same UID (except for the system or root user), and all whose name
5972        // matches the package name.
5973        final int NP = mProcessNames.getMap().size();
5974        for (int ip=0; ip<NP; ip++) {
5975            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5976            final int NA = apps.size();
5977            for (int ia=0; ia<NA; ia++) {
5978                ProcessRecord app = apps.valueAt(ia);
5979                if (app.persistent && !evenPersistent) {
5980                    // we don't kill persistent processes
5981                    continue;
5982                }
5983                if (app.removed) {
5984                    if (doit) {
5985                        procs.add(app);
5986                    }
5987                    continue;
5988                }
5989
5990                // Skip process if it doesn't meet our oom adj requirement.
5991                if (app.setAdj < minOomAdj) {
5992                    continue;
5993                }
5994
5995                // If no package is specified, we call all processes under the
5996                // give user id.
5997                if (packageName == null) {
5998                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5999                        continue;
6000                    }
6001                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6002                        continue;
6003                    }
6004                // Package has been specified, we want to hit all processes
6005                // that match it.  We need to qualify this by the processes
6006                // that are running under the specified app and user ID.
6007                } else {
6008                    final boolean isDep = app.pkgDeps != null
6009                            && app.pkgDeps.contains(packageName);
6010                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6011                        continue;
6012                    }
6013                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6014                        continue;
6015                    }
6016                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6017                        continue;
6018                    }
6019                }
6020
6021                // Process has passed all conditions, kill it!
6022                if (!doit) {
6023                    return true;
6024                }
6025                app.removed = true;
6026                procs.add(app);
6027            }
6028        }
6029
6030        int N = procs.size();
6031        for (int i=0; i<N; i++) {
6032            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6033        }
6034        updateOomAdjLocked();
6035        return N > 0;
6036    }
6037
6038    private void cleanupDisabledPackageComponentsLocked(
6039            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6040
6041        Set<String> disabledClasses = null;
6042        boolean packageDisabled = false;
6043        IPackageManager pm = AppGlobals.getPackageManager();
6044
6045        if (changedClasses == null) {
6046            // Nothing changed...
6047            return;
6048        }
6049
6050        // Determine enable/disable state of the package and its components.
6051        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6052        for (int i = changedClasses.length - 1; i >= 0; i--) {
6053            final String changedClass = changedClasses[i];
6054
6055            if (changedClass.equals(packageName)) {
6056                try {
6057                    // Entire package setting changed
6058                    enabled = pm.getApplicationEnabledSetting(packageName,
6059                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6060                } catch (Exception e) {
6061                    // No such package/component; probably racing with uninstall.  In any
6062                    // event it means we have nothing further to do here.
6063                    return;
6064                }
6065                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6066                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6067                if (packageDisabled) {
6068                    // Entire package is disabled.
6069                    // No need to continue to check component states.
6070                    disabledClasses = null;
6071                    break;
6072                }
6073            } else {
6074                try {
6075                    enabled = pm.getComponentEnabledSetting(
6076                            new ComponentName(packageName, changedClass),
6077                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6078                } catch (Exception e) {
6079                    // As above, probably racing with uninstall.
6080                    return;
6081                }
6082                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6083                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6084                    if (disabledClasses == null) {
6085                        disabledClasses = new ArraySet<>(changedClasses.length);
6086                    }
6087                    disabledClasses.add(changedClass);
6088                }
6089            }
6090        }
6091
6092        if (!packageDisabled && disabledClasses == null) {
6093            // Nothing to do here...
6094            return;
6095        }
6096
6097        // Clean-up disabled activities.
6098        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6099                packageName, disabledClasses, true, false, userId) && mBooted) {
6100            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6101            mStackSupervisor.scheduleIdleLocked();
6102        }
6103
6104        // Clean-up disabled tasks
6105        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6106
6107        // Clean-up disabled services.
6108        mServices.bringDownDisabledPackageServicesLocked(
6109                packageName, disabledClasses, userId, false, killProcess, true);
6110
6111        // Clean-up disabled providers.
6112        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6113        mProviderMap.collectPackageProvidersLocked(
6114                packageName, disabledClasses, true, false, userId, providers);
6115        for (int i = providers.size() - 1; i >= 0; i--) {
6116            removeDyingProviderLocked(null, providers.get(i), true);
6117        }
6118
6119        // Clean-up disabled broadcast receivers.
6120        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6121            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6122                    packageName, disabledClasses, userId, true);
6123        }
6124
6125    }
6126
6127    final boolean clearBroadcastQueueForUserLocked(int userId) {
6128        boolean didSomething = false;
6129        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6130            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6131                    null, null, userId, true);
6132        }
6133        return didSomething;
6134    }
6135
6136    final boolean forceStopPackageLocked(String packageName, int appId,
6137            boolean callerWillRestart, boolean purgeCache, boolean doit,
6138            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6139        int i;
6140
6141        if (userId == UserHandle.USER_ALL && packageName == null) {
6142            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6143        }
6144
6145        if (appId < 0 && packageName != null) {
6146            try {
6147                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6148                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6149            } catch (RemoteException e) {
6150            }
6151        }
6152
6153        if (doit) {
6154            if (packageName != null) {
6155                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6156                        + " user=" + userId + ": " + reason);
6157            } else {
6158                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6159            }
6160
6161            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6162        }
6163
6164        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6165                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6166                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6167
6168        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6169
6170        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6171                packageName, null, doit, evenPersistent, userId)) {
6172            if (!doit) {
6173                return true;
6174            }
6175            didSomething = true;
6176        }
6177
6178        if (mServices.bringDownDisabledPackageServicesLocked(
6179                packageName, null, userId, evenPersistent, true, doit)) {
6180            if (!doit) {
6181                return true;
6182            }
6183            didSomething = true;
6184        }
6185
6186        if (packageName == null) {
6187            // Remove all sticky broadcasts from this user.
6188            mStickyBroadcasts.remove(userId);
6189        }
6190
6191        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6192        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6193                userId, providers)) {
6194            if (!doit) {
6195                return true;
6196            }
6197            didSomething = true;
6198        }
6199        for (i = providers.size() - 1; i >= 0; i--) {
6200            removeDyingProviderLocked(null, providers.get(i), true);
6201        }
6202
6203        // Remove transient permissions granted from/to this package/user
6204        removeUriPermissionsForPackageLocked(packageName, userId, false);
6205
6206        if (doit) {
6207            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6208                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6209                        packageName, null, userId, doit);
6210            }
6211        }
6212
6213        if (packageName == null || uninstalling) {
6214            // Remove pending intents.  For now we only do this when force
6215            // stopping users, because we have some problems when doing this
6216            // for packages -- app widgets are not currently cleaned up for
6217            // such packages, so they can be left with bad pending intents.
6218            if (mIntentSenderRecords.size() > 0) {
6219                Iterator<WeakReference<PendingIntentRecord>> it
6220                        = mIntentSenderRecords.values().iterator();
6221                while (it.hasNext()) {
6222                    WeakReference<PendingIntentRecord> wpir = it.next();
6223                    if (wpir == null) {
6224                        it.remove();
6225                        continue;
6226                    }
6227                    PendingIntentRecord pir = wpir.get();
6228                    if (pir == null) {
6229                        it.remove();
6230                        continue;
6231                    }
6232                    if (packageName == null) {
6233                        // Stopping user, remove all objects for the user.
6234                        if (pir.key.userId != userId) {
6235                            // Not the same user, skip it.
6236                            continue;
6237                        }
6238                    } else {
6239                        if (UserHandle.getAppId(pir.uid) != appId) {
6240                            // Different app id, skip it.
6241                            continue;
6242                        }
6243                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6244                            // Different user, skip it.
6245                            continue;
6246                        }
6247                        if (!pir.key.packageName.equals(packageName)) {
6248                            // Different package, skip it.
6249                            continue;
6250                        }
6251                    }
6252                    if (!doit) {
6253                        return true;
6254                    }
6255                    didSomething = true;
6256                    it.remove();
6257                    pir.canceled = true;
6258                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6259                        pir.key.activity.pendingResults.remove(pir.ref);
6260                    }
6261                }
6262            }
6263        }
6264
6265        if (doit) {
6266            if (purgeCache && packageName != null) {
6267                AttributeCache ac = AttributeCache.instance();
6268                if (ac != null) {
6269                    ac.removePackage(packageName);
6270                }
6271            }
6272            if (mBooted) {
6273                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6274                mStackSupervisor.scheduleIdleLocked();
6275            }
6276        }
6277
6278        return didSomething;
6279    }
6280
6281    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6282        ProcessRecord old = mProcessNames.remove(name, uid);
6283        if (old != null) {
6284            old.uidRecord.numProcs--;
6285            if (old.uidRecord.numProcs == 0) {
6286                // No more processes using this uid, tell clients it is gone.
6287                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6288                        "No more processes in " + old.uidRecord);
6289                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6290                mActiveUids.remove(uid);
6291                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6292            }
6293            old.uidRecord = null;
6294        }
6295        mIsolatedProcesses.remove(uid);
6296        return old;
6297    }
6298
6299    private final void addProcessNameLocked(ProcessRecord proc) {
6300        // We shouldn't already have a process under this name, but just in case we
6301        // need to clean up whatever may be there now.
6302        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6303        if (old == proc && proc.persistent) {
6304            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6305            Slog.w(TAG, "Re-adding persistent process " + proc);
6306        } else if (old != null) {
6307            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6308        }
6309        UidRecord uidRec = mActiveUids.get(proc.uid);
6310        if (uidRec == null) {
6311            uidRec = new UidRecord(proc.uid);
6312            // This is the first appearance of the uid, report it now!
6313            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6314                    "Creating new process uid: " + uidRec);
6315            mActiveUids.put(proc.uid, uidRec);
6316            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6317            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6318        }
6319        proc.uidRecord = uidRec;
6320
6321        // Reset render thread tid if it was already set, so new process can set it again.
6322        proc.renderThreadTid = 0;
6323        uidRec.numProcs++;
6324        mProcessNames.put(proc.processName, proc.uid, proc);
6325        if (proc.isolated) {
6326            mIsolatedProcesses.put(proc.uid, proc);
6327        }
6328    }
6329
6330    boolean removeProcessLocked(ProcessRecord app,
6331            boolean callerWillRestart, boolean allowRestart, String reason) {
6332        final String name = app.processName;
6333        final int uid = app.uid;
6334        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6335            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6336
6337        ProcessRecord old = mProcessNames.get(name, uid);
6338        if (old != app) {
6339            // This process is no longer active, so nothing to do.
6340            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6341            return false;
6342        }
6343        removeProcessNameLocked(name, uid);
6344        if (mHeavyWeightProcess == app) {
6345            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6346                    mHeavyWeightProcess.userId, 0));
6347            mHeavyWeightProcess = null;
6348        }
6349        boolean needRestart = false;
6350        if (app.pid > 0 && app.pid != MY_PID) {
6351            int pid = app.pid;
6352            synchronized (mPidsSelfLocked) {
6353                mPidsSelfLocked.remove(pid);
6354                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6355            }
6356            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6357            if (app.isolated) {
6358                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6359            }
6360            boolean willRestart = false;
6361            if (app.persistent && !app.isolated) {
6362                if (!callerWillRestart) {
6363                    willRestart = true;
6364                } else {
6365                    needRestart = true;
6366                }
6367            }
6368            app.kill(reason, true);
6369            handleAppDiedLocked(app, willRestart, allowRestart);
6370            if (willRestart) {
6371                removeLruProcessLocked(app);
6372                addAppLocked(app.info, false, null /* ABI override */);
6373            }
6374        } else {
6375            mRemovedProcesses.add(app);
6376        }
6377
6378        return needRestart;
6379    }
6380
6381    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6382        cleanupAppInLaunchingProvidersLocked(app, true);
6383        removeProcessLocked(app, false, true, "timeout publishing content providers");
6384    }
6385
6386    private final void processStartTimedOutLocked(ProcessRecord app) {
6387        final int pid = app.pid;
6388        boolean gone = false;
6389        synchronized (mPidsSelfLocked) {
6390            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6391            if (knownApp != null && knownApp.thread == null) {
6392                mPidsSelfLocked.remove(pid);
6393                gone = true;
6394            }
6395        }
6396
6397        if (gone) {
6398            Slog.w(TAG, "Process " + app + " failed to attach");
6399            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6400                    pid, app.uid, app.processName);
6401            removeProcessNameLocked(app.processName, app.uid);
6402            if (mHeavyWeightProcess == app) {
6403                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6404                        mHeavyWeightProcess.userId, 0));
6405                mHeavyWeightProcess = null;
6406            }
6407            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6408            if (app.isolated) {
6409                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6410            }
6411            // Take care of any launching providers waiting for this process.
6412            cleanupAppInLaunchingProvidersLocked(app, true);
6413            // Take care of any services that are waiting for the process.
6414            mServices.processStartTimedOutLocked(app);
6415            app.kill("start timeout", true);
6416            removeLruProcessLocked(app);
6417            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6418                Slog.w(TAG, "Unattached app died before backup, skipping");
6419                try {
6420                    IBackupManager bm = IBackupManager.Stub.asInterface(
6421                            ServiceManager.getService(Context.BACKUP_SERVICE));
6422                    bm.agentDisconnected(app.info.packageName);
6423                } catch (RemoteException e) {
6424                    // Can't happen; the backup manager is local
6425                }
6426            }
6427            if (isPendingBroadcastProcessLocked(pid)) {
6428                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6429                skipPendingBroadcastLocked(pid);
6430            }
6431        } else {
6432            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6433        }
6434    }
6435
6436    private final boolean attachApplicationLocked(IApplicationThread thread,
6437            int pid) {
6438
6439        // Find the application record that is being attached...  either via
6440        // the pid if we are running in multiple processes, or just pull the
6441        // next app record if we are emulating process with anonymous threads.
6442        ProcessRecord app;
6443        if (pid != MY_PID && pid >= 0) {
6444            synchronized (mPidsSelfLocked) {
6445                app = mPidsSelfLocked.get(pid);
6446            }
6447        } else {
6448            app = null;
6449        }
6450
6451        if (app == null) {
6452            Slog.w(TAG, "No pending application record for pid " + pid
6453                    + " (IApplicationThread " + thread + "); dropping process");
6454            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6455            if (pid > 0 && pid != MY_PID) {
6456                Process.killProcessQuiet(pid);
6457                //TODO: killProcessGroup(app.info.uid, pid);
6458            } else {
6459                try {
6460                    thread.scheduleExit();
6461                } catch (Exception e) {
6462                    // Ignore exceptions.
6463                }
6464            }
6465            return false;
6466        }
6467
6468        // If this application record is still attached to a previous
6469        // process, clean it up now.
6470        if (app.thread != null) {
6471            handleAppDiedLocked(app, true, true);
6472        }
6473
6474        // Tell the process all about itself.
6475
6476        if (DEBUG_ALL) Slog.v(
6477                TAG, "Binding process pid " + pid + " to record " + app);
6478
6479        final String processName = app.processName;
6480        try {
6481            AppDeathRecipient adr = new AppDeathRecipient(
6482                    app, pid, thread);
6483            thread.asBinder().linkToDeath(adr, 0);
6484            app.deathRecipient = adr;
6485        } catch (RemoteException e) {
6486            app.resetPackageList(mProcessStats);
6487            startProcessLocked(app, "link fail", processName);
6488            return false;
6489        }
6490
6491        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6492
6493        app.makeActive(thread, mProcessStats);
6494        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6495        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6496        app.forcingToForeground = null;
6497        updateProcessForegroundLocked(app, false, false);
6498        app.hasShownUi = false;
6499        app.debugging = false;
6500        app.cached = false;
6501        app.killedByAm = false;
6502        app.killed = false;
6503
6504
6505        // We carefully use the same state that PackageManager uses for
6506        // filtering, since we use this flag to decide if we need to install
6507        // providers when user is unlocked later
6508        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6509
6510        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6511
6512        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6513        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6514
6515        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6516            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6517            msg.obj = app;
6518            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6519        }
6520
6521        if (!normalMode) {
6522            Slog.i(TAG, "Launching preboot mode app: " + app);
6523        }
6524
6525        if (DEBUG_ALL) Slog.v(
6526            TAG, "New app record " + app
6527            + " thread=" + thread.asBinder() + " pid=" + pid);
6528        try {
6529            int testMode = IApplicationThread.DEBUG_OFF;
6530            if (mDebugApp != null && mDebugApp.equals(processName)) {
6531                testMode = mWaitForDebugger
6532                    ? IApplicationThread.DEBUG_WAIT
6533                    : IApplicationThread.DEBUG_ON;
6534                app.debugging = true;
6535                if (mDebugTransient) {
6536                    mDebugApp = mOrigDebugApp;
6537                    mWaitForDebugger = mOrigWaitForDebugger;
6538                }
6539            }
6540            String profileFile = app.instrumentationProfileFile;
6541            ParcelFileDescriptor profileFd = null;
6542            int samplingInterval = 0;
6543            boolean profileAutoStop = false;
6544            if (mProfileApp != null && mProfileApp.equals(processName)) {
6545                mProfileProc = app;
6546                profileFile = mProfileFile;
6547                profileFd = mProfileFd;
6548                samplingInterval = mSamplingInterval;
6549                profileAutoStop = mAutoStopProfiler;
6550            }
6551            boolean enableTrackAllocation = false;
6552            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6553                enableTrackAllocation = true;
6554                mTrackAllocationApp = null;
6555            }
6556
6557            // If the app is being launched for restore or full backup, set it up specially
6558            boolean isRestrictedBackupMode = false;
6559            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6560                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6561                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6562                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6563                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6564            }
6565
6566            if (app.instrumentationClass != null) {
6567                notifyPackageUse(app.instrumentationClass.getPackageName(),
6568                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6569            }
6570            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6571                    + processName + " with config " + mConfiguration);
6572            ApplicationInfo appInfo = app.instrumentationInfo != null
6573                    ? app.instrumentationInfo : app.info;
6574            app.compat = compatibilityInfoForPackageLocked(appInfo);
6575            if (profileFd != null) {
6576                profileFd = profileFd.dup();
6577            }
6578            ProfilerInfo profilerInfo = profileFile == null ? null
6579                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6580            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6581                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6582                    app.instrumentationUiAutomationConnection, testMode,
6583                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6584                    isRestrictedBackupMode || !normalMode, app.persistent,
6585                    new Configuration(mConfiguration), app.compat,
6586                    getCommonServicesLocked(app.isolated),
6587                    mCoreSettingsObserver.getCoreSettingsLocked());
6588            updateLruProcessLocked(app, false, null);
6589            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6590        } catch (Exception e) {
6591            // todo: Yikes!  What should we do?  For now we will try to
6592            // start another process, but that could easily get us in
6593            // an infinite loop of restarting processes...
6594            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6595
6596            app.resetPackageList(mProcessStats);
6597            app.unlinkDeathRecipient();
6598            startProcessLocked(app, "bind fail", processName);
6599            return false;
6600        }
6601
6602        // Remove this record from the list of starting applications.
6603        mPersistentStartingProcesses.remove(app);
6604        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6605                "Attach application locked removing on hold: " + app);
6606        mProcessesOnHold.remove(app);
6607
6608        boolean badApp = false;
6609        boolean didSomething = false;
6610
6611        // See if the top visible activity is waiting to run in this process...
6612        if (normalMode) {
6613            try {
6614                if (mStackSupervisor.attachApplicationLocked(app)) {
6615                    didSomething = true;
6616                }
6617            } catch (Exception e) {
6618                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6619                badApp = true;
6620            }
6621        }
6622
6623        // Find any services that should be running in this process...
6624        if (!badApp) {
6625            try {
6626                didSomething |= mServices.attachApplicationLocked(app, processName);
6627            } catch (Exception e) {
6628                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6629                badApp = true;
6630            }
6631        }
6632
6633        // Check if a next-broadcast receiver is in this process...
6634        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6635            try {
6636                didSomething |= sendPendingBroadcastsLocked(app);
6637            } catch (Exception e) {
6638                // If the app died trying to launch the receiver we declare it 'bad'
6639                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6640                badApp = true;
6641            }
6642        }
6643
6644        // Check whether the next backup agent is in this process...
6645        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6646            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6647                    "New app is backup target, launching agent for " + app);
6648            notifyPackageUse(mBackupTarget.appInfo.packageName,
6649                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6650            try {
6651                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6652                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6653                        mBackupTarget.backupMode);
6654            } catch (Exception e) {
6655                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6656                badApp = true;
6657            }
6658        }
6659
6660        if (badApp) {
6661            app.kill("error during init", true);
6662            handleAppDiedLocked(app, false, true);
6663            return false;
6664        }
6665
6666        if (!didSomething) {
6667            updateOomAdjLocked();
6668        }
6669
6670        return true;
6671    }
6672
6673    @Override
6674    public final void attachApplication(IApplicationThread thread) {
6675        synchronized (this) {
6676            int callingPid = Binder.getCallingPid();
6677            final long origId = Binder.clearCallingIdentity();
6678            attachApplicationLocked(thread, callingPid);
6679            Binder.restoreCallingIdentity(origId);
6680        }
6681    }
6682
6683    @Override
6684    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6685        final long origId = Binder.clearCallingIdentity();
6686        synchronized (this) {
6687            ActivityStack stack = ActivityRecord.getStackLocked(token);
6688            if (stack != null) {
6689                ActivityRecord r =
6690                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6691                if (stopProfiling) {
6692                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6693                        try {
6694                            mProfileFd.close();
6695                        } catch (IOException e) {
6696                        }
6697                        clearProfilerLocked();
6698                    }
6699                }
6700            }
6701        }
6702        Binder.restoreCallingIdentity(origId);
6703    }
6704
6705    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6706        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6707                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6708    }
6709
6710    void enableScreenAfterBoot() {
6711        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6712                SystemClock.uptimeMillis());
6713        mWindowManager.enableScreenAfterBoot();
6714
6715        synchronized (this) {
6716            updateEventDispatchingLocked();
6717        }
6718    }
6719
6720    @Override
6721    public void showBootMessage(final CharSequence msg, final boolean always) {
6722        if (Binder.getCallingUid() != Process.myUid()) {
6723            throw new SecurityException();
6724        }
6725        mWindowManager.showBootMessage(msg, always);
6726    }
6727
6728    @Override
6729    public void keyguardWaitingForActivityDrawn() {
6730        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6731        final long token = Binder.clearCallingIdentity();
6732        try {
6733            synchronized (this) {
6734                if (DEBUG_LOCKSCREEN) logLockScreen("");
6735                mWindowManager.keyguardWaitingForActivityDrawn();
6736                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6737                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6738                    updateSleepIfNeededLocked();
6739                }
6740            }
6741        } finally {
6742            Binder.restoreCallingIdentity(token);
6743        }
6744    }
6745
6746    @Override
6747    public void keyguardGoingAway(int flags) {
6748        enforceNotIsolatedCaller("keyguardGoingAway");
6749        final long token = Binder.clearCallingIdentity();
6750        try {
6751            synchronized (this) {
6752                if (DEBUG_LOCKSCREEN) logLockScreen("");
6753                mWindowManager.keyguardGoingAway(flags);
6754                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6755                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6756                    updateSleepIfNeededLocked();
6757
6758                    // Some stack visibility might change (e.g. docked stack)
6759                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6760                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6761                }
6762            }
6763        } finally {
6764            Binder.restoreCallingIdentity(token);
6765        }
6766    }
6767
6768    final void finishBooting() {
6769        synchronized (this) {
6770            if (!mBootAnimationComplete) {
6771                mCallFinishBooting = true;
6772                return;
6773            }
6774            mCallFinishBooting = false;
6775        }
6776
6777        ArraySet<String> completedIsas = new ArraySet<String>();
6778        for (String abi : Build.SUPPORTED_ABIS) {
6779            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6780            final String instructionSet = VMRuntime.getInstructionSet(abi);
6781            if (!completedIsas.contains(instructionSet)) {
6782                try {
6783                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6784                } catch (InstallerException e) {
6785                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6786                            e.getMessage() +")");
6787                }
6788                completedIsas.add(instructionSet);
6789            }
6790        }
6791
6792        IntentFilter pkgFilter = new IntentFilter();
6793        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6794        pkgFilter.addDataScheme("package");
6795        mContext.registerReceiver(new BroadcastReceiver() {
6796            @Override
6797            public void onReceive(Context context, Intent intent) {
6798                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6799                if (pkgs != null) {
6800                    for (String pkg : pkgs) {
6801                        synchronized (ActivityManagerService.this) {
6802                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6803                                    0, "query restart")) {
6804                                setResultCode(Activity.RESULT_OK);
6805                                return;
6806                            }
6807                        }
6808                    }
6809                }
6810            }
6811        }, pkgFilter);
6812
6813        IntentFilter dumpheapFilter = new IntentFilter();
6814        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6815        mContext.registerReceiver(new BroadcastReceiver() {
6816            @Override
6817            public void onReceive(Context context, Intent intent) {
6818                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6819                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6820                } else {
6821                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6822                }
6823            }
6824        }, dumpheapFilter);
6825
6826        // Let system services know.
6827        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6828
6829        synchronized (this) {
6830            // Ensure that any processes we had put on hold are now started
6831            // up.
6832            final int NP = mProcessesOnHold.size();
6833            if (NP > 0) {
6834                ArrayList<ProcessRecord> procs =
6835                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6836                for (int ip=0; ip<NP; ip++) {
6837                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6838                            + procs.get(ip));
6839                    startProcessLocked(procs.get(ip), "on-hold", null);
6840                }
6841            }
6842
6843            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6844                // Start looking for apps that are abusing wake locks.
6845                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6846                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6847                // Tell anyone interested that we are done booting!
6848                SystemProperties.set("sys.boot_completed", "1");
6849
6850                // And trigger dev.bootcomplete if we are not showing encryption progress
6851                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6852                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6853                    SystemProperties.set("dev.bootcomplete", "1");
6854                }
6855                mUserController.sendBootCompletedLocked(
6856                        new IIntentReceiver.Stub() {
6857                            @Override
6858                            public void performReceive(Intent intent, int resultCode,
6859                                    String data, Bundle extras, boolean ordered,
6860                                    boolean sticky, int sendingUser) {
6861                                synchronized (ActivityManagerService.this) {
6862                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6863                                            true, false);
6864                                }
6865                            }
6866                        });
6867                scheduleStartProfilesLocked();
6868            }
6869        }
6870    }
6871
6872    @Override
6873    public void bootAnimationComplete() {
6874        final boolean callFinishBooting;
6875        synchronized (this) {
6876            callFinishBooting = mCallFinishBooting;
6877            mBootAnimationComplete = true;
6878        }
6879        if (callFinishBooting) {
6880            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6881            finishBooting();
6882            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6883        }
6884    }
6885
6886    final void ensureBootCompleted() {
6887        boolean booting;
6888        boolean enableScreen;
6889        synchronized (this) {
6890            booting = mBooting;
6891            mBooting = false;
6892            enableScreen = !mBooted;
6893            mBooted = true;
6894        }
6895
6896        if (booting) {
6897            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6898            finishBooting();
6899            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6900        }
6901
6902        if (enableScreen) {
6903            enableScreenAfterBoot();
6904        }
6905    }
6906
6907    @Override
6908    public final void activityResumed(IBinder token) {
6909        final long origId = Binder.clearCallingIdentity();
6910        synchronized(this) {
6911            ActivityStack stack = ActivityRecord.getStackLocked(token);
6912            if (stack != null) {
6913                stack.activityResumedLocked(token);
6914            }
6915        }
6916        Binder.restoreCallingIdentity(origId);
6917    }
6918
6919    @Override
6920    public final void activityPaused(IBinder token) {
6921        final long origId = Binder.clearCallingIdentity();
6922        synchronized(this) {
6923            ActivityStack stack = ActivityRecord.getStackLocked(token);
6924            if (stack != null) {
6925                stack.activityPausedLocked(token, false);
6926            }
6927        }
6928        Binder.restoreCallingIdentity(origId);
6929    }
6930
6931    @Override
6932    public final void activityStopped(IBinder token, Bundle icicle,
6933            PersistableBundle persistentState, CharSequence description) {
6934        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6935
6936        // Refuse possible leaked file descriptors
6937        if (icicle != null && icicle.hasFileDescriptors()) {
6938            throw new IllegalArgumentException("File descriptors passed in Bundle");
6939        }
6940
6941        final long origId = Binder.clearCallingIdentity();
6942
6943        synchronized (this) {
6944            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6945            if (r != null) {
6946                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6947            }
6948        }
6949
6950        trimApplications();
6951
6952        Binder.restoreCallingIdentity(origId);
6953    }
6954
6955    @Override
6956    public final void activityDestroyed(IBinder token) {
6957        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6958        synchronized (this) {
6959            ActivityStack stack = ActivityRecord.getStackLocked(token);
6960            if (stack != null) {
6961                stack.activityDestroyedLocked(token, "activityDestroyed");
6962            }
6963        }
6964    }
6965
6966    @Override
6967    public final void activityRelaunched(IBinder token) {
6968        final long origId = Binder.clearCallingIdentity();
6969        synchronized (this) {
6970            mStackSupervisor.activityRelaunchedLocked(token);
6971        }
6972        Binder.restoreCallingIdentity(origId);
6973    }
6974
6975    @Override
6976    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6977            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6978        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6979                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6980        synchronized (this) {
6981            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6982            if (record == null) {
6983                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6984                        + "found for: " + token);
6985            }
6986            record.setSizeConfigurations(horizontalSizeConfiguration,
6987                    verticalSizeConfigurations, smallestSizeConfigurations);
6988        }
6989    }
6990
6991    @Override
6992    public final void backgroundResourcesReleased(IBinder token) {
6993        final long origId = Binder.clearCallingIdentity();
6994        try {
6995            synchronized (this) {
6996                ActivityStack stack = ActivityRecord.getStackLocked(token);
6997                if (stack != null) {
6998                    stack.backgroundResourcesReleased();
6999                }
7000            }
7001        } finally {
7002            Binder.restoreCallingIdentity(origId);
7003        }
7004    }
7005
7006    @Override
7007    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7008        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7009    }
7010
7011    @Override
7012    public final void notifyEnterAnimationComplete(IBinder token) {
7013        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7014    }
7015
7016    @Override
7017    public String getCallingPackage(IBinder token) {
7018        synchronized (this) {
7019            ActivityRecord r = getCallingRecordLocked(token);
7020            return r != null ? r.info.packageName : null;
7021        }
7022    }
7023
7024    @Override
7025    public ComponentName getCallingActivity(IBinder token) {
7026        synchronized (this) {
7027            ActivityRecord r = getCallingRecordLocked(token);
7028            return r != null ? r.intent.getComponent() : null;
7029        }
7030    }
7031
7032    private ActivityRecord getCallingRecordLocked(IBinder token) {
7033        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7034        if (r == null) {
7035            return null;
7036        }
7037        return r.resultTo;
7038    }
7039
7040    @Override
7041    public ComponentName getActivityClassForToken(IBinder token) {
7042        synchronized(this) {
7043            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7044            if (r == null) {
7045                return null;
7046            }
7047            return r.intent.getComponent();
7048        }
7049    }
7050
7051    @Override
7052    public String getPackageForToken(IBinder token) {
7053        synchronized(this) {
7054            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7055            if (r == null) {
7056                return null;
7057            }
7058            return r.packageName;
7059        }
7060    }
7061
7062    @Override
7063    public boolean isRootVoiceInteraction(IBinder token) {
7064        synchronized(this) {
7065            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7066            if (r == null) {
7067                return false;
7068            }
7069            return r.rootVoiceInteraction;
7070        }
7071    }
7072
7073    @Override
7074    public IIntentSender getIntentSender(int type,
7075            String packageName, IBinder token, String resultWho,
7076            int requestCode, Intent[] intents, String[] resolvedTypes,
7077            int flags, Bundle bOptions, int userId) {
7078        enforceNotIsolatedCaller("getIntentSender");
7079        // Refuse possible leaked file descriptors
7080        if (intents != null) {
7081            if (intents.length < 1) {
7082                throw new IllegalArgumentException("Intents array length must be >= 1");
7083            }
7084            for (int i=0; i<intents.length; i++) {
7085                Intent intent = intents[i];
7086                if (intent != null) {
7087                    if (intent.hasFileDescriptors()) {
7088                        throw new IllegalArgumentException("File descriptors passed in Intent");
7089                    }
7090                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7091                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7092                        throw new IllegalArgumentException(
7093                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7094                    }
7095                    intents[i] = new Intent(intent);
7096                }
7097            }
7098            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7099                throw new IllegalArgumentException(
7100                        "Intent array length does not match resolvedTypes length");
7101            }
7102        }
7103        if (bOptions != null) {
7104            if (bOptions.hasFileDescriptors()) {
7105                throw new IllegalArgumentException("File descriptors passed in options");
7106            }
7107        }
7108
7109        synchronized(this) {
7110            int callingUid = Binder.getCallingUid();
7111            int origUserId = userId;
7112            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7113                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7114                    ALLOW_NON_FULL, "getIntentSender", null);
7115            if (origUserId == UserHandle.USER_CURRENT) {
7116                // We don't want to evaluate this until the pending intent is
7117                // actually executed.  However, we do want to always do the
7118                // security checking for it above.
7119                userId = UserHandle.USER_CURRENT;
7120            }
7121            try {
7122                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7123                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7124                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7125                    if (!UserHandle.isSameApp(callingUid, uid)) {
7126                        String msg = "Permission Denial: getIntentSender() from pid="
7127                            + Binder.getCallingPid()
7128                            + ", uid=" + Binder.getCallingUid()
7129                            + ", (need uid=" + uid + ")"
7130                            + " is not allowed to send as package " + packageName;
7131                        Slog.w(TAG, msg);
7132                        throw new SecurityException(msg);
7133                    }
7134                }
7135
7136                return getIntentSenderLocked(type, packageName, callingUid, userId,
7137                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7138
7139            } catch (RemoteException e) {
7140                throw new SecurityException(e);
7141            }
7142        }
7143    }
7144
7145    IIntentSender getIntentSenderLocked(int type, String packageName,
7146            int callingUid, int userId, IBinder token, String resultWho,
7147            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7148            Bundle bOptions) {
7149        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7150        ActivityRecord activity = null;
7151        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7152            activity = ActivityRecord.isInStackLocked(token);
7153            if (activity == null) {
7154                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7155                return null;
7156            }
7157            if (activity.finishing) {
7158                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7159                return null;
7160            }
7161        }
7162
7163        // We're going to be splicing together extras before sending, so we're
7164        // okay poking into any contained extras.
7165        if (intents != null) {
7166            for (int i = 0; i < intents.length; i++) {
7167                intents[i].setDefusable(true);
7168            }
7169        }
7170        Bundle.setDefusable(bOptions, true);
7171
7172        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7173        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7174        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7175        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7176                |PendingIntent.FLAG_UPDATE_CURRENT);
7177
7178        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7179                type, packageName, activity, resultWho,
7180                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7181        WeakReference<PendingIntentRecord> ref;
7182        ref = mIntentSenderRecords.get(key);
7183        PendingIntentRecord rec = ref != null ? ref.get() : null;
7184        if (rec != null) {
7185            if (!cancelCurrent) {
7186                if (updateCurrent) {
7187                    if (rec.key.requestIntent != null) {
7188                        rec.key.requestIntent.replaceExtras(intents != null ?
7189                                intents[intents.length - 1] : null);
7190                    }
7191                    if (intents != null) {
7192                        intents[intents.length-1] = rec.key.requestIntent;
7193                        rec.key.allIntents = intents;
7194                        rec.key.allResolvedTypes = resolvedTypes;
7195                    } else {
7196                        rec.key.allIntents = null;
7197                        rec.key.allResolvedTypes = null;
7198                    }
7199                }
7200                return rec;
7201            }
7202            rec.canceled = true;
7203            mIntentSenderRecords.remove(key);
7204        }
7205        if (noCreate) {
7206            return rec;
7207        }
7208        rec = new PendingIntentRecord(this, key, callingUid);
7209        mIntentSenderRecords.put(key, rec.ref);
7210        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7211            if (activity.pendingResults == null) {
7212                activity.pendingResults
7213                        = new HashSet<WeakReference<PendingIntentRecord>>();
7214            }
7215            activity.pendingResults.add(rec.ref);
7216        }
7217        return rec;
7218    }
7219
7220    @Override
7221    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7222            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7223        if (target instanceof PendingIntentRecord) {
7224            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7225                    finishedReceiver, requiredPermission, options);
7226        } else {
7227            if (intent == null) {
7228                // Weird case: someone has given us their own custom IIntentSender, and now
7229                // they have someone else trying to send to it but of course this isn't
7230                // really a PendingIntent, so there is no base Intent, and the caller isn't
7231                // supplying an Intent... but we never want to dispatch a null Intent to
7232                // a receiver, so um...  let's make something up.
7233                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7234                intent = new Intent(Intent.ACTION_MAIN);
7235            }
7236            try {
7237                target.send(code, intent, resolvedType, null, requiredPermission, options);
7238            } catch (RemoteException e) {
7239            }
7240            // Platform code can rely on getting a result back when the send is done, but if
7241            // this intent sender is from outside of the system we can't rely on it doing that.
7242            // So instead we don't give it the result receiver, and instead just directly
7243            // report the finish immediately.
7244            if (finishedReceiver != null) {
7245                try {
7246                    finishedReceiver.performReceive(intent, 0,
7247                            null, null, false, false, UserHandle.getCallingUserId());
7248                } catch (RemoteException e) {
7249                }
7250            }
7251            return 0;
7252        }
7253    }
7254
7255    /**
7256     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7257     *
7258     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7259     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7260     */
7261    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7262        if (DEBUG_WHITELISTS) {
7263            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7264                    + targetUid + ", " + duration + ")");
7265        }
7266        synchronized (mPidsSelfLocked) {
7267            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7268            if (pr == null) {
7269                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7270                return;
7271            }
7272            if (!pr.whitelistManager) {
7273                if (DEBUG_WHITELISTS) {
7274                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7275                            + callerPid + " is not allowed");
7276                }
7277                return;
7278            }
7279        }
7280
7281        final long token = Binder.clearCallingIdentity();
7282        try {
7283            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7284                    true, "pe from uid:" + callerUid);
7285        } finally {
7286            Binder.restoreCallingIdentity(token);
7287        }
7288    }
7289
7290    @Override
7291    public void cancelIntentSender(IIntentSender sender) {
7292        if (!(sender instanceof PendingIntentRecord)) {
7293            return;
7294        }
7295        synchronized(this) {
7296            PendingIntentRecord rec = (PendingIntentRecord)sender;
7297            try {
7298                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7299                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7300                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7301                    String msg = "Permission Denial: cancelIntentSender() from pid="
7302                        + Binder.getCallingPid()
7303                        + ", uid=" + Binder.getCallingUid()
7304                        + " is not allowed to cancel packges "
7305                        + rec.key.packageName;
7306                    Slog.w(TAG, msg);
7307                    throw new SecurityException(msg);
7308                }
7309            } catch (RemoteException e) {
7310                throw new SecurityException(e);
7311            }
7312            cancelIntentSenderLocked(rec, true);
7313        }
7314    }
7315
7316    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7317        rec.canceled = true;
7318        mIntentSenderRecords.remove(rec.key);
7319        if (cleanActivity && rec.key.activity != null) {
7320            rec.key.activity.pendingResults.remove(rec.ref);
7321        }
7322    }
7323
7324    @Override
7325    public String getPackageForIntentSender(IIntentSender pendingResult) {
7326        if (!(pendingResult instanceof PendingIntentRecord)) {
7327            return null;
7328        }
7329        try {
7330            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7331            return res.key.packageName;
7332        } catch (ClassCastException e) {
7333        }
7334        return null;
7335    }
7336
7337    @Override
7338    public int getUidForIntentSender(IIntentSender sender) {
7339        if (sender instanceof PendingIntentRecord) {
7340            try {
7341                PendingIntentRecord res = (PendingIntentRecord)sender;
7342                return res.uid;
7343            } catch (ClassCastException e) {
7344            }
7345        }
7346        return -1;
7347    }
7348
7349    @Override
7350    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7351        if (!(pendingResult instanceof PendingIntentRecord)) {
7352            return false;
7353        }
7354        try {
7355            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7356            if (res.key.allIntents == null) {
7357                return false;
7358            }
7359            for (int i=0; i<res.key.allIntents.length; i++) {
7360                Intent intent = res.key.allIntents[i];
7361                if (intent.getPackage() != null && intent.getComponent() != null) {
7362                    return false;
7363                }
7364            }
7365            return true;
7366        } catch (ClassCastException e) {
7367        }
7368        return false;
7369    }
7370
7371    @Override
7372    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7373        if (!(pendingResult instanceof PendingIntentRecord)) {
7374            return false;
7375        }
7376        try {
7377            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7378            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7379                return true;
7380            }
7381            return false;
7382        } catch (ClassCastException e) {
7383        }
7384        return false;
7385    }
7386
7387    @Override
7388    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7389        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7390                "getIntentForIntentSender()");
7391        if (!(pendingResult instanceof PendingIntentRecord)) {
7392            return null;
7393        }
7394        try {
7395            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7396            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7397        } catch (ClassCastException e) {
7398        }
7399        return null;
7400    }
7401
7402    @Override
7403    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7404        if (!(pendingResult instanceof PendingIntentRecord)) {
7405            return null;
7406        }
7407        try {
7408            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7409            synchronized (this) {
7410                return getTagForIntentSenderLocked(res, prefix);
7411            }
7412        } catch (ClassCastException e) {
7413        }
7414        return null;
7415    }
7416
7417    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7418        final Intent intent = res.key.requestIntent;
7419        if (intent != null) {
7420            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7421                    || res.lastTagPrefix.equals(prefix))) {
7422                return res.lastTag;
7423            }
7424            res.lastTagPrefix = prefix;
7425            final StringBuilder sb = new StringBuilder(128);
7426            if (prefix != null) {
7427                sb.append(prefix);
7428            }
7429            if (intent.getAction() != null) {
7430                sb.append(intent.getAction());
7431            } else if (intent.getComponent() != null) {
7432                intent.getComponent().appendShortString(sb);
7433            } else {
7434                sb.append("?");
7435            }
7436            return res.lastTag = sb.toString();
7437        }
7438        return null;
7439    }
7440
7441    @Override
7442    public void setProcessLimit(int max) {
7443        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7444                "setProcessLimit()");
7445        synchronized (this) {
7446            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7447            mProcessLimitOverride = max;
7448        }
7449        trimApplications();
7450    }
7451
7452    @Override
7453    public int getProcessLimit() {
7454        synchronized (this) {
7455            return mProcessLimitOverride;
7456        }
7457    }
7458
7459    void foregroundTokenDied(ForegroundToken token) {
7460        synchronized (ActivityManagerService.this) {
7461            synchronized (mPidsSelfLocked) {
7462                ForegroundToken cur
7463                    = mForegroundProcesses.get(token.pid);
7464                if (cur != token) {
7465                    return;
7466                }
7467                mForegroundProcesses.remove(token.pid);
7468                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7469                if (pr == null) {
7470                    return;
7471                }
7472                pr.forcingToForeground = null;
7473                updateProcessForegroundLocked(pr, false, false);
7474            }
7475            updateOomAdjLocked();
7476        }
7477    }
7478
7479    @Override
7480    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7481        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7482                "setProcessForeground()");
7483        synchronized(this) {
7484            boolean changed = false;
7485
7486            synchronized (mPidsSelfLocked) {
7487                ProcessRecord pr = mPidsSelfLocked.get(pid);
7488                if (pr == null && isForeground) {
7489                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7490                    return;
7491                }
7492                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7493                if (oldToken != null) {
7494                    oldToken.token.unlinkToDeath(oldToken, 0);
7495                    mForegroundProcesses.remove(pid);
7496                    if (pr != null) {
7497                        pr.forcingToForeground = null;
7498                    }
7499                    changed = true;
7500                }
7501                if (isForeground && token != null) {
7502                    ForegroundToken newToken = new ForegroundToken() {
7503                        @Override
7504                        public void binderDied() {
7505                            foregroundTokenDied(this);
7506                        }
7507                    };
7508                    newToken.pid = pid;
7509                    newToken.token = token;
7510                    try {
7511                        token.linkToDeath(newToken, 0);
7512                        mForegroundProcesses.put(pid, newToken);
7513                        pr.forcingToForeground = token;
7514                        changed = true;
7515                    } catch (RemoteException e) {
7516                        // If the process died while doing this, we will later
7517                        // do the cleanup with the process death link.
7518                    }
7519                }
7520            }
7521
7522            if (changed) {
7523                updateOomAdjLocked();
7524            }
7525        }
7526    }
7527
7528    @Override
7529    public boolean isAppForeground(int uid) throws RemoteException {
7530        synchronized (this) {
7531            UidRecord uidRec = mActiveUids.get(uid);
7532            if (uidRec == null || uidRec.idle) {
7533                return false;
7534            }
7535            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7536        }
7537    }
7538
7539    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7540    // be guarded by permission checking.
7541    int getUidState(int uid) {
7542        synchronized (this) {
7543            UidRecord uidRec = mActiveUids.get(uid);
7544            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7545        }
7546    }
7547
7548    @Override
7549    public boolean isInMultiWindowMode(IBinder token) {
7550        final long origId = Binder.clearCallingIdentity();
7551        try {
7552            synchronized(this) {
7553                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7554                if (r == null) {
7555                    return false;
7556                }
7557                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7558                return !r.task.mFullscreen;
7559            }
7560        } finally {
7561            Binder.restoreCallingIdentity(origId);
7562        }
7563    }
7564
7565    @Override
7566    public boolean isInPictureInPictureMode(IBinder token) {
7567        final long origId = Binder.clearCallingIdentity();
7568        try {
7569            synchronized(this) {
7570                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7571                if (stack == null) {
7572                    return false;
7573                }
7574                return stack.mStackId == PINNED_STACK_ID;
7575            }
7576        } finally {
7577            Binder.restoreCallingIdentity(origId);
7578        }
7579    }
7580
7581    @Override
7582    public void enterPictureInPictureMode(IBinder token) {
7583        final long origId = Binder.clearCallingIdentity();
7584        try {
7585            synchronized(this) {
7586                if (!mSupportsPictureInPicture) {
7587                    throw new IllegalStateException("enterPictureInPictureMode: "
7588                            + "Device doesn't support picture-in-picture mode.");
7589                }
7590
7591                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7592
7593                if (r == null) {
7594                    throw new IllegalStateException("enterPictureInPictureMode: "
7595                            + "Can't find activity for token=" + token);
7596                }
7597
7598                if (!r.supportsPictureInPicture()) {
7599                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7600                            + "Picture-In-Picture not supported for r=" + r);
7601                }
7602
7603                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7604                // current bounds.
7605                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7606                final Rect bounds = (pinnedStack != null)
7607                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7608
7609                mStackSupervisor.moveActivityToPinnedStackLocked(
7610                        r, "enterPictureInPictureMode", bounds);
7611            }
7612        } finally {
7613            Binder.restoreCallingIdentity(origId);
7614        }
7615    }
7616
7617    // =========================================================
7618    // PROCESS INFO
7619    // =========================================================
7620
7621    static class ProcessInfoService extends IProcessInfoService.Stub {
7622        final ActivityManagerService mActivityManagerService;
7623        ProcessInfoService(ActivityManagerService activityManagerService) {
7624            mActivityManagerService = activityManagerService;
7625        }
7626
7627        @Override
7628        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7629            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7630                    /*in*/ pids, /*out*/ states, null);
7631        }
7632
7633        @Override
7634        public void getProcessStatesAndOomScoresFromPids(
7635                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7636            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7637                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7638        }
7639    }
7640
7641    /**
7642     * For each PID in the given input array, write the current process state
7643     * for that process into the states array, or -1 to indicate that no
7644     * process with the given PID exists. If scores array is provided, write
7645     * the oom score for the process into the scores array, with INVALID_ADJ
7646     * indicating the PID doesn't exist.
7647     */
7648    public void getProcessStatesAndOomScoresForPIDs(
7649            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7650        if (scores != null) {
7651            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7652                    "getProcessStatesAndOomScoresForPIDs()");
7653        }
7654
7655        if (pids == null) {
7656            throw new NullPointerException("pids");
7657        } else if (states == null) {
7658            throw new NullPointerException("states");
7659        } else if (pids.length != states.length) {
7660            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7661        } else if (scores != null && pids.length != scores.length) {
7662            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7663        }
7664
7665        synchronized (mPidsSelfLocked) {
7666            for (int i = 0; i < pids.length; i++) {
7667                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7668                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7669                        pr.curProcState;
7670                if (scores != null) {
7671                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7672                }
7673            }
7674        }
7675    }
7676
7677    // =========================================================
7678    // PERMISSIONS
7679    // =========================================================
7680
7681    static class PermissionController extends IPermissionController.Stub {
7682        ActivityManagerService mActivityManagerService;
7683        PermissionController(ActivityManagerService activityManagerService) {
7684            mActivityManagerService = activityManagerService;
7685        }
7686
7687        @Override
7688        public boolean checkPermission(String permission, int pid, int uid) {
7689            return mActivityManagerService.checkPermission(permission, pid,
7690                    uid) == PackageManager.PERMISSION_GRANTED;
7691        }
7692
7693        @Override
7694        public String[] getPackagesForUid(int uid) {
7695            return mActivityManagerService.mContext.getPackageManager()
7696                    .getPackagesForUid(uid);
7697        }
7698
7699        @Override
7700        public boolean isRuntimePermission(String permission) {
7701            try {
7702                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7703                        .getPermissionInfo(permission, 0);
7704                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7705            } catch (NameNotFoundException nnfe) {
7706                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7707            }
7708            return false;
7709        }
7710    }
7711
7712    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7713        @Override
7714        public int checkComponentPermission(String permission, int pid, int uid,
7715                int owningUid, boolean exported) {
7716            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7717                    owningUid, exported);
7718        }
7719
7720        @Override
7721        public Object getAMSLock() {
7722            return ActivityManagerService.this;
7723        }
7724    }
7725
7726    /**
7727     * This can be called with or without the global lock held.
7728     */
7729    int checkComponentPermission(String permission, int pid, int uid,
7730            int owningUid, boolean exported) {
7731        if (pid == MY_PID) {
7732            return PackageManager.PERMISSION_GRANTED;
7733        }
7734        return ActivityManager.checkComponentPermission(permission, uid,
7735                owningUid, exported);
7736    }
7737
7738    /**
7739     * As the only public entry point for permissions checking, this method
7740     * can enforce the semantic that requesting a check on a null global
7741     * permission is automatically denied.  (Internally a null permission
7742     * string is used when calling {@link #checkComponentPermission} in cases
7743     * when only uid-based security is needed.)
7744     *
7745     * This can be called with or without the global lock held.
7746     */
7747    @Override
7748    public int checkPermission(String permission, int pid, int uid) {
7749        if (permission == null) {
7750            return PackageManager.PERMISSION_DENIED;
7751        }
7752        return checkComponentPermission(permission, pid, uid, -1, true);
7753    }
7754
7755    @Override
7756    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7757        if (permission == null) {
7758            return PackageManager.PERMISSION_DENIED;
7759        }
7760
7761        // We might be performing an operation on behalf of an indirect binder
7762        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7763        // client identity accordingly before proceeding.
7764        Identity tlsIdentity = sCallerIdentity.get();
7765        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7766            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7767                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7768            uid = tlsIdentity.uid;
7769            pid = tlsIdentity.pid;
7770        }
7771
7772        return checkComponentPermission(permission, pid, uid, -1, true);
7773    }
7774
7775    /**
7776     * Binder IPC calls go through the public entry point.
7777     * This can be called with or without the global lock held.
7778     */
7779    int checkCallingPermission(String permission) {
7780        return checkPermission(permission,
7781                Binder.getCallingPid(),
7782                UserHandle.getAppId(Binder.getCallingUid()));
7783    }
7784
7785    /**
7786     * This can be called with or without the global lock held.
7787     */
7788    void enforceCallingPermission(String permission, String func) {
7789        if (checkCallingPermission(permission)
7790                == PackageManager.PERMISSION_GRANTED) {
7791            return;
7792        }
7793
7794        String msg = "Permission Denial: " + func + " from pid="
7795                + Binder.getCallingPid()
7796                + ", uid=" + Binder.getCallingUid()
7797                + " requires " + permission;
7798        Slog.w(TAG, msg);
7799        throw new SecurityException(msg);
7800    }
7801
7802    /**
7803     * Determine if UID is holding permissions required to access {@link Uri} in
7804     * the given {@link ProviderInfo}. Final permission checking is always done
7805     * in {@link ContentProvider}.
7806     */
7807    private final boolean checkHoldingPermissionsLocked(
7808            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7809        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7810                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7811        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7812            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7813                    != PERMISSION_GRANTED) {
7814                return false;
7815            }
7816        }
7817        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7818    }
7819
7820    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7821            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7822        if (pi.applicationInfo.uid == uid) {
7823            return true;
7824        } else if (!pi.exported) {
7825            return false;
7826        }
7827
7828        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7829        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7830        try {
7831            // check if target holds top-level <provider> permissions
7832            if (!readMet && pi.readPermission != null && considerUidPermissions
7833                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7834                readMet = true;
7835            }
7836            if (!writeMet && pi.writePermission != null && considerUidPermissions
7837                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7838                writeMet = true;
7839            }
7840
7841            // track if unprotected read/write is allowed; any denied
7842            // <path-permission> below removes this ability
7843            boolean allowDefaultRead = pi.readPermission == null;
7844            boolean allowDefaultWrite = pi.writePermission == null;
7845
7846            // check if target holds any <path-permission> that match uri
7847            final PathPermission[] pps = pi.pathPermissions;
7848            if (pps != null) {
7849                final String path = grantUri.uri.getPath();
7850                int i = pps.length;
7851                while (i > 0 && (!readMet || !writeMet)) {
7852                    i--;
7853                    PathPermission pp = pps[i];
7854                    if (pp.match(path)) {
7855                        if (!readMet) {
7856                            final String pprperm = pp.getReadPermission();
7857                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7858                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7859                                    + ": match=" + pp.match(path)
7860                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7861                            if (pprperm != null) {
7862                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7863                                        == PERMISSION_GRANTED) {
7864                                    readMet = true;
7865                                } else {
7866                                    allowDefaultRead = false;
7867                                }
7868                            }
7869                        }
7870                        if (!writeMet) {
7871                            final String ppwperm = pp.getWritePermission();
7872                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7873                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7874                                    + ": match=" + pp.match(path)
7875                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7876                            if (ppwperm != null) {
7877                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7878                                        == PERMISSION_GRANTED) {
7879                                    writeMet = true;
7880                                } else {
7881                                    allowDefaultWrite = false;
7882                                }
7883                            }
7884                        }
7885                    }
7886                }
7887            }
7888
7889            // grant unprotected <provider> read/write, if not blocked by
7890            // <path-permission> above
7891            if (allowDefaultRead) readMet = true;
7892            if (allowDefaultWrite) writeMet = true;
7893
7894        } catch (RemoteException e) {
7895            return false;
7896        }
7897
7898        return readMet && writeMet;
7899    }
7900
7901    public int getAppStartMode(int uid, String packageName) {
7902        synchronized (this) {
7903            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7904        }
7905    }
7906
7907    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7908            boolean allowWhenForeground) {
7909        UidRecord uidRec = mActiveUids.get(uid);
7910        if (!mLenientBackgroundCheck) {
7911            if (!allowWhenForeground || uidRec == null
7912                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7913                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7914                        packageName) != AppOpsManager.MODE_ALLOWED) {
7915                    return ActivityManager.APP_START_MODE_DELAYED;
7916                }
7917            }
7918
7919        } else if (uidRec == null || uidRec.idle) {
7920            if (callingPid >= 0) {
7921                ProcessRecord proc;
7922                synchronized (mPidsSelfLocked) {
7923                    proc = mPidsSelfLocked.get(callingPid);
7924                }
7925                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7926                    // Whoever is instigating this is in the foreground, so we will allow it
7927                    // to go through.
7928                    return ActivityManager.APP_START_MODE_NORMAL;
7929                }
7930            }
7931            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7932                    != AppOpsManager.MODE_ALLOWED) {
7933                return ActivityManager.APP_START_MODE_DELAYED;
7934            }
7935        }
7936        return ActivityManager.APP_START_MODE_NORMAL;
7937    }
7938
7939    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7940        ProviderInfo pi = null;
7941        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7942        if (cpr != null) {
7943            pi = cpr.info;
7944        } else {
7945            try {
7946                pi = AppGlobals.getPackageManager().resolveContentProvider(
7947                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7948                        userHandle);
7949            } catch (RemoteException ex) {
7950            }
7951        }
7952        return pi;
7953    }
7954
7955    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7956        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7957        if (targetUris != null) {
7958            return targetUris.get(grantUri);
7959        }
7960        return null;
7961    }
7962
7963    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7964            String targetPkg, int targetUid, GrantUri grantUri) {
7965        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7966        if (targetUris == null) {
7967            targetUris = Maps.newArrayMap();
7968            mGrantedUriPermissions.put(targetUid, targetUris);
7969        }
7970
7971        UriPermission perm = targetUris.get(grantUri);
7972        if (perm == null) {
7973            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7974            targetUris.put(grantUri, perm);
7975        }
7976
7977        return perm;
7978    }
7979
7980    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7981            final int modeFlags) {
7982        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7983        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7984                : UriPermission.STRENGTH_OWNED;
7985
7986        // Root gets to do everything.
7987        if (uid == 0) {
7988            return true;
7989        }
7990
7991        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7992        if (perms == null) return false;
7993
7994        // First look for exact match
7995        final UriPermission exactPerm = perms.get(grantUri);
7996        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7997            return true;
7998        }
7999
8000        // No exact match, look for prefixes
8001        final int N = perms.size();
8002        for (int i = 0; i < N; i++) {
8003            final UriPermission perm = perms.valueAt(i);
8004            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8005                    && perm.getStrength(modeFlags) >= minStrength) {
8006                return true;
8007            }
8008        }
8009
8010        return false;
8011    }
8012
8013    /**
8014     * @param uri This uri must NOT contain an embedded userId.
8015     * @param userId The userId in which the uri is to be resolved.
8016     */
8017    @Override
8018    public int checkUriPermission(Uri uri, int pid, int uid,
8019            final int modeFlags, int userId, IBinder callerToken) {
8020        enforceNotIsolatedCaller("checkUriPermission");
8021
8022        // Another redirected-binder-call permissions check as in
8023        // {@link checkPermissionWithToken}.
8024        Identity tlsIdentity = sCallerIdentity.get();
8025        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8026            uid = tlsIdentity.uid;
8027            pid = tlsIdentity.pid;
8028        }
8029
8030        // Our own process gets to do everything.
8031        if (pid == MY_PID) {
8032            return PackageManager.PERMISSION_GRANTED;
8033        }
8034        synchronized (this) {
8035            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8036                    ? PackageManager.PERMISSION_GRANTED
8037                    : PackageManager.PERMISSION_DENIED;
8038        }
8039    }
8040
8041    /**
8042     * Check if the targetPkg can be granted permission to access uri by
8043     * the callingUid using the given modeFlags.  Throws a security exception
8044     * if callingUid is not allowed to do this.  Returns the uid of the target
8045     * if the URI permission grant should be performed; returns -1 if it is not
8046     * needed (for example targetPkg already has permission to access the URI).
8047     * If you already know the uid of the target, you can supply it in
8048     * lastTargetUid else set that to -1.
8049     */
8050    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8051            final int modeFlags, int lastTargetUid) {
8052        if (!Intent.isAccessUriMode(modeFlags)) {
8053            return -1;
8054        }
8055
8056        if (targetPkg != null) {
8057            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8058                    "Checking grant " + targetPkg + " permission to " + grantUri);
8059        }
8060
8061        final IPackageManager pm = AppGlobals.getPackageManager();
8062
8063        // If this is not a content: uri, we can't do anything with it.
8064        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8065            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8066                    "Can't grant URI permission for non-content URI: " + grantUri);
8067            return -1;
8068        }
8069
8070        final String authority = grantUri.uri.getAuthority();
8071        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8072                MATCH_DEBUG_TRIAGED_MISSING);
8073        if (pi == null) {
8074            Slog.w(TAG, "No content provider found for permission check: " +
8075                    grantUri.uri.toSafeString());
8076            return -1;
8077        }
8078
8079        int targetUid = lastTargetUid;
8080        if (targetUid < 0 && targetPkg != null) {
8081            try {
8082                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8083                        UserHandle.getUserId(callingUid));
8084                if (targetUid < 0) {
8085                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8086                            "Can't grant URI permission no uid for: " + targetPkg);
8087                    return -1;
8088                }
8089            } catch (RemoteException ex) {
8090                return -1;
8091            }
8092        }
8093
8094        if (targetUid >= 0) {
8095            // First...  does the target actually need this permission?
8096            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8097                // No need to grant the target this permission.
8098                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8099                        "Target " + targetPkg + " already has full permission to " + grantUri);
8100                return -1;
8101            }
8102        } else {
8103            // First...  there is no target package, so can anyone access it?
8104            boolean allowed = pi.exported;
8105            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8106                if (pi.readPermission != null) {
8107                    allowed = false;
8108                }
8109            }
8110            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8111                if (pi.writePermission != null) {
8112                    allowed = false;
8113                }
8114            }
8115            if (allowed) {
8116                return -1;
8117            }
8118        }
8119
8120        /* There is a special cross user grant if:
8121         * - The target is on another user.
8122         * - Apps on the current user can access the uri without any uid permissions.
8123         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8124         * grant uri permissions.
8125         */
8126        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8127                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8128                modeFlags, false /*without considering the uid permissions*/);
8129
8130        // Second...  is the provider allowing granting of URI permissions?
8131        if (!specialCrossUserGrant) {
8132            if (!pi.grantUriPermissions) {
8133                throw new SecurityException("Provider " + pi.packageName
8134                        + "/" + pi.name
8135                        + " does not allow granting of Uri permissions (uri "
8136                        + grantUri + ")");
8137            }
8138            if (pi.uriPermissionPatterns != null) {
8139                final int N = pi.uriPermissionPatterns.length;
8140                boolean allowed = false;
8141                for (int i=0; i<N; i++) {
8142                    if (pi.uriPermissionPatterns[i] != null
8143                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8144                        allowed = true;
8145                        break;
8146                    }
8147                }
8148                if (!allowed) {
8149                    throw new SecurityException("Provider " + pi.packageName
8150                            + "/" + pi.name
8151                            + " does not allow granting of permission to path of Uri "
8152                            + grantUri);
8153                }
8154            }
8155        }
8156
8157        // Third...  does the caller itself have permission to access
8158        // this uri?
8159        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8160            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8161                // Require they hold a strong enough Uri permission
8162                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8163                    throw new SecurityException("Uid " + callingUid
8164                            + " does not have permission to uri " + grantUri);
8165                }
8166            }
8167        }
8168        return targetUid;
8169    }
8170
8171    /**
8172     * @param uri This uri must NOT contain an embedded userId.
8173     * @param userId The userId in which the uri is to be resolved.
8174     */
8175    @Override
8176    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8177            final int modeFlags, int userId) {
8178        enforceNotIsolatedCaller("checkGrantUriPermission");
8179        synchronized(this) {
8180            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8181                    new GrantUri(userId, uri, false), modeFlags, -1);
8182        }
8183    }
8184
8185    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8186            final int modeFlags, UriPermissionOwner owner) {
8187        if (!Intent.isAccessUriMode(modeFlags)) {
8188            return;
8189        }
8190
8191        // So here we are: the caller has the assumed permission
8192        // to the uri, and the target doesn't.  Let's now give this to
8193        // the target.
8194
8195        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8196                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8197
8198        final String authority = grantUri.uri.getAuthority();
8199        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8200                MATCH_DEBUG_TRIAGED_MISSING);
8201        if (pi == null) {
8202            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8203            return;
8204        }
8205
8206        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8207            grantUri.prefix = true;
8208        }
8209        final UriPermission perm = findOrCreateUriPermissionLocked(
8210                pi.packageName, targetPkg, targetUid, grantUri);
8211        perm.grantModes(modeFlags, owner);
8212    }
8213
8214    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8215            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8216        if (targetPkg == null) {
8217            throw new NullPointerException("targetPkg");
8218        }
8219        int targetUid;
8220        final IPackageManager pm = AppGlobals.getPackageManager();
8221        try {
8222            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8223        } catch (RemoteException ex) {
8224            return;
8225        }
8226
8227        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8228                targetUid);
8229        if (targetUid < 0) {
8230            return;
8231        }
8232
8233        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8234                owner);
8235    }
8236
8237    static class NeededUriGrants extends ArrayList<GrantUri> {
8238        final String targetPkg;
8239        final int targetUid;
8240        final int flags;
8241
8242        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8243            this.targetPkg = targetPkg;
8244            this.targetUid = targetUid;
8245            this.flags = flags;
8246        }
8247    }
8248
8249    /**
8250     * Like checkGrantUriPermissionLocked, but takes an Intent.
8251     */
8252    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8253            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8254        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8255                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8256                + " clip=" + (intent != null ? intent.getClipData() : null)
8257                + " from " + intent + "; flags=0x"
8258                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8259
8260        if (targetPkg == null) {
8261            throw new NullPointerException("targetPkg");
8262        }
8263
8264        if (intent == null) {
8265            return null;
8266        }
8267        Uri data = intent.getData();
8268        ClipData clip = intent.getClipData();
8269        if (data == null && clip == null) {
8270            return null;
8271        }
8272        // Default userId for uris in the intent (if they don't specify it themselves)
8273        int contentUserHint = intent.getContentUserHint();
8274        if (contentUserHint == UserHandle.USER_CURRENT) {
8275            contentUserHint = UserHandle.getUserId(callingUid);
8276        }
8277        final IPackageManager pm = AppGlobals.getPackageManager();
8278        int targetUid;
8279        if (needed != null) {
8280            targetUid = needed.targetUid;
8281        } else {
8282            try {
8283                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8284                        targetUserId);
8285            } catch (RemoteException ex) {
8286                return null;
8287            }
8288            if (targetUid < 0) {
8289                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8290                        "Can't grant URI permission no uid for: " + targetPkg
8291                        + " on user " + targetUserId);
8292                return null;
8293            }
8294        }
8295        if (data != null) {
8296            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8297            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8298                    targetUid);
8299            if (targetUid > 0) {
8300                if (needed == null) {
8301                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8302                }
8303                needed.add(grantUri);
8304            }
8305        }
8306        if (clip != null) {
8307            for (int i=0; i<clip.getItemCount(); i++) {
8308                Uri uri = clip.getItemAt(i).getUri();
8309                if (uri != null) {
8310                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8311                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8312                            targetUid);
8313                    if (targetUid > 0) {
8314                        if (needed == null) {
8315                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8316                        }
8317                        needed.add(grantUri);
8318                    }
8319                } else {
8320                    Intent clipIntent = clip.getItemAt(i).getIntent();
8321                    if (clipIntent != null) {
8322                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8323                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8324                        if (newNeeded != null) {
8325                            needed = newNeeded;
8326                        }
8327                    }
8328                }
8329            }
8330        }
8331
8332        return needed;
8333    }
8334
8335    /**
8336     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8337     */
8338    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8339            UriPermissionOwner owner) {
8340        if (needed != null) {
8341            for (int i=0; i<needed.size(); i++) {
8342                GrantUri grantUri = needed.get(i);
8343                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8344                        grantUri, needed.flags, owner);
8345            }
8346        }
8347    }
8348
8349    void grantUriPermissionFromIntentLocked(int callingUid,
8350            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8351        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8352                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8353        if (needed == null) {
8354            return;
8355        }
8356
8357        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8358    }
8359
8360    /**
8361     * @param uri This uri must NOT contain an embedded userId.
8362     * @param userId The userId in which the uri is to be resolved.
8363     */
8364    @Override
8365    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8366            final int modeFlags, int userId) {
8367        enforceNotIsolatedCaller("grantUriPermission");
8368        GrantUri grantUri = new GrantUri(userId, uri, false);
8369        synchronized(this) {
8370            final ProcessRecord r = getRecordForAppLocked(caller);
8371            if (r == null) {
8372                throw new SecurityException("Unable to find app for caller "
8373                        + caller
8374                        + " when granting permission to uri " + grantUri);
8375            }
8376            if (targetPkg == null) {
8377                throw new IllegalArgumentException("null target");
8378            }
8379            if (grantUri == null) {
8380                throw new IllegalArgumentException("null uri");
8381            }
8382
8383            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8384                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8385                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8386                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8387
8388            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8389                    UserHandle.getUserId(r.uid));
8390        }
8391    }
8392
8393    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8394        if (perm.modeFlags == 0) {
8395            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8396                    perm.targetUid);
8397            if (perms != null) {
8398                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8399                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8400
8401                perms.remove(perm.uri);
8402                if (perms.isEmpty()) {
8403                    mGrantedUriPermissions.remove(perm.targetUid);
8404                }
8405            }
8406        }
8407    }
8408
8409    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8410        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8411                "Revoking all granted permissions to " + grantUri);
8412
8413        final IPackageManager pm = AppGlobals.getPackageManager();
8414        final String authority = grantUri.uri.getAuthority();
8415        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8416                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8417        if (pi == null) {
8418            Slog.w(TAG, "No content provider found for permission revoke: "
8419                    + grantUri.toSafeString());
8420            return;
8421        }
8422
8423        // Does the caller have this permission on the URI?
8424        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8425            // If they don't have direct access to the URI, then revoke any
8426            // ownerless URI permissions that have been granted to them.
8427            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8428            if (perms != null) {
8429                boolean persistChanged = false;
8430                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8431                    final UriPermission perm = it.next();
8432                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8433                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8434                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8435                                "Revoking non-owned " + perm.targetUid
8436                                + " permission to " + perm.uri);
8437                        persistChanged |= perm.revokeModes(
8438                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8439                        if (perm.modeFlags == 0) {
8440                            it.remove();
8441                        }
8442                    }
8443                }
8444                if (perms.isEmpty()) {
8445                    mGrantedUriPermissions.remove(callingUid);
8446                }
8447                if (persistChanged) {
8448                    schedulePersistUriGrants();
8449                }
8450            }
8451            return;
8452        }
8453
8454        boolean persistChanged = false;
8455
8456        // Go through all of the permissions and remove any that match.
8457        int N = mGrantedUriPermissions.size();
8458        for (int i = 0; i < N; i++) {
8459            final int targetUid = mGrantedUriPermissions.keyAt(i);
8460            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8461
8462            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8463                final UriPermission perm = it.next();
8464                if (perm.uri.sourceUserId == grantUri.sourceUserId
8465                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8466                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8467                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8468                    persistChanged |= perm.revokeModes(
8469                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8470                    if (perm.modeFlags == 0) {
8471                        it.remove();
8472                    }
8473                }
8474            }
8475
8476            if (perms.isEmpty()) {
8477                mGrantedUriPermissions.remove(targetUid);
8478                N--;
8479                i--;
8480            }
8481        }
8482
8483        if (persistChanged) {
8484            schedulePersistUriGrants();
8485        }
8486    }
8487
8488    /**
8489     * @param uri This uri must NOT contain an embedded userId.
8490     * @param userId The userId in which the uri is to be resolved.
8491     */
8492    @Override
8493    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8494            int userId) {
8495        enforceNotIsolatedCaller("revokeUriPermission");
8496        synchronized(this) {
8497            final ProcessRecord r = getRecordForAppLocked(caller);
8498            if (r == null) {
8499                throw new SecurityException("Unable to find app for caller "
8500                        + caller
8501                        + " when revoking permission to uri " + uri);
8502            }
8503            if (uri == null) {
8504                Slog.w(TAG, "revokeUriPermission: null uri");
8505                return;
8506            }
8507
8508            if (!Intent.isAccessUriMode(modeFlags)) {
8509                return;
8510            }
8511
8512            final String authority = uri.getAuthority();
8513            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8514                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8515            if (pi == null) {
8516                Slog.w(TAG, "No content provider found for permission revoke: "
8517                        + uri.toSafeString());
8518                return;
8519            }
8520
8521            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8522        }
8523    }
8524
8525    /**
8526     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8527     * given package.
8528     *
8529     * @param packageName Package name to match, or {@code null} to apply to all
8530     *            packages.
8531     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8532     *            to all users.
8533     * @param persistable If persistable grants should be removed.
8534     */
8535    private void removeUriPermissionsForPackageLocked(
8536            String packageName, int userHandle, boolean persistable) {
8537        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8538            throw new IllegalArgumentException("Must narrow by either package or user");
8539        }
8540
8541        boolean persistChanged = false;
8542
8543        int N = mGrantedUriPermissions.size();
8544        for (int i = 0; i < N; i++) {
8545            final int targetUid = mGrantedUriPermissions.keyAt(i);
8546            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8547
8548            // Only inspect grants matching user
8549            if (userHandle == UserHandle.USER_ALL
8550                    || userHandle == UserHandle.getUserId(targetUid)) {
8551                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8552                    final UriPermission perm = it.next();
8553
8554                    // Only inspect grants matching package
8555                    if (packageName == null || perm.sourcePkg.equals(packageName)
8556                            || perm.targetPkg.equals(packageName)) {
8557                        persistChanged |= perm.revokeModes(persistable
8558                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8559
8560                        // Only remove when no modes remain; any persisted grants
8561                        // will keep this alive.
8562                        if (perm.modeFlags == 0) {
8563                            it.remove();
8564                        }
8565                    }
8566                }
8567
8568                if (perms.isEmpty()) {
8569                    mGrantedUriPermissions.remove(targetUid);
8570                    N--;
8571                    i--;
8572                }
8573            }
8574        }
8575
8576        if (persistChanged) {
8577            schedulePersistUriGrants();
8578        }
8579    }
8580
8581    @Override
8582    public IBinder newUriPermissionOwner(String name) {
8583        enforceNotIsolatedCaller("newUriPermissionOwner");
8584        synchronized(this) {
8585            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8586            return owner.getExternalTokenLocked();
8587        }
8588    }
8589
8590    @Override
8591    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8592        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8593        synchronized(this) {
8594            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8595            if (r == null) {
8596                throw new IllegalArgumentException("Activity does not exist; token="
8597                        + activityToken);
8598            }
8599            return r.getUriPermissionsLocked().getExternalTokenLocked();
8600        }
8601    }
8602    /**
8603     * @param uri This uri must NOT contain an embedded userId.
8604     * @param sourceUserId The userId in which the uri is to be resolved.
8605     * @param targetUserId The userId of the app that receives the grant.
8606     */
8607    @Override
8608    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8609            final int modeFlags, int sourceUserId, int targetUserId) {
8610        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8611                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8612                "grantUriPermissionFromOwner", null);
8613        synchronized(this) {
8614            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8615            if (owner == null) {
8616                throw new IllegalArgumentException("Unknown owner: " + token);
8617            }
8618            if (fromUid != Binder.getCallingUid()) {
8619                if (Binder.getCallingUid() != Process.myUid()) {
8620                    // Only system code can grant URI permissions on behalf
8621                    // of other users.
8622                    throw new SecurityException("nice try");
8623                }
8624            }
8625            if (targetPkg == null) {
8626                throw new IllegalArgumentException("null target");
8627            }
8628            if (uri == null) {
8629                throw new IllegalArgumentException("null uri");
8630            }
8631
8632            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8633                    modeFlags, owner, targetUserId);
8634        }
8635    }
8636
8637    /**
8638     * @param uri This uri must NOT contain an embedded userId.
8639     * @param userId The userId in which the uri is to be resolved.
8640     */
8641    @Override
8642    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8643        synchronized(this) {
8644            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8645            if (owner == null) {
8646                throw new IllegalArgumentException("Unknown owner: " + token);
8647            }
8648
8649            if (uri == null) {
8650                owner.removeUriPermissionsLocked(mode);
8651            } else {
8652                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8653                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8654            }
8655        }
8656    }
8657
8658    private void schedulePersistUriGrants() {
8659        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8660            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8661                    10 * DateUtils.SECOND_IN_MILLIS);
8662        }
8663    }
8664
8665    private void writeGrantedUriPermissions() {
8666        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8667
8668        // Snapshot permissions so we can persist without lock
8669        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8670        synchronized (this) {
8671            final int size = mGrantedUriPermissions.size();
8672            for (int i = 0; i < size; i++) {
8673                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8674                for (UriPermission perm : perms.values()) {
8675                    if (perm.persistedModeFlags != 0) {
8676                        persist.add(perm.snapshot());
8677                    }
8678                }
8679            }
8680        }
8681
8682        FileOutputStream fos = null;
8683        try {
8684            fos = mGrantFile.startWrite();
8685
8686            XmlSerializer out = new FastXmlSerializer();
8687            out.setOutput(fos, StandardCharsets.UTF_8.name());
8688            out.startDocument(null, true);
8689            out.startTag(null, TAG_URI_GRANTS);
8690            for (UriPermission.Snapshot perm : persist) {
8691                out.startTag(null, TAG_URI_GRANT);
8692                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8693                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8694                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8695                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8696                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8697                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8698                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8699                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8700                out.endTag(null, TAG_URI_GRANT);
8701            }
8702            out.endTag(null, TAG_URI_GRANTS);
8703            out.endDocument();
8704
8705            mGrantFile.finishWrite(fos);
8706        } catch (IOException e) {
8707            if (fos != null) {
8708                mGrantFile.failWrite(fos);
8709            }
8710        }
8711    }
8712
8713    private void readGrantedUriPermissionsLocked() {
8714        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8715
8716        final long now = System.currentTimeMillis();
8717
8718        FileInputStream fis = null;
8719        try {
8720            fis = mGrantFile.openRead();
8721            final XmlPullParser in = Xml.newPullParser();
8722            in.setInput(fis, StandardCharsets.UTF_8.name());
8723
8724            int type;
8725            while ((type = in.next()) != END_DOCUMENT) {
8726                final String tag = in.getName();
8727                if (type == START_TAG) {
8728                    if (TAG_URI_GRANT.equals(tag)) {
8729                        final int sourceUserId;
8730                        final int targetUserId;
8731                        final int userHandle = readIntAttribute(in,
8732                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8733                        if (userHandle != UserHandle.USER_NULL) {
8734                            // For backwards compatibility.
8735                            sourceUserId = userHandle;
8736                            targetUserId = userHandle;
8737                        } else {
8738                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8739                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8740                        }
8741                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8742                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8743                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8744                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8745                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8746                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8747
8748                        // Sanity check that provider still belongs to source package
8749                        // Both direct boot aware and unaware packages are fine as we
8750                        // will do filtering at query time to avoid multiple parsing.
8751                        final ProviderInfo pi = getProviderInfoLocked(
8752                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8753                                        | MATCH_DIRECT_BOOT_UNAWARE);
8754                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8755                            int targetUid = -1;
8756                            try {
8757                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8758                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8759                            } catch (RemoteException e) {
8760                            }
8761                            if (targetUid != -1) {
8762                                final UriPermission perm = findOrCreateUriPermissionLocked(
8763                                        sourcePkg, targetPkg, targetUid,
8764                                        new GrantUri(sourceUserId, uri, prefix));
8765                                perm.initPersistedModes(modeFlags, createdTime);
8766                            }
8767                        } else {
8768                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8769                                    + " but instead found " + pi);
8770                        }
8771                    }
8772                }
8773            }
8774        } catch (FileNotFoundException e) {
8775            // Missing grants is okay
8776        } catch (IOException e) {
8777            Slog.wtf(TAG, "Failed reading Uri grants", e);
8778        } catch (XmlPullParserException e) {
8779            Slog.wtf(TAG, "Failed reading Uri grants", e);
8780        } finally {
8781            IoUtils.closeQuietly(fis);
8782        }
8783    }
8784
8785    /**
8786     * @param uri This uri must NOT contain an embedded userId.
8787     * @param userId The userId in which the uri is to be resolved.
8788     */
8789    @Override
8790    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8791        enforceNotIsolatedCaller("takePersistableUriPermission");
8792
8793        Preconditions.checkFlagsArgument(modeFlags,
8794                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8795
8796        synchronized (this) {
8797            final int callingUid = Binder.getCallingUid();
8798            boolean persistChanged = false;
8799            GrantUri grantUri = new GrantUri(userId, uri, false);
8800
8801            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8802                    new GrantUri(userId, uri, false));
8803            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8804                    new GrantUri(userId, uri, true));
8805
8806            final boolean exactValid = (exactPerm != null)
8807                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8808            final boolean prefixValid = (prefixPerm != null)
8809                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8810
8811            if (!(exactValid || prefixValid)) {
8812                throw new SecurityException("No persistable permission grants found for UID "
8813                        + callingUid + " and Uri " + grantUri.toSafeString());
8814            }
8815
8816            if (exactValid) {
8817                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8818            }
8819            if (prefixValid) {
8820                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8821            }
8822
8823            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8824
8825            if (persistChanged) {
8826                schedulePersistUriGrants();
8827            }
8828        }
8829    }
8830
8831    /**
8832     * @param uri This uri must NOT contain an embedded userId.
8833     * @param userId The userId in which the uri is to be resolved.
8834     */
8835    @Override
8836    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8837        enforceNotIsolatedCaller("releasePersistableUriPermission");
8838
8839        Preconditions.checkFlagsArgument(modeFlags,
8840                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8841
8842        synchronized (this) {
8843            final int callingUid = Binder.getCallingUid();
8844            boolean persistChanged = false;
8845
8846            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8847                    new GrantUri(userId, uri, false));
8848            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8849                    new GrantUri(userId, uri, true));
8850            if (exactPerm == null && prefixPerm == null) {
8851                throw new SecurityException("No permission grants found for UID " + callingUid
8852                        + " and Uri " + uri.toSafeString());
8853            }
8854
8855            if (exactPerm != null) {
8856                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8857                removeUriPermissionIfNeededLocked(exactPerm);
8858            }
8859            if (prefixPerm != null) {
8860                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8861                removeUriPermissionIfNeededLocked(prefixPerm);
8862            }
8863
8864            if (persistChanged) {
8865                schedulePersistUriGrants();
8866            }
8867        }
8868    }
8869
8870    /**
8871     * Prune any older {@link UriPermission} for the given UID until outstanding
8872     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8873     *
8874     * @return if any mutations occured that require persisting.
8875     */
8876    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8877        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8878        if (perms == null) return false;
8879        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8880
8881        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8882        for (UriPermission perm : perms.values()) {
8883            if (perm.persistedModeFlags != 0) {
8884                persisted.add(perm);
8885            }
8886        }
8887
8888        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8889        if (trimCount <= 0) return false;
8890
8891        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8892        for (int i = 0; i < trimCount; i++) {
8893            final UriPermission perm = persisted.get(i);
8894
8895            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8896                    "Trimming grant created at " + perm.persistedCreateTime);
8897
8898            perm.releasePersistableModes(~0);
8899            removeUriPermissionIfNeededLocked(perm);
8900        }
8901
8902        return true;
8903    }
8904
8905    @Override
8906    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8907            String packageName, boolean incoming) {
8908        enforceNotIsolatedCaller("getPersistedUriPermissions");
8909        Preconditions.checkNotNull(packageName, "packageName");
8910
8911        final int callingUid = Binder.getCallingUid();
8912        final int callingUserId = UserHandle.getUserId(callingUid);
8913        final IPackageManager pm = AppGlobals.getPackageManager();
8914        try {
8915            final int packageUid = pm.getPackageUid(packageName,
8916                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8917            if (packageUid != callingUid) {
8918                throw new SecurityException(
8919                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8920            }
8921        } catch (RemoteException e) {
8922            throw new SecurityException("Failed to verify package name ownership");
8923        }
8924
8925        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8926        synchronized (this) {
8927            if (incoming) {
8928                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8929                        callingUid);
8930                if (perms == null) {
8931                    Slog.w(TAG, "No permission grants found for " + packageName);
8932                } else {
8933                    for (UriPermission perm : perms.values()) {
8934                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8935                            result.add(perm.buildPersistedPublicApiObject());
8936                        }
8937                    }
8938                }
8939            } else {
8940                final int size = mGrantedUriPermissions.size();
8941                for (int i = 0; i < size; i++) {
8942                    final ArrayMap<GrantUri, UriPermission> perms =
8943                            mGrantedUriPermissions.valueAt(i);
8944                    for (UriPermission perm : perms.values()) {
8945                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8946                            result.add(perm.buildPersistedPublicApiObject());
8947                        }
8948                    }
8949                }
8950            }
8951        }
8952        return new ParceledListSlice<android.content.UriPermission>(result);
8953    }
8954
8955    @Override
8956    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8957            String packageName, int userId) {
8958        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8959                "getGrantedUriPermissions");
8960
8961        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8962        synchronized (this) {
8963            final int size = mGrantedUriPermissions.size();
8964            for (int i = 0; i < size; i++) {
8965                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8966                for (UriPermission perm : perms.values()) {
8967                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8968                            && perm.persistedModeFlags != 0) {
8969                        result.add(perm.buildPersistedPublicApiObject());
8970                    }
8971                }
8972            }
8973        }
8974        return new ParceledListSlice<android.content.UriPermission>(result);
8975    }
8976
8977    @Override
8978    public void clearGrantedUriPermissions(String packageName, int userId) {
8979        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8980                "clearGrantedUriPermissions");
8981        removeUriPermissionsForPackageLocked(packageName, userId, true);
8982    }
8983
8984    @Override
8985    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8986        synchronized (this) {
8987            ProcessRecord app =
8988                who != null ? getRecordForAppLocked(who) : null;
8989            if (app == null) return;
8990
8991            Message msg = Message.obtain();
8992            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8993            msg.obj = app;
8994            msg.arg1 = waiting ? 1 : 0;
8995            mUiHandler.sendMessage(msg);
8996        }
8997    }
8998
8999    @Override
9000    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9001        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9002        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9003        outInfo.availMem = Process.getFreeMemory();
9004        outInfo.totalMem = Process.getTotalMemory();
9005        outInfo.threshold = homeAppMem;
9006        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9007        outInfo.hiddenAppThreshold = cachedAppMem;
9008        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9009                ProcessList.SERVICE_ADJ);
9010        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9011                ProcessList.VISIBLE_APP_ADJ);
9012        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9013                ProcessList.FOREGROUND_APP_ADJ);
9014    }
9015
9016    // =========================================================
9017    // TASK MANAGEMENT
9018    // =========================================================
9019
9020    @Override
9021    public List<IAppTask> getAppTasks(String callingPackage) {
9022        int callingUid = Binder.getCallingUid();
9023        long ident = Binder.clearCallingIdentity();
9024
9025        synchronized(this) {
9026            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9027            try {
9028                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9029
9030                final int N = mRecentTasks.size();
9031                for (int i = 0; i < N; i++) {
9032                    TaskRecord tr = mRecentTasks.get(i);
9033                    // Skip tasks that do not match the caller.  We don't need to verify
9034                    // callingPackage, because we are also limiting to callingUid and know
9035                    // that will limit to the correct security sandbox.
9036                    if (tr.effectiveUid != callingUid) {
9037                        continue;
9038                    }
9039                    Intent intent = tr.getBaseIntent();
9040                    if (intent == null ||
9041                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9042                        continue;
9043                    }
9044                    ActivityManager.RecentTaskInfo taskInfo =
9045                            createRecentTaskInfoFromTaskRecord(tr);
9046                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9047                    list.add(taskImpl);
9048                }
9049            } finally {
9050                Binder.restoreCallingIdentity(ident);
9051            }
9052            return list;
9053        }
9054    }
9055
9056    @Override
9057    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9058        final int callingUid = Binder.getCallingUid();
9059        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9060
9061        synchronized(this) {
9062            if (DEBUG_ALL) Slog.v(
9063                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9064
9065            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9066                    callingUid);
9067
9068            // TODO: Improve with MRU list from all ActivityStacks.
9069            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9070        }
9071
9072        return list;
9073    }
9074
9075    /**
9076     * Creates a new RecentTaskInfo from a TaskRecord.
9077     */
9078    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9079        // Update the task description to reflect any changes in the task stack
9080        tr.updateTaskDescription();
9081
9082        // Compose the recent task info
9083        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9084        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9085        rti.persistentId = tr.taskId;
9086        rti.baseIntent = new Intent(tr.getBaseIntent());
9087        rti.origActivity = tr.origActivity;
9088        rti.realActivity = tr.realActivity;
9089        rti.description = tr.lastDescription;
9090        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9091        rti.userId = tr.userId;
9092        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9093        rti.firstActiveTime = tr.firstActiveTime;
9094        rti.lastActiveTime = tr.lastActiveTime;
9095        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9096        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9097        rti.numActivities = 0;
9098        if (tr.mBounds != null) {
9099            rti.bounds = new Rect(tr.mBounds);
9100        }
9101        rti.isDockable = tr.canGoInDockedStack();
9102        rti.resizeMode = tr.mResizeMode;
9103
9104        ActivityRecord base = null;
9105        ActivityRecord top = null;
9106        ActivityRecord tmp;
9107
9108        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9109            tmp = tr.mActivities.get(i);
9110            if (tmp.finishing) {
9111                continue;
9112            }
9113            base = tmp;
9114            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9115                top = base;
9116            }
9117            rti.numActivities++;
9118        }
9119
9120        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9121        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9122
9123        return rti;
9124    }
9125
9126    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9127        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9128                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9129        if (!allowed) {
9130            if (checkPermission(android.Manifest.permission.GET_TASKS,
9131                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9132                // Temporary compatibility: some existing apps on the system image may
9133                // still be requesting the old permission and not switched to the new
9134                // one; if so, we'll still allow them full access.  This means we need
9135                // to see if they are holding the old permission and are a system app.
9136                try {
9137                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9138                        allowed = true;
9139                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9140                                + " is using old GET_TASKS but privileged; allowing");
9141                    }
9142                } catch (RemoteException e) {
9143                }
9144            }
9145        }
9146        if (!allowed) {
9147            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9148                    + " does not hold REAL_GET_TASKS; limiting output");
9149        }
9150        return allowed;
9151    }
9152
9153    @Override
9154    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9155            int userId) {
9156        final int callingUid = Binder.getCallingUid();
9157        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9158                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9159
9160        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9161        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9162        synchronized (this) {
9163            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9164                    callingUid);
9165            final boolean detailed = checkCallingPermission(
9166                    android.Manifest.permission.GET_DETAILED_TASKS)
9167                    == PackageManager.PERMISSION_GRANTED;
9168
9169            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9170                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9171                return ParceledListSlice.emptyList();
9172            }
9173            mRecentTasks.loadUserRecentsLocked(userId);
9174
9175            final int recentsCount = mRecentTasks.size();
9176            ArrayList<ActivityManager.RecentTaskInfo> res =
9177                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9178
9179            final Set<Integer> includedUsers;
9180            if (includeProfiles) {
9181                includedUsers = mUserController.getProfileIds(userId);
9182            } else {
9183                includedUsers = new HashSet<>();
9184            }
9185            includedUsers.add(Integer.valueOf(userId));
9186
9187            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9188                TaskRecord tr = mRecentTasks.get(i);
9189                // Only add calling user or related users recent tasks
9190                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9191                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9192                    continue;
9193                }
9194
9195                if (tr.realActivitySuspended) {
9196                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9197                    continue;
9198                }
9199
9200                // Return the entry if desired by the caller.  We always return
9201                // the first entry, because callers always expect this to be the
9202                // foreground app.  We may filter others if the caller has
9203                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9204                // we should exclude the entry.
9205
9206                if (i == 0
9207                        || withExcluded
9208                        || (tr.intent == null)
9209                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9210                                == 0)) {
9211                    if (!allowed) {
9212                        // If the caller doesn't have the GET_TASKS permission, then only
9213                        // allow them to see a small subset of tasks -- their own and home.
9214                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9215                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9216                            continue;
9217                        }
9218                    }
9219                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9220                        if (tr.stack != null && tr.stack.isHomeStack()) {
9221                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9222                                    "Skipping, home stack task: " + tr);
9223                            continue;
9224                        }
9225                    }
9226                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9227                        final ActivityStack stack = tr.stack;
9228                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9229                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9230                                    "Skipping, top task in docked stack: " + tr);
9231                            continue;
9232                        }
9233                    }
9234                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9235                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9236                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9237                                    "Skipping, pinned stack task: " + tr);
9238                            continue;
9239                        }
9240                    }
9241                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9242                        // Don't include auto remove tasks that are finished or finishing.
9243                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9244                                "Skipping, auto-remove without activity: " + tr);
9245                        continue;
9246                    }
9247                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9248                            && !tr.isAvailable) {
9249                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9250                                "Skipping, unavail real act: " + tr);
9251                        continue;
9252                    }
9253
9254                    if (!tr.mUserSetupComplete) {
9255                        // Don't include task launched while user is not done setting-up.
9256                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9257                                "Skipping, user setup not complete: " + tr);
9258                        continue;
9259                    }
9260
9261                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9262                    if (!detailed) {
9263                        rti.baseIntent.replaceExtras((Bundle)null);
9264                    }
9265
9266                    res.add(rti);
9267                    maxNum--;
9268                }
9269            }
9270            return new ParceledListSlice<>(res);
9271        }
9272    }
9273
9274    @Override
9275    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9276        synchronized (this) {
9277            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9278                    "getTaskThumbnail()");
9279            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9280                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9281            if (tr != null) {
9282                return tr.getTaskThumbnailLocked();
9283            }
9284        }
9285        return null;
9286    }
9287
9288    @Override
9289    public int addAppTask(IBinder activityToken, Intent intent,
9290            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9291        final int callingUid = Binder.getCallingUid();
9292        final long callingIdent = Binder.clearCallingIdentity();
9293
9294        try {
9295            synchronized (this) {
9296                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9297                if (r == null) {
9298                    throw new IllegalArgumentException("Activity does not exist; token="
9299                            + activityToken);
9300                }
9301                ComponentName comp = intent.getComponent();
9302                if (comp == null) {
9303                    throw new IllegalArgumentException("Intent " + intent
9304                            + " must specify explicit component");
9305                }
9306                if (thumbnail.getWidth() != mThumbnailWidth
9307                        || thumbnail.getHeight() != mThumbnailHeight) {
9308                    throw new IllegalArgumentException("Bad thumbnail size: got "
9309                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9310                            + mThumbnailWidth + "x" + mThumbnailHeight);
9311                }
9312                if (intent.getSelector() != null) {
9313                    intent.setSelector(null);
9314                }
9315                if (intent.getSourceBounds() != null) {
9316                    intent.setSourceBounds(null);
9317                }
9318                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9319                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9320                        // The caller has added this as an auto-remove task...  that makes no
9321                        // sense, so turn off auto-remove.
9322                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9323                    }
9324                }
9325                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9326                    mLastAddedTaskActivity = null;
9327                }
9328                ActivityInfo ainfo = mLastAddedTaskActivity;
9329                if (ainfo == null) {
9330                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9331                            comp, 0, UserHandle.getUserId(callingUid));
9332                    if (ainfo.applicationInfo.uid != callingUid) {
9333                        throw new SecurityException(
9334                                "Can't add task for another application: target uid="
9335                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9336                    }
9337                }
9338
9339                // Use the full screen as the context for the task thumbnail
9340                final Point displaySize = new Point();
9341                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9342                r.task.stack.getDisplaySize(displaySize);
9343                thumbnailInfo.taskWidth = displaySize.x;
9344                thumbnailInfo.taskHeight = displaySize.y;
9345                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9346
9347                TaskRecord task = new TaskRecord(this,
9348                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9349                        ainfo, intent, description, thumbnailInfo);
9350
9351                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9352                if (trimIdx >= 0) {
9353                    // If this would have caused a trim, then we'll abort because that
9354                    // means it would be added at the end of the list but then just removed.
9355                    return INVALID_TASK_ID;
9356                }
9357
9358                final int N = mRecentTasks.size();
9359                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9360                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9361                    tr.removedFromRecents();
9362                }
9363
9364                task.inRecents = true;
9365                mRecentTasks.add(task);
9366                r.task.stack.addTask(task, false, "addAppTask");
9367
9368                task.setLastThumbnailLocked(thumbnail);
9369                task.freeLastThumbnail();
9370
9371                return task.taskId;
9372            }
9373        } finally {
9374            Binder.restoreCallingIdentity(callingIdent);
9375        }
9376    }
9377
9378    @Override
9379    public Point getAppTaskThumbnailSize() {
9380        synchronized (this) {
9381            return new Point(mThumbnailWidth,  mThumbnailHeight);
9382        }
9383    }
9384
9385    @Override
9386    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9387        synchronized (this) {
9388            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9389            if (r != null) {
9390                r.setTaskDescription(td);
9391                r.task.updateTaskDescription();
9392            }
9393        }
9394    }
9395
9396    @Override
9397    public void setTaskResizeable(int taskId, int resizeableMode) {
9398        synchronized (this) {
9399            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9400                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9401            if (task == null) {
9402                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9403                return;
9404            }
9405            if (task.mResizeMode != resizeableMode) {
9406                task.mResizeMode = resizeableMode;
9407                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9408                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9409                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9410            }
9411        }
9412    }
9413
9414    @Override
9415    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9416        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9417        long ident = Binder.clearCallingIdentity();
9418        try {
9419            synchronized (this) {
9420                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9421                if (task == null) {
9422                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9423                    return;
9424                }
9425                int stackId = task.stack.mStackId;
9426                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9427                // in crop windows resize mode or if the task size is affected by the docked stack
9428                // changing size. No need to update configuration.
9429                if (bounds != null && task.inCropWindowsResizeMode()
9430                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9431                    mWindowManager.scrollTask(task.taskId, bounds);
9432                    return;
9433                }
9434
9435                // Place the task in the right stack if it isn't there already based on
9436                // the requested bounds.
9437                // The stack transition logic is:
9438                // - a null bounds on a freeform task moves that task to fullscreen
9439                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9440                //   that task to freeform
9441                // - otherwise the task is not moved
9442                if (!StackId.isTaskResizeAllowed(stackId)) {
9443                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9444                }
9445                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9446                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9447                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9448                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9449                }
9450                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9451                if (stackId != task.stack.mStackId) {
9452                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9453                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9454                    preserveWindow = false;
9455                }
9456
9457                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9458                        false /* deferResume */);
9459            }
9460        } finally {
9461            Binder.restoreCallingIdentity(ident);
9462        }
9463    }
9464
9465    @Override
9466    public Rect getTaskBounds(int taskId) {
9467        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9468        long ident = Binder.clearCallingIdentity();
9469        Rect rect = new Rect();
9470        try {
9471            synchronized (this) {
9472                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9473                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9474                if (task == null) {
9475                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9476                    return rect;
9477                }
9478                if (task.stack != null) {
9479                    // Return the bounds from window manager since it will be adjusted for various
9480                    // things like the presense of a docked stack for tasks that aren't resizeable.
9481                    mWindowManager.getTaskBounds(task.taskId, rect);
9482                } else {
9483                    // Task isn't in window manager yet since it isn't associated with a stack.
9484                    // Return the persist value from activity manager
9485                    if (task.mBounds != null) {
9486                        rect.set(task.mBounds);
9487                    } else if (task.mLastNonFullscreenBounds != null) {
9488                        rect.set(task.mLastNonFullscreenBounds);
9489                    }
9490                }
9491            }
9492        } finally {
9493            Binder.restoreCallingIdentity(ident);
9494        }
9495        return rect;
9496    }
9497
9498    @Override
9499    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9500        if (userId != UserHandle.getCallingUserId()) {
9501            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9502                    "getTaskDescriptionIcon");
9503        }
9504        final File passedIconFile = new File(filePath);
9505        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9506                passedIconFile.getName());
9507        if (!legitIconFile.getPath().equals(filePath)
9508                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9509            throw new IllegalArgumentException("Bad file path: " + filePath
9510                    + " passed for userId " + userId);
9511        }
9512        return mRecentTasks.getTaskDescriptionIcon(filePath);
9513    }
9514
9515    @Override
9516    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9517            throws RemoteException {
9518        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9519                opts.getCustomInPlaceResId() == 0) {
9520            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9521                    "with valid animation");
9522        }
9523        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9524        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9525                opts.getCustomInPlaceResId());
9526        mWindowManager.executeAppTransition();
9527    }
9528
9529    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9530            boolean removeFromRecents) {
9531        if (removeFromRecents) {
9532            mRecentTasks.remove(tr);
9533            tr.removedFromRecents();
9534        }
9535        ComponentName component = tr.getBaseIntent().getComponent();
9536        if (component == null) {
9537            Slog.w(TAG, "No component for base intent of task: " + tr);
9538            return;
9539        }
9540
9541        // Find any running services associated with this app and stop if needed.
9542        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9543
9544        if (!killProcess) {
9545            return;
9546        }
9547
9548        // Determine if the process(es) for this task should be killed.
9549        final String pkg = component.getPackageName();
9550        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9551        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9552        for (int i = 0; i < pmap.size(); i++) {
9553
9554            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9555            for (int j = 0; j < uids.size(); j++) {
9556                ProcessRecord proc = uids.valueAt(j);
9557                if (proc.userId != tr.userId) {
9558                    // Don't kill process for a different user.
9559                    continue;
9560                }
9561                if (proc == mHomeProcess) {
9562                    // Don't kill the home process along with tasks from the same package.
9563                    continue;
9564                }
9565                if (!proc.pkgList.containsKey(pkg)) {
9566                    // Don't kill process that is not associated with this task.
9567                    continue;
9568                }
9569
9570                for (int k = 0; k < proc.activities.size(); k++) {
9571                    TaskRecord otherTask = proc.activities.get(k).task;
9572                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9573                        // Don't kill process(es) that has an activity in a different task that is
9574                        // also in recents.
9575                        return;
9576                    }
9577                }
9578
9579                if (proc.foregroundServices) {
9580                    // Don't kill process(es) with foreground service.
9581                    return;
9582                }
9583
9584                // Add process to kill list.
9585                procsToKill.add(proc);
9586            }
9587        }
9588
9589        // Kill the running processes.
9590        for (int i = 0; i < procsToKill.size(); i++) {
9591            ProcessRecord pr = procsToKill.get(i);
9592            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9593                    && pr.curReceivers.isEmpty()) {
9594                pr.kill("remove task", true);
9595            } else {
9596                // We delay killing processes that are not in the background or running a receiver.
9597                pr.waitingToKill = "remove task";
9598            }
9599        }
9600    }
9601
9602    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9603        // Remove all tasks with activities in the specified package from the list of recent tasks
9604        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9605            TaskRecord tr = mRecentTasks.get(i);
9606            if (tr.userId != userId) continue;
9607
9608            ComponentName cn = tr.intent.getComponent();
9609            if (cn != null && cn.getPackageName().equals(packageName)) {
9610                // If the package name matches, remove the task.
9611                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9612            }
9613        }
9614    }
9615
9616    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9617            int userId) {
9618
9619        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9620            TaskRecord tr = mRecentTasks.get(i);
9621            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9622                continue;
9623            }
9624
9625            ComponentName cn = tr.intent.getComponent();
9626            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9627                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9628            if (sameComponent) {
9629                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9630            }
9631        }
9632    }
9633
9634    /**
9635     * Removes the task with the specified task id.
9636     *
9637     * @param taskId Identifier of the task to be removed.
9638     * @param killProcess Kill any process associated with the task if possible.
9639     * @param removeFromRecents Whether to also remove the task from recents.
9640     * @return Returns true if the given task was found and removed.
9641     */
9642    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9643            boolean removeFromRecents) {
9644        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9645                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9646        if (tr != null) {
9647            tr.removeTaskActivitiesLocked();
9648            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9649            if (tr.isPersistable) {
9650                notifyTaskPersisterLocked(null, true);
9651            }
9652            return true;
9653        }
9654        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9655        return false;
9656    }
9657
9658    @Override
9659    public void removeStack(int stackId) {
9660        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9661        if (stackId == HOME_STACK_ID) {
9662            throw new IllegalArgumentException("Removing home stack is not allowed.");
9663        }
9664
9665        synchronized (this) {
9666            final long ident = Binder.clearCallingIdentity();
9667            try {
9668                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9669                if (stack == null) {
9670                    return;
9671                }
9672                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9673                for (int i = tasks.size() - 1; i >= 0; i--) {
9674                    removeTaskByIdLocked(
9675                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9676                }
9677            } finally {
9678                Binder.restoreCallingIdentity(ident);
9679            }
9680        }
9681    }
9682
9683    @Override
9684    public boolean removeTask(int taskId) {
9685        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9686        synchronized (this) {
9687            final long ident = Binder.clearCallingIdentity();
9688            try {
9689                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9690            } finally {
9691                Binder.restoreCallingIdentity(ident);
9692            }
9693        }
9694    }
9695
9696    /**
9697     * TODO: Add mController hook
9698     */
9699    @Override
9700    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9701        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9702
9703        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9704        synchronized(this) {
9705            moveTaskToFrontLocked(taskId, flags, bOptions);
9706        }
9707    }
9708
9709    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9710        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9711
9712        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9713                Binder.getCallingUid(), -1, -1, "Task to front")) {
9714            ActivityOptions.abort(options);
9715            return;
9716        }
9717        final long origId = Binder.clearCallingIdentity();
9718        try {
9719            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9720            if (task == null) {
9721                Slog.d(TAG, "Could not find task for id: "+ taskId);
9722                return;
9723            }
9724            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9725                mStackSupervisor.showLockTaskToast();
9726                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9727                return;
9728            }
9729            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9730            if (prev != null && prev.isRecentsActivity()) {
9731                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9732            }
9733            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9734                    false /* forceNonResizable */);
9735        } finally {
9736            Binder.restoreCallingIdentity(origId);
9737        }
9738        ActivityOptions.abort(options);
9739    }
9740
9741    /**
9742     * Moves an activity, and all of the other activities within the same task, to the bottom
9743     * of the history stack.  The activity's order within the task is unchanged.
9744     *
9745     * @param token A reference to the activity we wish to move
9746     * @param nonRoot If false then this only works if the activity is the root
9747     *                of a task; if true it will work for any activity in a task.
9748     * @return Returns true if the move completed, false if not.
9749     */
9750    @Override
9751    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9752        enforceNotIsolatedCaller("moveActivityTaskToBack");
9753        synchronized(this) {
9754            final long origId = Binder.clearCallingIdentity();
9755            try {
9756                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9757                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9758                if (task != null) {
9759                    if (mStackSupervisor.isLockedTask(task)) {
9760                        mStackSupervisor.showLockTaskToast();
9761                        return false;
9762                    }
9763                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9764                }
9765            } finally {
9766                Binder.restoreCallingIdentity(origId);
9767            }
9768        }
9769        return false;
9770    }
9771
9772    @Override
9773    public void moveTaskBackwards(int task) {
9774        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9775                "moveTaskBackwards()");
9776
9777        synchronized(this) {
9778            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9779                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9780                return;
9781            }
9782            final long origId = Binder.clearCallingIdentity();
9783            moveTaskBackwardsLocked(task);
9784            Binder.restoreCallingIdentity(origId);
9785        }
9786    }
9787
9788    private final void moveTaskBackwardsLocked(int task) {
9789        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9790    }
9791
9792    @Override
9793    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9794            IActivityContainerCallback callback) throws RemoteException {
9795        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9796        synchronized (this) {
9797            if (parentActivityToken == null) {
9798                throw new IllegalArgumentException("parent token must not be null");
9799            }
9800            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9801            if (r == null) {
9802                return null;
9803            }
9804            if (callback == null) {
9805                throw new IllegalArgumentException("callback must not be null");
9806            }
9807            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9808        }
9809    }
9810
9811    @Override
9812    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9813        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9814        synchronized (this) {
9815            mStackSupervisor.deleteActivityContainer(container);
9816        }
9817    }
9818
9819    @Override
9820    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9821        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9822        synchronized (this) {
9823            final int stackId = mStackSupervisor.getNextStackId();
9824            final ActivityStack stack =
9825                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9826            if (stack == null) {
9827                return null;
9828            }
9829            return stack.mActivityContainer;
9830        }
9831    }
9832
9833    @Override
9834    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9835        synchronized (this) {
9836            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9837            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9838                return stack.mActivityContainer.getDisplayId();
9839            }
9840            return Display.DEFAULT_DISPLAY;
9841        }
9842    }
9843
9844    @Override
9845    public int getActivityStackId(IBinder token) throws RemoteException {
9846        synchronized (this) {
9847            ActivityStack stack = ActivityRecord.getStackLocked(token);
9848            if (stack == null) {
9849                return INVALID_STACK_ID;
9850            }
9851            return stack.mStackId;
9852        }
9853    }
9854
9855    @Override
9856    public void exitFreeformMode(IBinder token) throws RemoteException {
9857        synchronized (this) {
9858            long ident = Binder.clearCallingIdentity();
9859            try {
9860                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9861                if (r == null) {
9862                    throw new IllegalArgumentException(
9863                            "exitFreeformMode: No activity record matching token=" + token);
9864                }
9865                final ActivityStack stack = r.getStackLocked(token);
9866                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9867                    throw new IllegalStateException(
9868                            "exitFreeformMode: You can only go fullscreen from freeform.");
9869                }
9870                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9871                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9872                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9873            } finally {
9874                Binder.restoreCallingIdentity(ident);
9875            }
9876        }
9877    }
9878
9879    @Override
9880    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9881        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9882        if (stackId == HOME_STACK_ID) {
9883            throw new IllegalArgumentException(
9884                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9885        }
9886        synchronized (this) {
9887            long ident = Binder.clearCallingIdentity();
9888            try {
9889                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9890                        + " to stackId=" + stackId + " toTop=" + toTop);
9891                if (stackId == DOCKED_STACK_ID) {
9892                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9893                            null /* initialBounds */);
9894                }
9895                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9896                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9897                if (result && stackId == DOCKED_STACK_ID) {
9898                    // If task moved to docked stack - show recents if needed.
9899                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9900                            "moveTaskToDockedStack");
9901                }
9902            } finally {
9903                Binder.restoreCallingIdentity(ident);
9904            }
9905        }
9906    }
9907
9908    @Override
9909    public void swapDockedAndFullscreenStack() throws RemoteException {
9910        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9911        synchronized (this) {
9912            long ident = Binder.clearCallingIdentity();
9913            try {
9914                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9915                        FULLSCREEN_WORKSPACE_STACK_ID);
9916                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9917                        : null;
9918                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9919                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9920                        : null;
9921                if (topTask == null || tasks == null || tasks.size() == 0) {
9922                    Slog.w(TAG,
9923                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9924                    return;
9925                }
9926
9927                // TODO: App transition
9928                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9929
9930                // Defer the resume so resume/pausing while moving stacks is dangerous.
9931                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9932                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9933                        ANIMATE, true /* deferResume */);
9934                final int size = tasks.size();
9935                for (int i = 0; i < size; i++) {
9936                    final int id = tasks.get(i).taskId;
9937                    if (id == topTask.taskId) {
9938                        continue;
9939                    }
9940                    mStackSupervisor.moveTaskToStackLocked(id,
9941                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9942                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9943                }
9944
9945                // Because we deferred the resume, to avoid conflicts with stack switches while
9946                // resuming, we need to do it after all the tasks are moved.
9947                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9948                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9949
9950                mWindowManager.executeAppTransition();
9951            } finally {
9952                Binder.restoreCallingIdentity(ident);
9953            }
9954        }
9955    }
9956
9957    /**
9958     * Moves the input task to the docked stack.
9959     *
9960     * @param taskId Id of task to move.
9961     * @param createMode The mode the docked stack should be created in if it doesn't exist
9962     *                   already. See
9963     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9964     *                   and
9965     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9966     * @param toTop If the task and stack should be moved to the top.
9967     * @param animate Whether we should play an animation for the moving the task
9968     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9969     *                      docked stack. Pass {@code null} to use default bounds.
9970     */
9971    @Override
9972    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9973            Rect initialBounds, boolean moveHomeStackFront) {
9974        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9975        synchronized (this) {
9976            long ident = Binder.clearCallingIdentity();
9977            try {
9978                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9979                        + " to createMode=" + createMode + " toTop=" + toTop);
9980                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9981                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9982                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9983                        animate, DEFER_RESUME);
9984                if (moved) {
9985                    if (moveHomeStackFront) {
9986                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9987                    }
9988                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9989                }
9990                return moved;
9991            } finally {
9992                Binder.restoreCallingIdentity(ident);
9993            }
9994        }
9995    }
9996
9997    /**
9998     * Moves the top activity in the input stackId to the pinned stack.
9999     *
10000     * @param stackId Id of stack to move the top activity to pinned stack.
10001     * @param bounds Bounds to use for pinned stack.
10002     *
10003     * @return True if the top activity of the input stack was successfully moved to the pinned
10004     *          stack.
10005     */
10006    @Override
10007    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10008        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10009        synchronized (this) {
10010            if (!mSupportsPictureInPicture) {
10011                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10012                        + "Device doesn't support picture-in-pciture mode");
10013            }
10014
10015            long ident = Binder.clearCallingIdentity();
10016            try {
10017                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10018            } finally {
10019                Binder.restoreCallingIdentity(ident);
10020            }
10021        }
10022    }
10023
10024    @Override
10025    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10026            boolean preserveWindows, boolean animate, int animationDuration) {
10027        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10028        long ident = Binder.clearCallingIdentity();
10029        try {
10030            synchronized (this) {
10031                if (animate) {
10032                    if (stackId == PINNED_STACK_ID) {
10033                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10034                    } else {
10035                        throw new IllegalArgumentException("Stack: " + stackId
10036                                + " doesn't support animated resize.");
10037                    }
10038                } else {
10039                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10040                            null /* tempTaskInsetBounds */, preserveWindows,
10041                            allowResizeInDockedMode, !DEFER_RESUME);
10042                }
10043            }
10044        } finally {
10045            Binder.restoreCallingIdentity(ident);
10046        }
10047    }
10048
10049    @Override
10050    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10051            Rect tempDockedTaskInsetBounds,
10052            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10053        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10054                "resizeDockedStack()");
10055        long ident = Binder.clearCallingIdentity();
10056        try {
10057            synchronized (this) {
10058                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10059                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10060                        PRESERVE_WINDOWS);
10061            }
10062        } finally {
10063            Binder.restoreCallingIdentity(ident);
10064        }
10065    }
10066
10067    @Override
10068    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10069        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10070                "resizePinnedStack()");
10071        final long ident = Binder.clearCallingIdentity();
10072        try {
10073            synchronized (this) {
10074                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10075            }
10076        } finally {
10077            Binder.restoreCallingIdentity(ident);
10078        }
10079    }
10080
10081    @Override
10082    public void positionTaskInStack(int taskId, int stackId, int position) {
10083        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10084        if (stackId == HOME_STACK_ID) {
10085            throw new IllegalArgumentException(
10086                    "positionTaskInStack: Attempt to change the position of task "
10087                    + taskId + " in/to home stack");
10088        }
10089        synchronized (this) {
10090            long ident = Binder.clearCallingIdentity();
10091            try {
10092                if (DEBUG_STACK) Slog.d(TAG_STACK,
10093                        "positionTaskInStack: positioning task=" + taskId
10094                        + " in stackId=" + stackId + " at position=" + position);
10095                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10096            } finally {
10097                Binder.restoreCallingIdentity(ident);
10098            }
10099        }
10100    }
10101
10102    @Override
10103    public List<StackInfo> getAllStackInfos() {
10104        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10105        long ident = Binder.clearCallingIdentity();
10106        try {
10107            synchronized (this) {
10108                return mStackSupervisor.getAllStackInfosLocked();
10109            }
10110        } finally {
10111            Binder.restoreCallingIdentity(ident);
10112        }
10113    }
10114
10115    @Override
10116    public StackInfo getStackInfo(int stackId) {
10117        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10118        long ident = Binder.clearCallingIdentity();
10119        try {
10120            synchronized (this) {
10121                return mStackSupervisor.getStackInfoLocked(stackId);
10122            }
10123        } finally {
10124            Binder.restoreCallingIdentity(ident);
10125        }
10126    }
10127
10128    @Override
10129    public boolean isInHomeStack(int taskId) {
10130        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10131        long ident = Binder.clearCallingIdentity();
10132        try {
10133            synchronized (this) {
10134                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10135                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10136                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10137            }
10138        } finally {
10139            Binder.restoreCallingIdentity(ident);
10140        }
10141    }
10142
10143    @Override
10144    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10145        synchronized(this) {
10146            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10147        }
10148    }
10149
10150    @Override
10151    public void updateDeviceOwner(String packageName) {
10152        final int callingUid = Binder.getCallingUid();
10153        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10154            throw new SecurityException("updateDeviceOwner called from non-system process");
10155        }
10156        synchronized (this) {
10157            mDeviceOwnerName = packageName;
10158        }
10159    }
10160
10161    @Override
10162    public void updateLockTaskPackages(int userId, String[] packages) {
10163        final int callingUid = Binder.getCallingUid();
10164        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10165            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10166                    "updateLockTaskPackages()");
10167        }
10168        synchronized (this) {
10169            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10170                    Arrays.toString(packages));
10171            mLockTaskPackages.put(userId, packages);
10172            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10173        }
10174    }
10175
10176
10177    void startLockTaskModeLocked(TaskRecord task) {
10178        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10179        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10180            return;
10181        }
10182
10183        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10184        // is initiated by system after the pinning request was shown and locked mode is initiated
10185        // by an authorized app directly
10186        final int callingUid = Binder.getCallingUid();
10187        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10188        long ident = Binder.clearCallingIdentity();
10189        try {
10190            if (!isSystemInitiated) {
10191                task.mLockTaskUid = callingUid;
10192                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10193                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10194                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10195                    StatusBarManagerInternal statusBarManager =
10196                            LocalServices.getService(StatusBarManagerInternal.class);
10197                    if (statusBarManager != null) {
10198                        statusBarManager.showScreenPinningRequest(task.taskId);
10199                    }
10200                    return;
10201                }
10202
10203                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10204                if (stack == null || task != stack.topTask()) {
10205                    throw new IllegalArgumentException("Invalid task, not in foreground");
10206                }
10207            }
10208            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10209                    "Locking fully");
10210            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10211                    ActivityManager.LOCK_TASK_MODE_PINNED :
10212                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10213                    "startLockTask", true);
10214        } finally {
10215            Binder.restoreCallingIdentity(ident);
10216        }
10217    }
10218
10219    @Override
10220    public void startLockTaskMode(int taskId) {
10221        synchronized (this) {
10222            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10223            if (task != null) {
10224                startLockTaskModeLocked(task);
10225            }
10226        }
10227    }
10228
10229    @Override
10230    public void startLockTaskMode(IBinder token) {
10231        synchronized (this) {
10232            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10233            if (r == null) {
10234                return;
10235            }
10236            final TaskRecord task = r.task;
10237            if (task != null) {
10238                startLockTaskModeLocked(task);
10239            }
10240        }
10241    }
10242
10243    @Override
10244    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10245        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10246        // This makes inner call to look as if it was initiated by system.
10247        long ident = Binder.clearCallingIdentity();
10248        try {
10249            synchronized (this) {
10250                startLockTaskMode(taskId);
10251            }
10252        } finally {
10253            Binder.restoreCallingIdentity(ident);
10254        }
10255    }
10256
10257    @Override
10258    public void stopLockTaskMode() {
10259        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10260        if (lockTask == null) {
10261            // Our work here is done.
10262            return;
10263        }
10264
10265        final int callingUid = Binder.getCallingUid();
10266        final int lockTaskUid = lockTask.mLockTaskUid;
10267        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10268        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10269            // Done.
10270            return;
10271        } else {
10272            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10273            // It is possible lockTaskMode was started by the system process because
10274            // android:lockTaskMode is set to a locking value in the application manifest
10275            // instead of the app calling startLockTaskMode. In this case
10276            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10277            // {@link TaskRecord.effectiveUid} instead. Also caller with
10278            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10279            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10280                    && callingUid != lockTaskUid
10281                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10282                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10283                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10284            }
10285        }
10286        long ident = Binder.clearCallingIdentity();
10287        try {
10288            Log.d(TAG, "stopLockTaskMode");
10289            // Stop lock task
10290            synchronized (this) {
10291                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10292                        "stopLockTask", true);
10293            }
10294            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10295            if (tm != null) {
10296                tm.showInCallScreen(false);
10297            }
10298        } finally {
10299            Binder.restoreCallingIdentity(ident);
10300        }
10301    }
10302
10303    /**
10304     * This API should be called by SystemUI only when user perform certain action to dismiss
10305     * lock task mode. We should only dismiss pinned lock task mode in this case.
10306     */
10307    @Override
10308    public void stopSystemLockTaskMode() throws RemoteException {
10309        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10310            stopLockTaskMode();
10311        } else {
10312            mStackSupervisor.showLockTaskToast();
10313        }
10314    }
10315
10316    @Override
10317    public boolean isInLockTaskMode() {
10318        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10319    }
10320
10321    @Override
10322    public int getLockTaskModeState() {
10323        synchronized (this) {
10324            return mStackSupervisor.getLockTaskModeState();
10325        }
10326    }
10327
10328    @Override
10329    public void showLockTaskEscapeMessage(IBinder token) {
10330        synchronized (this) {
10331            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10332            if (r == null) {
10333                return;
10334            }
10335            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10336        }
10337    }
10338
10339    // =========================================================
10340    // CONTENT PROVIDERS
10341    // =========================================================
10342
10343    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10344        List<ProviderInfo> providers = null;
10345        try {
10346            providers = AppGlobals.getPackageManager()
10347                    .queryContentProviders(app.processName, app.uid,
10348                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10349                                    | MATCH_DEBUG_TRIAGED_MISSING)
10350                    .getList();
10351        } catch (RemoteException ex) {
10352        }
10353        if (DEBUG_MU) Slog.v(TAG_MU,
10354                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10355        int userId = app.userId;
10356        if (providers != null) {
10357            int N = providers.size();
10358            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10359            for (int i=0; i<N; i++) {
10360                // TODO: keep logic in sync with installEncryptionUnawareProviders
10361                ProviderInfo cpi =
10362                    (ProviderInfo)providers.get(i);
10363                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10364                        cpi.name, cpi.flags);
10365                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10366                    // This is a singleton provider, but a user besides the
10367                    // default user is asking to initialize a process it runs
10368                    // in...  well, no, it doesn't actually run in this process,
10369                    // it runs in the process of the default user.  Get rid of it.
10370                    providers.remove(i);
10371                    N--;
10372                    i--;
10373                    continue;
10374                }
10375
10376                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10377                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10378                if (cpr == null) {
10379                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10380                    mProviderMap.putProviderByClass(comp, cpr);
10381                }
10382                if (DEBUG_MU) Slog.v(TAG_MU,
10383                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10384                app.pubProviders.put(cpi.name, cpr);
10385                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10386                    // Don't add this if it is a platform component that is marked
10387                    // to run in multiple processes, because this is actually
10388                    // part of the framework so doesn't make sense to track as a
10389                    // separate apk in the process.
10390                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10391                            mProcessStats);
10392                }
10393                notifyPackageUse(cpi.applicationInfo.packageName,
10394                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10395            }
10396        }
10397        return providers;
10398    }
10399
10400    /**
10401     * Check if {@link ProcessRecord} has a possible chance at accessing the
10402     * given {@link ProviderInfo}. Final permission checking is always done
10403     * in {@link ContentProvider}.
10404     */
10405    private final String checkContentProviderPermissionLocked(
10406            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10407        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10408        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10409        boolean checkedGrants = false;
10410        if (checkUser) {
10411            // Looking for cross-user grants before enforcing the typical cross-users permissions
10412            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10413            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10414                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10415                    return null;
10416                }
10417                checkedGrants = true;
10418            }
10419            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10420                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10421            if (userId != tmpTargetUserId) {
10422                // When we actually went to determine the final targer user ID, this ended
10423                // up different than our initial check for the authority.  This is because
10424                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10425                // SELF.  So we need to re-check the grants again.
10426                checkedGrants = false;
10427            }
10428        }
10429        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10430                cpi.applicationInfo.uid, cpi.exported)
10431                == PackageManager.PERMISSION_GRANTED) {
10432            return null;
10433        }
10434        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10435                cpi.applicationInfo.uid, cpi.exported)
10436                == PackageManager.PERMISSION_GRANTED) {
10437            return null;
10438        }
10439
10440        PathPermission[] pps = cpi.pathPermissions;
10441        if (pps != null) {
10442            int i = pps.length;
10443            while (i > 0) {
10444                i--;
10445                PathPermission pp = pps[i];
10446                String pprperm = pp.getReadPermission();
10447                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10448                        cpi.applicationInfo.uid, cpi.exported)
10449                        == PackageManager.PERMISSION_GRANTED) {
10450                    return null;
10451                }
10452                String ppwperm = pp.getWritePermission();
10453                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10454                        cpi.applicationInfo.uid, cpi.exported)
10455                        == PackageManager.PERMISSION_GRANTED) {
10456                    return null;
10457                }
10458            }
10459        }
10460        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10461            return null;
10462        }
10463
10464        String msg;
10465        if (!cpi.exported) {
10466            msg = "Permission Denial: opening provider " + cpi.name
10467                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10468                    + ", uid=" + callingUid + ") that is not exported from uid "
10469                    + cpi.applicationInfo.uid;
10470        } else {
10471            msg = "Permission Denial: opening provider " + cpi.name
10472                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10473                    + ", uid=" + callingUid + ") requires "
10474                    + cpi.readPermission + " or " + cpi.writePermission;
10475        }
10476        Slog.w(TAG, msg);
10477        return msg;
10478    }
10479
10480    /**
10481     * Returns if the ContentProvider has granted a uri to callingUid
10482     */
10483    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10484        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10485        if (perms != null) {
10486            for (int i=perms.size()-1; i>=0; i--) {
10487                GrantUri grantUri = perms.keyAt(i);
10488                if (grantUri.sourceUserId == userId || !checkUser) {
10489                    if (matchesProvider(grantUri.uri, cpi)) {
10490                        return true;
10491                    }
10492                }
10493            }
10494        }
10495        return false;
10496    }
10497
10498    /**
10499     * Returns true if the uri authority is one of the authorities specified in the provider.
10500     */
10501    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10502        String uriAuth = uri.getAuthority();
10503        String cpiAuth = cpi.authority;
10504        if (cpiAuth.indexOf(';') == -1) {
10505            return cpiAuth.equals(uriAuth);
10506        }
10507        String[] cpiAuths = cpiAuth.split(";");
10508        int length = cpiAuths.length;
10509        for (int i = 0; i < length; i++) {
10510            if (cpiAuths[i].equals(uriAuth)) return true;
10511        }
10512        return false;
10513    }
10514
10515    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10516            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10517        if (r != null) {
10518            for (int i=0; i<r.conProviders.size(); i++) {
10519                ContentProviderConnection conn = r.conProviders.get(i);
10520                if (conn.provider == cpr) {
10521                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10522                            "Adding provider requested by "
10523                            + r.processName + " from process "
10524                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10525                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10526                    if (stable) {
10527                        conn.stableCount++;
10528                        conn.numStableIncs++;
10529                    } else {
10530                        conn.unstableCount++;
10531                        conn.numUnstableIncs++;
10532                    }
10533                    return conn;
10534                }
10535            }
10536            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10537            if (stable) {
10538                conn.stableCount = 1;
10539                conn.numStableIncs = 1;
10540            } else {
10541                conn.unstableCount = 1;
10542                conn.numUnstableIncs = 1;
10543            }
10544            cpr.connections.add(conn);
10545            r.conProviders.add(conn);
10546            startAssociationLocked(r.uid, r.processName, r.curProcState,
10547                    cpr.uid, cpr.name, cpr.info.processName);
10548            return conn;
10549        }
10550        cpr.addExternalProcessHandleLocked(externalProcessToken);
10551        return null;
10552    }
10553
10554    boolean decProviderCountLocked(ContentProviderConnection conn,
10555            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10556        if (conn != null) {
10557            cpr = conn.provider;
10558            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10559                    "Removing provider requested by "
10560                    + conn.client.processName + " from process "
10561                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10562                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10563            if (stable) {
10564                conn.stableCount--;
10565            } else {
10566                conn.unstableCount--;
10567            }
10568            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10569                cpr.connections.remove(conn);
10570                conn.client.conProviders.remove(conn);
10571                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10572                    // The client is more important than last activity -- note the time this
10573                    // is happening, so we keep the old provider process around a bit as last
10574                    // activity to avoid thrashing it.
10575                    if (cpr.proc != null) {
10576                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10577                    }
10578                }
10579                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10580                return true;
10581            }
10582            return false;
10583        }
10584        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10585        return false;
10586    }
10587
10588    private void checkTime(long startTime, String where) {
10589        long now = SystemClock.uptimeMillis();
10590        if ((now-startTime) > 50) {
10591            // If we are taking more than 50ms, log about it.
10592            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10593        }
10594    }
10595
10596    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10597            PROC_SPACE_TERM,
10598            PROC_SPACE_TERM|PROC_PARENS,
10599            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10600    };
10601
10602    private final long[] mProcessStateStatsLongs = new long[1];
10603
10604    boolean isProcessAliveLocked(ProcessRecord proc) {
10605        if (proc.procStatFile == null) {
10606            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10607        }
10608        mProcessStateStatsLongs[0] = 0;
10609        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10610                mProcessStateStatsLongs, null)) {
10611            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10612            return false;
10613        }
10614        final long state = mProcessStateStatsLongs[0];
10615        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10616                + (char)state);
10617        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10618    }
10619
10620    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10621            String name, IBinder token, boolean stable, int userId) {
10622        ContentProviderRecord cpr;
10623        ContentProviderConnection conn = null;
10624        ProviderInfo cpi = null;
10625
10626        synchronized(this) {
10627            long startTime = SystemClock.uptimeMillis();
10628
10629            ProcessRecord r = null;
10630            if (caller != null) {
10631                r = getRecordForAppLocked(caller);
10632                if (r == null) {
10633                    throw new SecurityException(
10634                            "Unable to find app for caller " + caller
10635                          + " (pid=" + Binder.getCallingPid()
10636                          + ") when getting content provider " + name);
10637                }
10638            }
10639
10640            boolean checkCrossUser = true;
10641
10642            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10643
10644            // First check if this content provider has been published...
10645            cpr = mProviderMap.getProviderByName(name, userId);
10646            // If that didn't work, check if it exists for user 0 and then
10647            // verify that it's a singleton provider before using it.
10648            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10649                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10650                if (cpr != null) {
10651                    cpi = cpr.info;
10652                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10653                            cpi.name, cpi.flags)
10654                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10655                        userId = UserHandle.USER_SYSTEM;
10656                        checkCrossUser = false;
10657                    } else {
10658                        cpr = null;
10659                        cpi = null;
10660                    }
10661                }
10662            }
10663
10664            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10665            if (providerRunning) {
10666                cpi = cpr.info;
10667                String msg;
10668                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10669                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10670                        != null) {
10671                    throw new SecurityException(msg);
10672                }
10673                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10674
10675                if (r != null && cpr.canRunHere(r)) {
10676                    // This provider has been published or is in the process
10677                    // of being published...  but it is also allowed to run
10678                    // in the caller's process, so don't make a connection
10679                    // and just let the caller instantiate its own instance.
10680                    ContentProviderHolder holder = cpr.newHolder(null);
10681                    // don't give caller the provider object, it needs
10682                    // to make its own.
10683                    holder.provider = null;
10684                    return holder;
10685                }
10686
10687                final long origId = Binder.clearCallingIdentity();
10688
10689                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10690
10691                // In this case the provider instance already exists, so we can
10692                // return it right away.
10693                conn = incProviderCountLocked(r, cpr, token, stable);
10694                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10695                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10696                        // If this is a perceptible app accessing the provider,
10697                        // make sure to count it as being accessed and thus
10698                        // back up on the LRU list.  This is good because
10699                        // content providers are often expensive to start.
10700                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10701                        updateLruProcessLocked(cpr.proc, false, null);
10702                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10703                    }
10704                }
10705
10706                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10707                final int verifiedAdj = cpr.proc.verifiedAdj;
10708                boolean success = updateOomAdjLocked(cpr.proc);
10709                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10710                // if the process has been successfully adjusted.  So to reduce races with
10711                // it, we will check whether the process still exists.  Note that this doesn't
10712                // completely get rid of races with LMK killing the process, but should make
10713                // them much smaller.
10714                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10715                    success = false;
10716                }
10717                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10718                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10719                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10720                // NOTE: there is still a race here where a signal could be
10721                // pending on the process even though we managed to update its
10722                // adj level.  Not sure what to do about this, but at least
10723                // the race is now smaller.
10724                if (!success) {
10725                    // Uh oh...  it looks like the provider's process
10726                    // has been killed on us.  We need to wait for a new
10727                    // process to be started, and make sure its death
10728                    // doesn't kill our process.
10729                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10730                            + " is crashing; detaching " + r);
10731                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10732                    checkTime(startTime, "getContentProviderImpl: before appDied");
10733                    appDiedLocked(cpr.proc);
10734                    checkTime(startTime, "getContentProviderImpl: after appDied");
10735                    if (!lastRef) {
10736                        // This wasn't the last ref our process had on
10737                        // the provider...  we have now been killed, bail.
10738                        return null;
10739                    }
10740                    providerRunning = false;
10741                    conn = null;
10742                } else {
10743                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10744                }
10745
10746                Binder.restoreCallingIdentity(origId);
10747            }
10748
10749            if (!providerRunning) {
10750                try {
10751                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10752                    cpi = AppGlobals.getPackageManager().
10753                        resolveContentProvider(name,
10754                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10755                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10756                } catch (RemoteException ex) {
10757                }
10758                if (cpi == null) {
10759                    return null;
10760                }
10761                // If the provider is a singleton AND
10762                // (it's a call within the same user || the provider is a
10763                // privileged app)
10764                // Then allow connecting to the singleton provider
10765                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10766                        cpi.name, cpi.flags)
10767                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10768                if (singleton) {
10769                    userId = UserHandle.USER_SYSTEM;
10770                }
10771                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10772                checkTime(startTime, "getContentProviderImpl: got app info for user");
10773
10774                String msg;
10775                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10776                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10777                        != null) {
10778                    throw new SecurityException(msg);
10779                }
10780                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10781
10782                if (!mProcessesReady
10783                        && !cpi.processName.equals("system")) {
10784                    // If this content provider does not run in the system
10785                    // process, and the system is not yet ready to run other
10786                    // processes, then fail fast instead of hanging.
10787                    throw new IllegalArgumentException(
10788                            "Attempt to launch content provider before system ready");
10789                }
10790
10791                // Make sure that the user who owns this provider is running.  If not,
10792                // we don't want to allow it to run.
10793                if (!mUserController.isUserRunningLocked(userId, 0)) {
10794                    Slog.w(TAG, "Unable to launch app "
10795                            + cpi.applicationInfo.packageName + "/"
10796                            + cpi.applicationInfo.uid + " for provider "
10797                            + name + ": user " + userId + " is stopped");
10798                    return null;
10799                }
10800
10801                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10802                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10803                cpr = mProviderMap.getProviderByClass(comp, userId);
10804                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10805                final boolean firstClass = cpr == null;
10806                if (firstClass) {
10807                    final long ident = Binder.clearCallingIdentity();
10808
10809                    // If permissions need a review before any of the app components can run,
10810                    // we return no provider and launch a review activity if the calling app
10811                    // is in the foreground.
10812                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10813                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10814                            return null;
10815                        }
10816                    }
10817
10818                    try {
10819                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10820                        ApplicationInfo ai =
10821                            AppGlobals.getPackageManager().
10822                                getApplicationInfo(
10823                                        cpi.applicationInfo.packageName,
10824                                        STOCK_PM_FLAGS, userId);
10825                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10826                        if (ai == null) {
10827                            Slog.w(TAG, "No package info for content provider "
10828                                    + cpi.name);
10829                            return null;
10830                        }
10831                        ai = getAppInfoForUser(ai, userId);
10832                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10833                    } catch (RemoteException ex) {
10834                        // pm is in same process, this will never happen.
10835                    } finally {
10836                        Binder.restoreCallingIdentity(ident);
10837                    }
10838                }
10839
10840                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10841
10842                if (r != null && cpr.canRunHere(r)) {
10843                    // If this is a multiprocess provider, then just return its
10844                    // info and allow the caller to instantiate it.  Only do
10845                    // this if the provider is the same user as the caller's
10846                    // process, or can run as root (so can be in any process).
10847                    return cpr.newHolder(null);
10848                }
10849
10850                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10851                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10852                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10853
10854                // This is single process, and our app is now connecting to it.
10855                // See if we are already in the process of launching this
10856                // provider.
10857                final int N = mLaunchingProviders.size();
10858                int i;
10859                for (i = 0; i < N; i++) {
10860                    if (mLaunchingProviders.get(i) == cpr) {
10861                        break;
10862                    }
10863                }
10864
10865                // If the provider is not already being launched, then get it
10866                // started.
10867                if (i >= N) {
10868                    final long origId = Binder.clearCallingIdentity();
10869
10870                    try {
10871                        // Content provider is now in use, its package can't be stopped.
10872                        try {
10873                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10874                            AppGlobals.getPackageManager().setPackageStoppedState(
10875                                    cpr.appInfo.packageName, false, userId);
10876                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10877                        } catch (RemoteException e) {
10878                        } catch (IllegalArgumentException e) {
10879                            Slog.w(TAG, "Failed trying to unstop package "
10880                                    + cpr.appInfo.packageName + ": " + e);
10881                        }
10882
10883                        // Use existing process if already started
10884                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10885                        ProcessRecord proc = getProcessRecordLocked(
10886                                cpi.processName, cpr.appInfo.uid, false);
10887                        if (proc != null && proc.thread != null && !proc.killed) {
10888                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10889                                    "Installing in existing process " + proc);
10890                            if (!proc.pubProviders.containsKey(cpi.name)) {
10891                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10892                                proc.pubProviders.put(cpi.name, cpr);
10893                                try {
10894                                    proc.thread.scheduleInstallProvider(cpi);
10895                                } catch (RemoteException e) {
10896                                }
10897                            }
10898                        } else {
10899                            checkTime(startTime, "getContentProviderImpl: before start process");
10900                            proc = startProcessLocked(cpi.processName,
10901                                    cpr.appInfo, false, 0, "content provider",
10902                                    new ComponentName(cpi.applicationInfo.packageName,
10903                                            cpi.name), false, false, false);
10904                            checkTime(startTime, "getContentProviderImpl: after start process");
10905                            if (proc == null) {
10906                                Slog.w(TAG, "Unable to launch app "
10907                                        + cpi.applicationInfo.packageName + "/"
10908                                        + cpi.applicationInfo.uid + " for provider "
10909                                        + name + ": process is bad");
10910                                return null;
10911                            }
10912                        }
10913                        cpr.launchingApp = proc;
10914                        mLaunchingProviders.add(cpr);
10915                    } finally {
10916                        Binder.restoreCallingIdentity(origId);
10917                    }
10918                }
10919
10920                checkTime(startTime, "getContentProviderImpl: updating data structures");
10921
10922                // Make sure the provider is published (the same provider class
10923                // may be published under multiple names).
10924                if (firstClass) {
10925                    mProviderMap.putProviderByClass(comp, cpr);
10926                }
10927
10928                mProviderMap.putProviderByName(name, cpr);
10929                conn = incProviderCountLocked(r, cpr, token, stable);
10930                if (conn != null) {
10931                    conn.waiting = true;
10932                }
10933            }
10934            checkTime(startTime, "getContentProviderImpl: done!");
10935        }
10936
10937        // Wait for the provider to be published...
10938        synchronized (cpr) {
10939            while (cpr.provider == null) {
10940                if (cpr.launchingApp == null) {
10941                    Slog.w(TAG, "Unable to launch app "
10942                            + cpi.applicationInfo.packageName + "/"
10943                            + cpi.applicationInfo.uid + " for provider "
10944                            + name + ": launching app became null");
10945                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10946                            UserHandle.getUserId(cpi.applicationInfo.uid),
10947                            cpi.applicationInfo.packageName,
10948                            cpi.applicationInfo.uid, name);
10949                    return null;
10950                }
10951                try {
10952                    if (DEBUG_MU) Slog.v(TAG_MU,
10953                            "Waiting to start provider " + cpr
10954                            + " launchingApp=" + cpr.launchingApp);
10955                    if (conn != null) {
10956                        conn.waiting = true;
10957                    }
10958                    cpr.wait();
10959                } catch (InterruptedException ex) {
10960                } finally {
10961                    if (conn != null) {
10962                        conn.waiting = false;
10963                    }
10964                }
10965            }
10966        }
10967        return cpr != null ? cpr.newHolder(conn) : null;
10968    }
10969
10970    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10971            ProcessRecord r, final int userId) {
10972        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10973                cpi.packageName, userId)) {
10974
10975            final boolean callerForeground = r == null || r.setSchedGroup
10976                    != ProcessList.SCHED_GROUP_BACKGROUND;
10977
10978            // Show a permission review UI only for starting from a foreground app
10979            if (!callerForeground) {
10980                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10981                        + cpi.packageName + " requires a permissions review");
10982                return false;
10983            }
10984
10985            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10986            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10987                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10988            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10989
10990            if (DEBUG_PERMISSIONS_REVIEW) {
10991                Slog.i(TAG, "u" + userId + " Launching permission review "
10992                        + "for package " + cpi.packageName);
10993            }
10994
10995            final UserHandle userHandle = new UserHandle(userId);
10996            mHandler.post(new Runnable() {
10997                @Override
10998                public void run() {
10999                    mContext.startActivityAsUser(intent, userHandle);
11000                }
11001            });
11002
11003            return false;
11004        }
11005
11006        return true;
11007    }
11008
11009    PackageManagerInternal getPackageManagerInternalLocked() {
11010        if (mPackageManagerInt == null) {
11011            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11012        }
11013        return mPackageManagerInt;
11014    }
11015
11016    @Override
11017    public final ContentProviderHolder getContentProvider(
11018            IApplicationThread caller, String name, int userId, boolean stable) {
11019        enforceNotIsolatedCaller("getContentProvider");
11020        if (caller == null) {
11021            String msg = "null IApplicationThread when getting content provider "
11022                    + name;
11023            Slog.w(TAG, msg);
11024            throw new SecurityException(msg);
11025        }
11026        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11027        // with cross-user grant.
11028        return getContentProviderImpl(caller, name, null, stable, userId);
11029    }
11030
11031    public ContentProviderHolder getContentProviderExternal(
11032            String name, int userId, IBinder token) {
11033        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11034            "Do not have permission in call getContentProviderExternal()");
11035        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11036                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11037        return getContentProviderExternalUnchecked(name, token, userId);
11038    }
11039
11040    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11041            IBinder token, int userId) {
11042        return getContentProviderImpl(null, name, token, true, userId);
11043    }
11044
11045    /**
11046     * Drop a content provider from a ProcessRecord's bookkeeping
11047     */
11048    public void removeContentProvider(IBinder connection, boolean stable) {
11049        enforceNotIsolatedCaller("removeContentProvider");
11050        long ident = Binder.clearCallingIdentity();
11051        try {
11052            synchronized (this) {
11053                ContentProviderConnection conn;
11054                try {
11055                    conn = (ContentProviderConnection)connection;
11056                } catch (ClassCastException e) {
11057                    String msg ="removeContentProvider: " + connection
11058                            + " not a ContentProviderConnection";
11059                    Slog.w(TAG, msg);
11060                    throw new IllegalArgumentException(msg);
11061                }
11062                if (conn == null) {
11063                    throw new NullPointerException("connection is null");
11064                }
11065                if (decProviderCountLocked(conn, null, null, stable)) {
11066                    updateOomAdjLocked();
11067                }
11068            }
11069        } finally {
11070            Binder.restoreCallingIdentity(ident);
11071        }
11072    }
11073
11074    public void removeContentProviderExternal(String name, IBinder token) {
11075        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11076            "Do not have permission in call removeContentProviderExternal()");
11077        int userId = UserHandle.getCallingUserId();
11078        long ident = Binder.clearCallingIdentity();
11079        try {
11080            removeContentProviderExternalUnchecked(name, token, userId);
11081        } finally {
11082            Binder.restoreCallingIdentity(ident);
11083        }
11084    }
11085
11086    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11087        synchronized (this) {
11088            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11089            if(cpr == null) {
11090                //remove from mProvidersByClass
11091                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11092                return;
11093            }
11094
11095            //update content provider record entry info
11096            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11097            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11098            if (localCpr.hasExternalProcessHandles()) {
11099                if (localCpr.removeExternalProcessHandleLocked(token)) {
11100                    updateOomAdjLocked();
11101                } else {
11102                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11103                            + " with no external reference for token: "
11104                            + token + ".");
11105                }
11106            } else {
11107                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11108                        + " with no external references.");
11109            }
11110        }
11111    }
11112
11113    public final void publishContentProviders(IApplicationThread caller,
11114            List<ContentProviderHolder> providers) {
11115        if (providers == null) {
11116            return;
11117        }
11118
11119        enforceNotIsolatedCaller("publishContentProviders");
11120        synchronized (this) {
11121            final ProcessRecord r = getRecordForAppLocked(caller);
11122            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11123            if (r == null) {
11124                throw new SecurityException(
11125                        "Unable to find app for caller " + caller
11126                      + " (pid=" + Binder.getCallingPid()
11127                      + ") when publishing content providers");
11128            }
11129
11130            final long origId = Binder.clearCallingIdentity();
11131
11132            final int N = providers.size();
11133            for (int i = 0; i < N; i++) {
11134                ContentProviderHolder src = providers.get(i);
11135                if (src == null || src.info == null || src.provider == null) {
11136                    continue;
11137                }
11138                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11139                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11140                if (dst != null) {
11141                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11142                    mProviderMap.putProviderByClass(comp, dst);
11143                    String names[] = dst.info.authority.split(";");
11144                    for (int j = 0; j < names.length; j++) {
11145                        mProviderMap.putProviderByName(names[j], dst);
11146                    }
11147
11148                    int launchingCount = mLaunchingProviders.size();
11149                    int j;
11150                    boolean wasInLaunchingProviders = false;
11151                    for (j = 0; j < launchingCount; j++) {
11152                        if (mLaunchingProviders.get(j) == dst) {
11153                            mLaunchingProviders.remove(j);
11154                            wasInLaunchingProviders = true;
11155                            j--;
11156                            launchingCount--;
11157                        }
11158                    }
11159                    if (wasInLaunchingProviders) {
11160                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11161                    }
11162                    synchronized (dst) {
11163                        dst.provider = src.provider;
11164                        dst.proc = r;
11165                        dst.notifyAll();
11166                    }
11167                    updateOomAdjLocked(r);
11168                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11169                            src.info.authority);
11170                }
11171            }
11172
11173            Binder.restoreCallingIdentity(origId);
11174        }
11175    }
11176
11177    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11178        ContentProviderConnection conn;
11179        try {
11180            conn = (ContentProviderConnection)connection;
11181        } catch (ClassCastException e) {
11182            String msg ="refContentProvider: " + connection
11183                    + " not a ContentProviderConnection";
11184            Slog.w(TAG, msg);
11185            throw new IllegalArgumentException(msg);
11186        }
11187        if (conn == null) {
11188            throw new NullPointerException("connection is null");
11189        }
11190
11191        synchronized (this) {
11192            if (stable > 0) {
11193                conn.numStableIncs += stable;
11194            }
11195            stable = conn.stableCount + stable;
11196            if (stable < 0) {
11197                throw new IllegalStateException("stableCount < 0: " + stable);
11198            }
11199
11200            if (unstable > 0) {
11201                conn.numUnstableIncs += unstable;
11202            }
11203            unstable = conn.unstableCount + unstable;
11204            if (unstable < 0) {
11205                throw new IllegalStateException("unstableCount < 0: " + unstable);
11206            }
11207
11208            if ((stable+unstable) <= 0) {
11209                throw new IllegalStateException("ref counts can't go to zero here: stable="
11210                        + stable + " unstable=" + unstable);
11211            }
11212            conn.stableCount = stable;
11213            conn.unstableCount = unstable;
11214            return !conn.dead;
11215        }
11216    }
11217
11218    public void unstableProviderDied(IBinder connection) {
11219        ContentProviderConnection conn;
11220        try {
11221            conn = (ContentProviderConnection)connection;
11222        } catch (ClassCastException e) {
11223            String msg ="refContentProvider: " + connection
11224                    + " not a ContentProviderConnection";
11225            Slog.w(TAG, msg);
11226            throw new IllegalArgumentException(msg);
11227        }
11228        if (conn == null) {
11229            throw new NullPointerException("connection is null");
11230        }
11231
11232        // Safely retrieve the content provider associated with the connection.
11233        IContentProvider provider;
11234        synchronized (this) {
11235            provider = conn.provider.provider;
11236        }
11237
11238        if (provider == null) {
11239            // Um, yeah, we're way ahead of you.
11240            return;
11241        }
11242
11243        // Make sure the caller is being honest with us.
11244        if (provider.asBinder().pingBinder()) {
11245            // Er, no, still looks good to us.
11246            synchronized (this) {
11247                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11248                        + " says " + conn + " died, but we don't agree");
11249                return;
11250            }
11251        }
11252
11253        // Well look at that!  It's dead!
11254        synchronized (this) {
11255            if (conn.provider.provider != provider) {
11256                // But something changed...  good enough.
11257                return;
11258            }
11259
11260            ProcessRecord proc = conn.provider.proc;
11261            if (proc == null || proc.thread == null) {
11262                // Seems like the process is already cleaned up.
11263                return;
11264            }
11265
11266            // As far as we're concerned, this is just like receiving a
11267            // death notification...  just a bit prematurely.
11268            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11269                    + ") early provider death");
11270            final long ident = Binder.clearCallingIdentity();
11271            try {
11272                appDiedLocked(proc);
11273            } finally {
11274                Binder.restoreCallingIdentity(ident);
11275            }
11276        }
11277    }
11278
11279    @Override
11280    public void appNotRespondingViaProvider(IBinder connection) {
11281        enforceCallingPermission(
11282                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11283
11284        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11285        if (conn == null) {
11286            Slog.w(TAG, "ContentProviderConnection is null");
11287            return;
11288        }
11289
11290        final ProcessRecord host = conn.provider.proc;
11291        if (host == null) {
11292            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11293            return;
11294        }
11295
11296        mHandler.post(new Runnable() {
11297            @Override
11298            public void run() {
11299                mAppErrors.appNotResponding(host, null, null, false,
11300                        "ContentProvider not responding");
11301            }
11302        });
11303    }
11304
11305    public final void installSystemProviders() {
11306        List<ProviderInfo> providers;
11307        synchronized (this) {
11308            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11309            providers = generateApplicationProvidersLocked(app);
11310            if (providers != null) {
11311                for (int i=providers.size()-1; i>=0; i--) {
11312                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11313                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11314                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11315                                + ": not system .apk");
11316                        providers.remove(i);
11317                    }
11318                }
11319            }
11320        }
11321        if (providers != null) {
11322            mSystemThread.installSystemProviders(providers);
11323        }
11324
11325        mCoreSettingsObserver = new CoreSettingsObserver(this);
11326        mFontScaleSettingObserver = new FontScaleSettingObserver();
11327
11328        //mUsageStatsService.monitorPackages();
11329    }
11330
11331    private void startPersistentApps(int matchFlags) {
11332        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11333
11334        synchronized (this) {
11335            try {
11336                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11337                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11338                for (ApplicationInfo app : apps) {
11339                    if (!"android".equals(app.packageName)) {
11340                        addAppLocked(app, false, null /* ABI override */);
11341                    }
11342                }
11343            } catch (RemoteException ex) {
11344            }
11345        }
11346    }
11347
11348    /**
11349     * When a user is unlocked, we need to install encryption-unaware providers
11350     * belonging to any running apps.
11351     */
11352    private void installEncryptionUnawareProviders(int userId) {
11353        // We're only interested in providers that are encryption unaware, and
11354        // we don't care about uninstalled apps, since there's no way they're
11355        // running at this point.
11356        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11357
11358        synchronized (this) {
11359            final int NP = mProcessNames.getMap().size();
11360            for (int ip = 0; ip < NP; ip++) {
11361                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11362                final int NA = apps.size();
11363                for (int ia = 0; ia < NA; ia++) {
11364                    final ProcessRecord app = apps.valueAt(ia);
11365                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11366
11367                    final int NG = app.pkgList.size();
11368                    for (int ig = 0; ig < NG; ig++) {
11369                        try {
11370                            final String pkgName = app.pkgList.keyAt(ig);
11371                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11372                                    .getPackageInfo(pkgName, matchFlags, userId);
11373                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11374                                for (ProviderInfo pi : pkgInfo.providers) {
11375                                    // TODO: keep in sync with generateApplicationProvidersLocked
11376                                    final boolean processMatch = Objects.equals(pi.processName,
11377                                            app.processName) || pi.multiprocess;
11378                                    final boolean userMatch = isSingleton(pi.processName,
11379                                            pi.applicationInfo, pi.name, pi.flags)
11380                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11381                                    if (processMatch && userMatch) {
11382                                        Log.v(TAG, "Installing " + pi);
11383                                        app.thread.scheduleInstallProvider(pi);
11384                                    } else {
11385                                        Log.v(TAG, "Skipping " + pi);
11386                                    }
11387                                }
11388                            }
11389                        } catch (RemoteException ignored) {
11390                        }
11391                    }
11392                }
11393            }
11394        }
11395    }
11396
11397    /**
11398     * Allows apps to retrieve the MIME type of a URI.
11399     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11400     * users, then it does not need permission to access the ContentProvider.
11401     * Either, it needs cross-user uri grants.
11402     *
11403     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11404     *
11405     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11406     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11407     */
11408    public String getProviderMimeType(Uri uri, int userId) {
11409        enforceNotIsolatedCaller("getProviderMimeType");
11410        final String name = uri.getAuthority();
11411        int callingUid = Binder.getCallingUid();
11412        int callingPid = Binder.getCallingPid();
11413        long ident = 0;
11414        boolean clearedIdentity = false;
11415        synchronized (this) {
11416            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11417        }
11418        if (canClearIdentity(callingPid, callingUid, userId)) {
11419            clearedIdentity = true;
11420            ident = Binder.clearCallingIdentity();
11421        }
11422        ContentProviderHolder holder = null;
11423        try {
11424            holder = getContentProviderExternalUnchecked(name, null, userId);
11425            if (holder != null) {
11426                return holder.provider.getType(uri);
11427            }
11428        } catch (RemoteException e) {
11429            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11430            return null;
11431        } catch (Exception e) {
11432            Log.w(TAG, "Exception while determining type of " + uri, e);
11433            return null;
11434        } finally {
11435            // We need to clear the identity to call removeContentProviderExternalUnchecked
11436            if (!clearedIdentity) {
11437                ident = Binder.clearCallingIdentity();
11438            }
11439            try {
11440                if (holder != null) {
11441                    removeContentProviderExternalUnchecked(name, null, userId);
11442                }
11443            } finally {
11444                Binder.restoreCallingIdentity(ident);
11445            }
11446        }
11447
11448        return null;
11449    }
11450
11451    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11452        if (UserHandle.getUserId(callingUid) == userId) {
11453            return true;
11454        }
11455        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11456                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11457                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11458                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11459                return true;
11460        }
11461        return false;
11462    }
11463
11464    // =========================================================
11465    // GLOBAL MANAGEMENT
11466    // =========================================================
11467
11468    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11469            boolean isolated, int isolatedUid) {
11470        String proc = customProcess != null ? customProcess : info.processName;
11471        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11472        final int userId = UserHandle.getUserId(info.uid);
11473        int uid = info.uid;
11474        if (isolated) {
11475            if (isolatedUid == 0) {
11476                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11477                while (true) {
11478                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11479                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11480                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11481                    }
11482                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11483                    mNextIsolatedProcessUid++;
11484                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11485                        // No process for this uid, use it.
11486                        break;
11487                    }
11488                    stepsLeft--;
11489                    if (stepsLeft <= 0) {
11490                        return null;
11491                    }
11492                }
11493            } else {
11494                // Special case for startIsolatedProcess (internal only), where
11495                // the uid of the isolated process is specified by the caller.
11496                uid = isolatedUid;
11497            }
11498
11499            // Register the isolated UID with this application so BatteryStats knows to
11500            // attribute resource usage to the application.
11501            //
11502            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11503            // about the process state of the isolated UID *before* it is registered with the
11504            // owning application.
11505            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11506        }
11507        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11508        if (!mBooted && !mBooting
11509                && userId == UserHandle.USER_SYSTEM
11510                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11511            r.persistent = true;
11512            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11513        }
11514        addProcessNameLocked(r);
11515        return r;
11516    }
11517
11518    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11519            String abiOverride) {
11520        ProcessRecord app;
11521        if (!isolated) {
11522            app = getProcessRecordLocked(info.processName, info.uid, true);
11523        } else {
11524            app = null;
11525        }
11526
11527        if (app == null) {
11528            app = newProcessRecordLocked(info, null, isolated, 0);
11529            updateLruProcessLocked(app, false, null);
11530            updateOomAdjLocked();
11531        }
11532
11533        // This package really, really can not be stopped.
11534        try {
11535            AppGlobals.getPackageManager().setPackageStoppedState(
11536                    info.packageName, false, UserHandle.getUserId(app.uid));
11537        } catch (RemoteException e) {
11538        } catch (IllegalArgumentException e) {
11539            Slog.w(TAG, "Failed trying to unstop package "
11540                    + info.packageName + ": " + e);
11541        }
11542
11543        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11544            app.persistent = true;
11545            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11546        }
11547        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11548            mPersistentStartingProcesses.add(app);
11549            startProcessLocked(app, "added application", app.processName, abiOverride,
11550                    null /* entryPoint */, null /* entryPointArgs */);
11551        }
11552
11553        return app;
11554    }
11555
11556    public void unhandledBack() {
11557        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11558                "unhandledBack()");
11559
11560        synchronized(this) {
11561            final long origId = Binder.clearCallingIdentity();
11562            try {
11563                getFocusedStack().unhandledBackLocked();
11564            } finally {
11565                Binder.restoreCallingIdentity(origId);
11566            }
11567        }
11568    }
11569
11570    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11571        enforceNotIsolatedCaller("openContentUri");
11572        final int userId = UserHandle.getCallingUserId();
11573        String name = uri.getAuthority();
11574        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11575        ParcelFileDescriptor pfd = null;
11576        if (cph != null) {
11577            // We record the binder invoker's uid in thread-local storage before
11578            // going to the content provider to open the file.  Later, in the code
11579            // that handles all permissions checks, we look for this uid and use
11580            // that rather than the Activity Manager's own uid.  The effect is that
11581            // we do the check against the caller's permissions even though it looks
11582            // to the content provider like the Activity Manager itself is making
11583            // the request.
11584            Binder token = new Binder();
11585            sCallerIdentity.set(new Identity(
11586                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11587            try {
11588                pfd = cph.provider.openFile(null, uri, "r", null, token);
11589            } catch (FileNotFoundException e) {
11590                // do nothing; pfd will be returned null
11591            } finally {
11592                // Ensure that whatever happens, we clean up the identity state
11593                sCallerIdentity.remove();
11594                // Ensure we're done with the provider.
11595                removeContentProviderExternalUnchecked(name, null, userId);
11596            }
11597        } else {
11598            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11599        }
11600        return pfd;
11601    }
11602
11603    // Actually is sleeping or shutting down or whatever else in the future
11604    // is an inactive state.
11605    boolean isSleepingOrShuttingDownLocked() {
11606        return isSleepingLocked() || mShuttingDown;
11607    }
11608
11609    boolean isShuttingDownLocked() {
11610        return mShuttingDown;
11611    }
11612
11613    boolean isSleepingLocked() {
11614        return mSleeping;
11615    }
11616
11617    void onWakefulnessChanged(int wakefulness) {
11618        synchronized(this) {
11619            mWakefulness = wakefulness;
11620            updateSleepIfNeededLocked();
11621        }
11622    }
11623
11624    void finishRunningVoiceLocked() {
11625        if (mRunningVoice != null) {
11626            mRunningVoice = null;
11627            mVoiceWakeLock.release();
11628            updateSleepIfNeededLocked();
11629        }
11630    }
11631
11632    void startTimeTrackingFocusedActivityLocked() {
11633        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11634            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11635        }
11636    }
11637
11638    void updateSleepIfNeededLocked() {
11639        if (mSleeping && !shouldSleepLocked()) {
11640            mSleeping = false;
11641            startTimeTrackingFocusedActivityLocked();
11642            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11643            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11644            updateOomAdjLocked();
11645        } else if (!mSleeping && shouldSleepLocked()) {
11646            mSleeping = true;
11647            if (mCurAppTimeTracker != null) {
11648                mCurAppTimeTracker.stop();
11649            }
11650            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11651            mStackSupervisor.goingToSleepLocked();
11652            updateOomAdjLocked();
11653
11654            // Initialize the wake times of all processes.
11655            checkExcessivePowerUsageLocked(false);
11656            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11657            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11658            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11659        }
11660    }
11661
11662    private boolean shouldSleepLocked() {
11663        // Resume applications while running a voice interactor.
11664        if (mRunningVoice != null) {
11665            return false;
11666        }
11667
11668        // TODO: Transform the lock screen state into a sleep token instead.
11669        switch (mWakefulness) {
11670            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11671            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11672            case PowerManagerInternal.WAKEFULNESS_DOZING:
11673                // Pause applications whenever the lock screen is shown or any sleep
11674                // tokens have been acquired.
11675                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11676            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11677            default:
11678                // If we're asleep then pause applications unconditionally.
11679                return true;
11680        }
11681    }
11682
11683    /** Pokes the task persister. */
11684    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11685        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11686    }
11687
11688    /** Notifies all listeners when the task stack has changed. */
11689    void notifyTaskStackChangedLocked() {
11690        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11691        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11692        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11693        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11694    }
11695
11696    /** Notifies all listeners when an Activity is pinned. */
11697    void notifyActivityPinnedLocked() {
11698        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11699        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11700    }
11701
11702    /**
11703     * Notifies all listeners when an attempt was made to start an an activity that is already
11704     * running in the pinned stack and the activity was not actually started, but the task is
11705     * either brought to the front or a new Intent is delivered to it.
11706     */
11707    void notifyPinnedActivityRestartAttemptLocked() {
11708        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11709        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11710    }
11711
11712    /** Notifies all listeners when the pinned stack animation ends. */
11713    @Override
11714    public void notifyPinnedStackAnimationEnded() {
11715        synchronized (this) {
11716            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11717            mHandler.obtainMessage(
11718                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11719        }
11720    }
11721
11722    @Override
11723    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11724        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11725    }
11726
11727    @Override
11728    public boolean shutdown(int timeout) {
11729        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11730                != PackageManager.PERMISSION_GRANTED) {
11731            throw new SecurityException("Requires permission "
11732                    + android.Manifest.permission.SHUTDOWN);
11733        }
11734
11735        boolean timedout = false;
11736
11737        synchronized(this) {
11738            mShuttingDown = true;
11739            updateEventDispatchingLocked();
11740            timedout = mStackSupervisor.shutdownLocked(timeout);
11741        }
11742
11743        mAppOpsService.shutdown();
11744        if (mUsageStatsService != null) {
11745            mUsageStatsService.prepareShutdown();
11746        }
11747        mBatteryStatsService.shutdown();
11748        synchronized (this) {
11749            mProcessStats.shutdownLocked();
11750            notifyTaskPersisterLocked(null, true);
11751        }
11752
11753        return timedout;
11754    }
11755
11756    public final void activitySlept(IBinder token) {
11757        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11758
11759        final long origId = Binder.clearCallingIdentity();
11760
11761        synchronized (this) {
11762            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11763            if (r != null) {
11764                mStackSupervisor.activitySleptLocked(r);
11765            }
11766        }
11767
11768        Binder.restoreCallingIdentity(origId);
11769    }
11770
11771    private String lockScreenShownToString() {
11772        switch (mLockScreenShown) {
11773            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11774            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11775            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11776            default: return "Unknown=" + mLockScreenShown;
11777        }
11778    }
11779
11780    void logLockScreen(String msg) {
11781        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11782                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11783                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11784                + " mSleeping=" + mSleeping);
11785    }
11786
11787    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11788        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11789        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11790        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11791            boolean wasRunningVoice = mRunningVoice != null;
11792            mRunningVoice = session;
11793            if (!wasRunningVoice) {
11794                mVoiceWakeLock.acquire();
11795                updateSleepIfNeededLocked();
11796            }
11797        }
11798    }
11799
11800    private void updateEventDispatchingLocked() {
11801        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11802    }
11803
11804    public void setLockScreenShown(boolean showing, boolean occluded) {
11805        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11806                != PackageManager.PERMISSION_GRANTED) {
11807            throw new SecurityException("Requires permission "
11808                    + android.Manifest.permission.DEVICE_POWER);
11809        }
11810
11811        synchronized(this) {
11812            long ident = Binder.clearCallingIdentity();
11813            try {
11814                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11815                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11816                if (showing && occluded) {
11817                    // The lock screen is currently showing, but is occluded by a window that can
11818                    // show on top of the lock screen. In this can we want to dismiss the docked
11819                    // stack since it will be complicated/risky to try to put the activity on top
11820                    // of the lock screen in the right fullscreen configuration.
11821                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11822                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11823                }
11824
11825                updateSleepIfNeededLocked();
11826            } finally {
11827                Binder.restoreCallingIdentity(ident);
11828            }
11829        }
11830    }
11831
11832    @Override
11833    public void notifyLockedProfile(@UserIdInt int userId) {
11834        try {
11835            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11836                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11837            }
11838        } catch (RemoteException ex) {
11839            throw new SecurityException("Fail to check is caller a privileged app", ex);
11840        }
11841
11842        synchronized (this) {
11843            if (mStackSupervisor.isUserLockedProfile(userId)) {
11844                final long ident = Binder.clearCallingIdentity();
11845                try {
11846                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11847
11848                    // Drop locked freeform tasks out into the fullscreen stack.
11849                    // TODO: Redact the tasks in place. It's much better to keep them on the screen
11850                    //       where they were before, but in an obscured state.
11851                    mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11852
11853                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11854                        // If there is no device lock, we will show the profile's credential page.
11855                        mActivityStarter.showConfirmDeviceCredential(userId);
11856                    } else {
11857                        // Showing launcher to avoid user entering credential twice.
11858                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11859                    }
11860                } finally {
11861                    Binder.restoreCallingIdentity(ident);
11862                }
11863            }
11864        }
11865    }
11866
11867    @Override
11868    public void startConfirmDeviceCredentialIntent(Intent intent) {
11869        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11870        synchronized (this) {
11871            final long ident = Binder.clearCallingIdentity();
11872            try {
11873                mActivityStarter.startConfirmCredentialIntent(intent);
11874            } finally {
11875                Binder.restoreCallingIdentity(ident);
11876            }
11877        }
11878    }
11879
11880    @Override
11881    public void stopAppSwitches() {
11882        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11883                != PackageManager.PERMISSION_GRANTED) {
11884            throw new SecurityException("viewquires permission "
11885                    + android.Manifest.permission.STOP_APP_SWITCHES);
11886        }
11887
11888        synchronized(this) {
11889            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11890                    + APP_SWITCH_DELAY_TIME;
11891            mDidAppSwitch = false;
11892            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11893            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11894            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11895        }
11896    }
11897
11898    public void resumeAppSwitches() {
11899        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11900                != PackageManager.PERMISSION_GRANTED) {
11901            throw new SecurityException("Requires permission "
11902                    + android.Manifest.permission.STOP_APP_SWITCHES);
11903        }
11904
11905        synchronized(this) {
11906            // Note that we don't execute any pending app switches... we will
11907            // let those wait until either the timeout, or the next start
11908            // activity request.
11909            mAppSwitchesAllowedTime = 0;
11910        }
11911    }
11912
11913    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11914            int callingPid, int callingUid, String name) {
11915        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11916            return true;
11917        }
11918
11919        int perm = checkComponentPermission(
11920                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11921                sourceUid, -1, true);
11922        if (perm == PackageManager.PERMISSION_GRANTED) {
11923            return true;
11924        }
11925
11926        // If the actual IPC caller is different from the logical source, then
11927        // also see if they are allowed to control app switches.
11928        if (callingUid != -1 && callingUid != sourceUid) {
11929            perm = checkComponentPermission(
11930                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11931                    callingUid, -1, true);
11932            if (perm == PackageManager.PERMISSION_GRANTED) {
11933                return true;
11934            }
11935        }
11936
11937        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11938        return false;
11939    }
11940
11941    public void setDebugApp(String packageName, boolean waitForDebugger,
11942            boolean persistent) {
11943        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11944                "setDebugApp()");
11945
11946        long ident = Binder.clearCallingIdentity();
11947        try {
11948            // Note that this is not really thread safe if there are multiple
11949            // callers into it at the same time, but that's not a situation we
11950            // care about.
11951            if (persistent) {
11952                final ContentResolver resolver = mContext.getContentResolver();
11953                Settings.Global.putString(
11954                    resolver, Settings.Global.DEBUG_APP,
11955                    packageName);
11956                Settings.Global.putInt(
11957                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11958                    waitForDebugger ? 1 : 0);
11959            }
11960
11961            synchronized (this) {
11962                if (!persistent) {
11963                    mOrigDebugApp = mDebugApp;
11964                    mOrigWaitForDebugger = mWaitForDebugger;
11965                }
11966                mDebugApp = packageName;
11967                mWaitForDebugger = waitForDebugger;
11968                mDebugTransient = !persistent;
11969                if (packageName != null) {
11970                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11971                            false, UserHandle.USER_ALL, "set debug app");
11972                }
11973            }
11974        } finally {
11975            Binder.restoreCallingIdentity(ident);
11976        }
11977    }
11978
11979    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11980        synchronized (this) {
11981            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11982            if (!isDebuggable) {
11983                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11984                    throw new SecurityException("Process not debuggable: " + app.packageName);
11985                }
11986            }
11987
11988            mTrackAllocationApp = processName;
11989        }
11990    }
11991
11992    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11993        synchronized (this) {
11994            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11995            if (!isDebuggable) {
11996                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11997                    throw new SecurityException("Process not debuggable: " + app.packageName);
11998                }
11999            }
12000            mProfileApp = processName;
12001            mProfileFile = profilerInfo.profileFile;
12002            if (mProfileFd != null) {
12003                try {
12004                    mProfileFd.close();
12005                } catch (IOException e) {
12006                }
12007                mProfileFd = null;
12008            }
12009            mProfileFd = profilerInfo.profileFd;
12010            mSamplingInterval = profilerInfo.samplingInterval;
12011            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12012            mProfileType = 0;
12013        }
12014    }
12015
12016    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12017        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12018        if (!isDebuggable) {
12019            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12020                throw new SecurityException("Process not debuggable: " + app.packageName);
12021            }
12022        }
12023        mNativeDebuggingApp = processName;
12024    }
12025
12026    @Override
12027    public void setAlwaysFinish(boolean enabled) {
12028        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12029                "setAlwaysFinish()");
12030
12031        long ident = Binder.clearCallingIdentity();
12032        try {
12033            Settings.Global.putInt(
12034                    mContext.getContentResolver(),
12035                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12036
12037            synchronized (this) {
12038                mAlwaysFinishActivities = enabled;
12039            }
12040        } finally {
12041            Binder.restoreCallingIdentity(ident);
12042        }
12043    }
12044
12045    @Override
12046    public void setLenientBackgroundCheck(boolean enabled) {
12047        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12048                "setLenientBackgroundCheck()");
12049
12050        long ident = Binder.clearCallingIdentity();
12051        try {
12052            Settings.Global.putInt(
12053                    mContext.getContentResolver(),
12054                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12055
12056            synchronized (this) {
12057                mLenientBackgroundCheck = enabled;
12058            }
12059        } finally {
12060            Binder.restoreCallingIdentity(ident);
12061        }
12062    }
12063
12064    @Override
12065    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12066        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12067                "setActivityController()");
12068        synchronized (this) {
12069            mController = controller;
12070            mControllerIsAMonkey = imAMonkey;
12071            Watchdog.getInstance().setActivityController(controller);
12072        }
12073    }
12074
12075    @Override
12076    public void setUserIsMonkey(boolean userIsMonkey) {
12077        synchronized (this) {
12078            synchronized (mPidsSelfLocked) {
12079                final int callingPid = Binder.getCallingPid();
12080                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12081                if (precessRecord == null) {
12082                    throw new SecurityException("Unknown process: " + callingPid);
12083                }
12084                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12085                    throw new SecurityException("Only an instrumentation process "
12086                            + "with a UiAutomation can call setUserIsMonkey");
12087                }
12088            }
12089            mUserIsMonkey = userIsMonkey;
12090        }
12091    }
12092
12093    @Override
12094    public boolean isUserAMonkey() {
12095        synchronized (this) {
12096            // If there is a controller also implies the user is a monkey.
12097            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12098        }
12099    }
12100
12101    public void requestBugReport(int bugreportType) {
12102        String service = null;
12103        switch (bugreportType) {
12104            case ActivityManager.BUGREPORT_OPTION_FULL:
12105                service = "bugreport";
12106                break;
12107            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12108                service = "bugreportplus";
12109                break;
12110            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12111                service = "bugreportremote";
12112                break;
12113            case ActivityManager.BUGREPORT_OPTION_WEAR:
12114                service = "bugreportwear";
12115                break;
12116        }
12117        if (service == null) {
12118            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12119                    + bugreportType);
12120        }
12121        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12122        SystemProperties.set("ctl.start", service);
12123    }
12124
12125    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12126        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12127    }
12128
12129    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12130        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12131            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12132        }
12133        return KEY_DISPATCHING_TIMEOUT;
12134    }
12135
12136    @Override
12137    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12138        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12139                != PackageManager.PERMISSION_GRANTED) {
12140            throw new SecurityException("Requires permission "
12141                    + android.Manifest.permission.FILTER_EVENTS);
12142        }
12143        ProcessRecord proc;
12144        long timeout;
12145        synchronized (this) {
12146            synchronized (mPidsSelfLocked) {
12147                proc = mPidsSelfLocked.get(pid);
12148            }
12149            timeout = getInputDispatchingTimeoutLocked(proc);
12150        }
12151
12152        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12153            return -1;
12154        }
12155
12156        return timeout;
12157    }
12158
12159    /**
12160     * Handle input dispatching timeouts.
12161     * Returns whether input dispatching should be aborted or not.
12162     */
12163    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12164            final ActivityRecord activity, final ActivityRecord parent,
12165            final boolean aboveSystem, String reason) {
12166        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12167                != PackageManager.PERMISSION_GRANTED) {
12168            throw new SecurityException("Requires permission "
12169                    + android.Manifest.permission.FILTER_EVENTS);
12170        }
12171
12172        final String annotation;
12173        if (reason == null) {
12174            annotation = "Input dispatching timed out";
12175        } else {
12176            annotation = "Input dispatching timed out (" + reason + ")";
12177        }
12178
12179        if (proc != null) {
12180            synchronized (this) {
12181                if (proc.debugging) {
12182                    return false;
12183                }
12184
12185                if (mDidDexOpt) {
12186                    // Give more time since we were dexopting.
12187                    mDidDexOpt = false;
12188                    return false;
12189                }
12190
12191                if (proc.instrumentationClass != null) {
12192                    Bundle info = new Bundle();
12193                    info.putString("shortMsg", "keyDispatchingTimedOut");
12194                    info.putString("longMsg", annotation);
12195                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12196                    return true;
12197                }
12198            }
12199            mHandler.post(new Runnable() {
12200                @Override
12201                public void run() {
12202                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12203                }
12204            });
12205        }
12206
12207        return true;
12208    }
12209
12210    @Override
12211    public Bundle getAssistContextExtras(int requestType) {
12212        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12213                null, null, true /* focused */, true /* newSessionId */,
12214                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12215        if (pae == null) {
12216            return null;
12217        }
12218        synchronized (pae) {
12219            while (!pae.haveResult) {
12220                try {
12221                    pae.wait();
12222                } catch (InterruptedException e) {
12223                }
12224            }
12225        }
12226        synchronized (this) {
12227            buildAssistBundleLocked(pae, pae.result);
12228            mPendingAssistExtras.remove(pae);
12229            mUiHandler.removeCallbacks(pae);
12230        }
12231        return pae.extras;
12232    }
12233
12234    @Override
12235    public boolean isAssistDataAllowedOnCurrentActivity() {
12236        int userId;
12237        synchronized (this) {
12238            userId = mUserController.getCurrentUserIdLocked();
12239            ActivityRecord activity = getFocusedStack().topActivity();
12240            if (activity == null) {
12241                return false;
12242            }
12243            userId = activity.userId;
12244        }
12245        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12246                Context.DEVICE_POLICY_SERVICE);
12247        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12248    }
12249
12250    @Override
12251    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12252        long ident = Binder.clearCallingIdentity();
12253        try {
12254            synchronized (this) {
12255                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12256                ActivityRecord top = getFocusedStack().topActivity();
12257                if (top != caller) {
12258                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12259                            + " is not current top " + top);
12260                    return false;
12261                }
12262                if (!top.nowVisible) {
12263                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12264                            + " is not visible");
12265                    return false;
12266                }
12267            }
12268            AssistUtils utils = new AssistUtils(mContext);
12269            return utils.showSessionForActiveService(args,
12270                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12271        } finally {
12272            Binder.restoreCallingIdentity(ident);
12273        }
12274    }
12275
12276    @Override
12277    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12278            Bundle receiverExtras,
12279            IBinder activityToken, boolean focused, boolean newSessionId) {
12280        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12281                activityToken, focused, newSessionId,
12282                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12283                != null;
12284    }
12285
12286    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12287            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12288            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12289        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12290                "enqueueAssistContext()");
12291        synchronized (this) {
12292            ActivityRecord activity = getFocusedStack().topActivity();
12293            if (activity == null) {
12294                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12295                return null;
12296            }
12297            if (activity.app == null || activity.app.thread == null) {
12298                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12299                return null;
12300            }
12301            if (focused) {
12302                if (activityToken != null) {
12303                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12304                    if (activity != caller) {
12305                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12306                                + " is not current top " + activity);
12307                        return null;
12308                    }
12309                }
12310            } else {
12311                activity = ActivityRecord.forTokenLocked(activityToken);
12312                if (activity == null) {
12313                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12314                            + " couldn't be found");
12315                    return null;
12316                }
12317            }
12318
12319            PendingAssistExtras pae;
12320            Bundle extras = new Bundle();
12321            if (args != null) {
12322                extras.putAll(args);
12323            }
12324            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12325            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12326            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12327                    userHandle);
12328            // Increment the sessionId if necessary
12329            if (newSessionId) {
12330                mViSessionId++;
12331            }
12332            try {
12333                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12334                        requestType, mViSessionId);
12335                mPendingAssistExtras.add(pae);
12336                mUiHandler.postDelayed(pae, timeout);
12337            } catch (RemoteException e) {
12338                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12339                return null;
12340            }
12341            return pae;
12342        }
12343    }
12344
12345    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12346        IResultReceiver receiver;
12347        synchronized (this) {
12348            mPendingAssistExtras.remove(pae);
12349            receiver = pae.receiver;
12350        }
12351        if (receiver != null) {
12352            // Caller wants result sent back to them.
12353            Bundle sendBundle = new Bundle();
12354            // At least return the receiver extras
12355            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12356                    pae.receiverExtras);
12357            try {
12358                pae.receiver.send(0, sendBundle);
12359            } catch (RemoteException e) {
12360            }
12361        }
12362    }
12363
12364    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12365        if (result != null) {
12366            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12367        }
12368        if (pae.hint != null) {
12369            pae.extras.putBoolean(pae.hint, true);
12370        }
12371    }
12372
12373    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12374            AssistContent content, Uri referrer) {
12375        PendingAssistExtras pae = (PendingAssistExtras)token;
12376        synchronized (pae) {
12377            pae.result = extras;
12378            pae.structure = structure;
12379            pae.content = content;
12380            if (referrer != null) {
12381                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12382            }
12383            pae.haveResult = true;
12384            pae.notifyAll();
12385            if (pae.intent == null && pae.receiver == null) {
12386                // Caller is just waiting for the result.
12387                return;
12388            }
12389        }
12390
12391        // We are now ready to launch the assist activity.
12392        IResultReceiver sendReceiver = null;
12393        Bundle sendBundle = null;
12394        synchronized (this) {
12395            buildAssistBundleLocked(pae, extras);
12396            boolean exists = mPendingAssistExtras.remove(pae);
12397            mUiHandler.removeCallbacks(pae);
12398            if (!exists) {
12399                // Timed out.
12400                return;
12401            }
12402            if ((sendReceiver=pae.receiver) != null) {
12403                // Caller wants result sent back to them.
12404                sendBundle = new Bundle();
12405                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12406                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12407                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12408                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12409                        pae.receiverExtras);
12410            }
12411        }
12412        if (sendReceiver != null) {
12413            try {
12414                sendReceiver.send(0, sendBundle);
12415            } catch (RemoteException e) {
12416            }
12417            return;
12418        }
12419
12420        long ident = Binder.clearCallingIdentity();
12421        try {
12422            pae.intent.replaceExtras(pae.extras);
12423            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12424                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12425                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12426            closeSystemDialogs("assist");
12427            try {
12428                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12429            } catch (ActivityNotFoundException e) {
12430                Slog.w(TAG, "No activity to handle assist action.", e);
12431            }
12432        } finally {
12433            Binder.restoreCallingIdentity(ident);
12434        }
12435    }
12436
12437    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12438            Bundle args) {
12439        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12440                true /* focused */, true /* newSessionId */,
12441                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12442    }
12443
12444    public void registerProcessObserver(IProcessObserver observer) {
12445        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12446                "registerProcessObserver()");
12447        synchronized (this) {
12448            mProcessObservers.register(observer);
12449        }
12450    }
12451
12452    @Override
12453    public void unregisterProcessObserver(IProcessObserver observer) {
12454        synchronized (this) {
12455            mProcessObservers.unregister(observer);
12456        }
12457    }
12458
12459    @Override
12460    public void registerUidObserver(IUidObserver observer, int which) {
12461        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12462                "registerUidObserver()");
12463        synchronized (this) {
12464            mUidObservers.register(observer, which);
12465        }
12466    }
12467
12468    @Override
12469    public void unregisterUidObserver(IUidObserver observer) {
12470        synchronized (this) {
12471            mUidObservers.unregister(observer);
12472        }
12473    }
12474
12475    @Override
12476    public boolean convertFromTranslucent(IBinder token) {
12477        final long origId = Binder.clearCallingIdentity();
12478        try {
12479            synchronized (this) {
12480                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12481                if (r == null) {
12482                    return false;
12483                }
12484                final boolean translucentChanged = r.changeWindowTranslucency(true);
12485                if (translucentChanged) {
12486                    r.task.stack.releaseBackgroundResources(r);
12487                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12488                }
12489                mWindowManager.setAppFullscreen(token, true);
12490                return translucentChanged;
12491            }
12492        } finally {
12493            Binder.restoreCallingIdentity(origId);
12494        }
12495    }
12496
12497    @Override
12498    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12499        final long origId = Binder.clearCallingIdentity();
12500        try {
12501            synchronized (this) {
12502                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12503                if (r == null) {
12504                    return false;
12505                }
12506                int index = r.task.mActivities.lastIndexOf(r);
12507                if (index > 0) {
12508                    ActivityRecord under = r.task.mActivities.get(index - 1);
12509                    under.returningOptions = options;
12510                }
12511                final boolean translucentChanged = r.changeWindowTranslucency(false);
12512                if (translucentChanged) {
12513                    r.task.stack.convertActivityToTranslucent(r);
12514                }
12515                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12516                mWindowManager.setAppFullscreen(token, false);
12517                return translucentChanged;
12518            }
12519        } finally {
12520            Binder.restoreCallingIdentity(origId);
12521        }
12522    }
12523
12524    @Override
12525    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12526        final long origId = Binder.clearCallingIdentity();
12527        try {
12528            synchronized (this) {
12529                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12530                if (r != null) {
12531                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12532                }
12533            }
12534            return false;
12535        } finally {
12536            Binder.restoreCallingIdentity(origId);
12537        }
12538    }
12539
12540    @Override
12541    public boolean isBackgroundVisibleBehind(IBinder token) {
12542        final long origId = Binder.clearCallingIdentity();
12543        try {
12544            synchronized (this) {
12545                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12546                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12547                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12548                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12549                return visible;
12550            }
12551        } finally {
12552            Binder.restoreCallingIdentity(origId);
12553        }
12554    }
12555
12556    @Override
12557    public ActivityOptions getActivityOptions(IBinder token) {
12558        final long origId = Binder.clearCallingIdentity();
12559        try {
12560            synchronized (this) {
12561                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12562                if (r != null) {
12563                    final ActivityOptions activityOptions = r.pendingOptions;
12564                    r.pendingOptions = null;
12565                    return activityOptions;
12566                }
12567                return null;
12568            }
12569        } finally {
12570            Binder.restoreCallingIdentity(origId);
12571        }
12572    }
12573
12574    @Override
12575    public void setImmersive(IBinder token, boolean immersive) {
12576        synchronized(this) {
12577            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12578            if (r == null) {
12579                throw new IllegalArgumentException();
12580            }
12581            r.immersive = immersive;
12582
12583            // update associated state if we're frontmost
12584            if (r == mFocusedActivity) {
12585                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12586                applyUpdateLockStateLocked(r);
12587            }
12588        }
12589    }
12590
12591    @Override
12592    public boolean isImmersive(IBinder token) {
12593        synchronized (this) {
12594            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12595            if (r == null) {
12596                throw new IllegalArgumentException();
12597            }
12598            return r.immersive;
12599        }
12600    }
12601
12602    public void setVrThread(int tid) {
12603        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12604            throw new UnsupportedOperationException("VR mode not supported on this device!");
12605        }
12606
12607        synchronized (this) {
12608            ProcessRecord proc;
12609            synchronized (mPidsSelfLocked) {
12610                final int pid = Binder.getCallingPid();
12611                proc = mPidsSelfLocked.get(pid);
12612
12613                if (proc != null && mInVrMode && tid >= 0) {
12614                    // ensure the tid belongs to the process
12615                    if (!Process.isThreadInProcess(pid, tid)) {
12616                        throw new IllegalArgumentException("VR thread does not belong to process");
12617                    }
12618
12619                    // reset existing VR thread to CFS if this thread still exists and belongs to
12620                    // the calling process
12621                    if (proc.vrThreadTid != 0
12622                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12623                        try {
12624                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12625                        } catch (IllegalArgumentException e) {
12626                            // Ignore this.  Only occurs in race condition where previous VR thread
12627                            // was destroyed during this method call.
12628                        }
12629                    }
12630
12631                    proc.vrThreadTid = tid;
12632
12633                    // promote to FIFO now if the tid is non-zero
12634                    try {
12635                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12636                            proc.vrThreadTid > 0) {
12637                            Process.setThreadScheduler(proc.vrThreadTid,
12638                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12639                        }
12640                    } catch (IllegalArgumentException e) {
12641                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12642                               + " not exist:\n" + e);
12643                    }
12644                }
12645            }
12646        }
12647    }
12648
12649    @Override
12650    public void setRenderThread(int tid) {
12651        synchronized (this) {
12652            ProcessRecord proc;
12653            synchronized (mPidsSelfLocked) {
12654                int pid = Binder.getCallingPid();
12655                proc = mPidsSelfLocked.get(pid);
12656                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12657                    // ensure the tid belongs to the process
12658                    if (!Process.isThreadInProcess(pid, tid)) {
12659                        throw new IllegalArgumentException(
12660                            "Render thread does not belong to process");
12661                    }
12662                    proc.renderThreadTid = tid;
12663                    if (DEBUG_OOM_ADJ) {
12664                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12665                    }
12666                    // promote to FIFO now
12667                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12668                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12669                        if (mUseFifoUiScheduling) {
12670                            Process.setThreadScheduler(proc.renderThreadTid,
12671                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12672                        } else {
12673                            Process.setThreadPriority(proc.renderThreadTid, -10);
12674                        }
12675                    }
12676                } else {
12677                    if (DEBUG_OOM_ADJ) {
12678                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12679                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12680                               mUseFifoUiScheduling);
12681                    }
12682                }
12683            }
12684        }
12685    }
12686
12687    @Override
12688    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12689        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12690            throw new UnsupportedOperationException("VR mode not supported on this device!");
12691        }
12692
12693        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12694
12695        ActivityRecord r;
12696        synchronized (this) {
12697            r = ActivityRecord.isInStackLocked(token);
12698        }
12699
12700        if (r == null) {
12701            throw new IllegalArgumentException();
12702        }
12703
12704        int err;
12705        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12706                VrManagerInternal.NO_ERROR) {
12707            return err;
12708        }
12709
12710        synchronized(this) {
12711            r.requestedVrComponent = (enabled) ? packageName : null;
12712
12713            // Update associated state if this activity is currently focused
12714            if (r == mFocusedActivity) {
12715                applyUpdateVrModeLocked(r);
12716            }
12717            return 0;
12718        }
12719    }
12720
12721    @Override
12722    public boolean isVrModePackageEnabled(ComponentName packageName) {
12723        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12724            throw new UnsupportedOperationException("VR mode not supported on this device!");
12725        }
12726
12727        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12728
12729        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12730                VrManagerInternal.NO_ERROR;
12731    }
12732
12733    public boolean isTopActivityImmersive() {
12734        enforceNotIsolatedCaller("startActivity");
12735        synchronized (this) {
12736            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12737            return (r != null) ? r.immersive : false;
12738        }
12739    }
12740
12741    @Override
12742    public boolean isTopOfTask(IBinder token) {
12743        synchronized (this) {
12744            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12745            if (r == null) {
12746                throw new IllegalArgumentException();
12747            }
12748            return r.task.getTopActivity() == r;
12749        }
12750    }
12751
12752    @Override
12753    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12754        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12755            String msg = "Permission Denial: setHasTopUi() from pid="
12756                    + Binder.getCallingPid()
12757                    + ", uid=" + Binder.getCallingUid()
12758                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12759            Slog.w(TAG, msg);
12760            throw new SecurityException(msg);
12761        }
12762        final int pid = Binder.getCallingPid();
12763        final long origId = Binder.clearCallingIdentity();
12764        try {
12765            synchronized (this) {
12766                boolean changed = false;
12767                ProcessRecord pr;
12768                synchronized (mPidsSelfLocked) {
12769                    pr = mPidsSelfLocked.get(pid);
12770                    if (pr == null) {
12771                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12772                        return;
12773                    }
12774                    if (pr.hasTopUi != hasTopUi) {
12775                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12776                        pr.hasTopUi = hasTopUi;
12777                        changed = true;
12778                    }
12779                }
12780                if (changed) {
12781                    updateOomAdjLocked(pr);
12782                }
12783            }
12784        } finally {
12785            Binder.restoreCallingIdentity(origId);
12786        }
12787    }
12788
12789    public final void enterSafeMode() {
12790        synchronized(this) {
12791            // It only makes sense to do this before the system is ready
12792            // and started launching other packages.
12793            if (!mSystemReady) {
12794                try {
12795                    AppGlobals.getPackageManager().enterSafeMode();
12796                } catch (RemoteException e) {
12797                }
12798            }
12799
12800            mSafeMode = true;
12801        }
12802    }
12803
12804    public final void showSafeModeOverlay() {
12805        View v = LayoutInflater.from(mContext).inflate(
12806                com.android.internal.R.layout.safe_mode, null);
12807        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12808        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12809        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12810        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12811        lp.gravity = Gravity.BOTTOM | Gravity.START;
12812        lp.format = v.getBackground().getOpacity();
12813        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12814                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12815        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12816        ((WindowManager)mContext.getSystemService(
12817                Context.WINDOW_SERVICE)).addView(v, lp);
12818    }
12819
12820    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12821        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12822            return;
12823        }
12824        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12825        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12826        synchronized (stats) {
12827            if (mBatteryStatsService.isOnBattery()) {
12828                mBatteryStatsService.enforceCallingPermission();
12829                int MY_UID = Binder.getCallingUid();
12830                final int uid;
12831                if (sender == null) {
12832                    uid = sourceUid;
12833                } else {
12834                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12835                }
12836                BatteryStatsImpl.Uid.Pkg pkg =
12837                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12838                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12839                pkg.noteWakeupAlarmLocked(tag);
12840            }
12841        }
12842    }
12843
12844    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12845        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12846            return;
12847        }
12848        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12849        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12850        synchronized (stats) {
12851            mBatteryStatsService.enforceCallingPermission();
12852            int MY_UID = Binder.getCallingUid();
12853            final int uid;
12854            if (sender == null) {
12855                uid = sourceUid;
12856            } else {
12857                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12858            }
12859            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12860        }
12861    }
12862
12863    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12864        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12865            return;
12866        }
12867        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12868        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12869        synchronized (stats) {
12870            mBatteryStatsService.enforceCallingPermission();
12871            int MY_UID = Binder.getCallingUid();
12872            final int uid;
12873            if (sender == null) {
12874                uid = sourceUid;
12875            } else {
12876                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12877            }
12878            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12879        }
12880    }
12881
12882    public boolean killPids(int[] pids, String pReason, boolean secure) {
12883        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12884            throw new SecurityException("killPids only available to the system");
12885        }
12886        String reason = (pReason == null) ? "Unknown" : pReason;
12887        // XXX Note: don't acquire main activity lock here, because the window
12888        // manager calls in with its locks held.
12889
12890        boolean killed = false;
12891        synchronized (mPidsSelfLocked) {
12892            int worstType = 0;
12893            for (int i=0; i<pids.length; i++) {
12894                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12895                if (proc != null) {
12896                    int type = proc.setAdj;
12897                    if (type > worstType) {
12898                        worstType = type;
12899                    }
12900                }
12901            }
12902
12903            // If the worst oom_adj is somewhere in the cached proc LRU range,
12904            // then constrain it so we will kill all cached procs.
12905            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12906                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12907                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12908            }
12909
12910            // If this is not a secure call, don't let it kill processes that
12911            // are important.
12912            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12913                worstType = ProcessList.SERVICE_ADJ;
12914            }
12915
12916            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12917            for (int i=0; i<pids.length; i++) {
12918                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12919                if (proc == null) {
12920                    continue;
12921                }
12922                int adj = proc.setAdj;
12923                if (adj >= worstType && !proc.killedByAm) {
12924                    proc.kill(reason, true);
12925                    killed = true;
12926                }
12927            }
12928        }
12929        return killed;
12930    }
12931
12932    @Override
12933    public void killUid(int appId, int userId, String reason) {
12934        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12935        synchronized (this) {
12936            final long identity = Binder.clearCallingIdentity();
12937            try {
12938                killPackageProcessesLocked(null, appId, userId,
12939                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12940                        reason != null ? reason : "kill uid");
12941            } finally {
12942                Binder.restoreCallingIdentity(identity);
12943            }
12944        }
12945    }
12946
12947    @Override
12948    public boolean killProcessesBelowForeground(String reason) {
12949        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12950            throw new SecurityException("killProcessesBelowForeground() only available to system");
12951        }
12952
12953        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12954    }
12955
12956    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12957        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12958            throw new SecurityException("killProcessesBelowAdj() only available to system");
12959        }
12960
12961        boolean killed = false;
12962        synchronized (mPidsSelfLocked) {
12963            final int size = mPidsSelfLocked.size();
12964            for (int i = 0; i < size; i++) {
12965                final int pid = mPidsSelfLocked.keyAt(i);
12966                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12967                if (proc == null) continue;
12968
12969                final int adj = proc.setAdj;
12970                if (adj > belowAdj && !proc.killedByAm) {
12971                    proc.kill(reason, true);
12972                    killed = true;
12973                }
12974            }
12975        }
12976        return killed;
12977    }
12978
12979    @Override
12980    public void hang(final IBinder who, boolean allowRestart) {
12981        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12982                != PackageManager.PERMISSION_GRANTED) {
12983            throw new SecurityException("Requires permission "
12984                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12985        }
12986
12987        final IBinder.DeathRecipient death = new DeathRecipient() {
12988            @Override
12989            public void binderDied() {
12990                synchronized (this) {
12991                    notifyAll();
12992                }
12993            }
12994        };
12995
12996        try {
12997            who.linkToDeath(death, 0);
12998        } catch (RemoteException e) {
12999            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13000            return;
13001        }
13002
13003        synchronized (this) {
13004            Watchdog.getInstance().setAllowRestart(allowRestart);
13005            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13006            synchronized (death) {
13007                while (who.isBinderAlive()) {
13008                    try {
13009                        death.wait();
13010                    } catch (InterruptedException e) {
13011                    }
13012                }
13013            }
13014            Watchdog.getInstance().setAllowRestart(true);
13015        }
13016    }
13017
13018    @Override
13019    public void restart() {
13020        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13021                != PackageManager.PERMISSION_GRANTED) {
13022            throw new SecurityException("Requires permission "
13023                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13024        }
13025
13026        Log.i(TAG, "Sending shutdown broadcast...");
13027
13028        BroadcastReceiver br = new BroadcastReceiver() {
13029            @Override public void onReceive(Context context, Intent intent) {
13030                // Now the broadcast is done, finish up the low-level shutdown.
13031                Log.i(TAG, "Shutting down activity manager...");
13032                shutdown(10000);
13033                Log.i(TAG, "Shutdown complete, restarting!");
13034                Process.killProcess(Process.myPid());
13035                System.exit(10);
13036            }
13037        };
13038
13039        // First send the high-level shut down broadcast.
13040        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13041        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13042        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13043        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13044        mContext.sendOrderedBroadcastAsUser(intent,
13045                UserHandle.ALL, null, br, mHandler, 0, null, null);
13046        */
13047        br.onReceive(mContext, intent);
13048    }
13049
13050    private long getLowRamTimeSinceIdle(long now) {
13051        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13052    }
13053
13054    @Override
13055    public void performIdleMaintenance() {
13056        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13057                != PackageManager.PERMISSION_GRANTED) {
13058            throw new SecurityException("Requires permission "
13059                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13060        }
13061
13062        synchronized (this) {
13063            final long now = SystemClock.uptimeMillis();
13064            final long timeSinceLastIdle = now - mLastIdleTime;
13065            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13066            mLastIdleTime = now;
13067            mLowRamTimeSinceLastIdle = 0;
13068            if (mLowRamStartTime != 0) {
13069                mLowRamStartTime = now;
13070            }
13071
13072            StringBuilder sb = new StringBuilder(128);
13073            sb.append("Idle maintenance over ");
13074            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13075            sb.append(" low RAM for ");
13076            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13077            Slog.i(TAG, sb.toString());
13078
13079            // If at least 1/3 of our time since the last idle period has been spent
13080            // with RAM low, then we want to kill processes.
13081            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13082
13083            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13084                ProcessRecord proc = mLruProcesses.get(i);
13085                if (proc.notCachedSinceIdle) {
13086                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13087                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13088                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13089                        if (doKilling && proc.initialIdlePss != 0
13090                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13091                            sb = new StringBuilder(128);
13092                            sb.append("Kill");
13093                            sb.append(proc.processName);
13094                            sb.append(" in idle maint: pss=");
13095                            sb.append(proc.lastPss);
13096                            sb.append(", swapPss=");
13097                            sb.append(proc.lastSwapPss);
13098                            sb.append(", initialPss=");
13099                            sb.append(proc.initialIdlePss);
13100                            sb.append(", period=");
13101                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13102                            sb.append(", lowRamPeriod=");
13103                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13104                            Slog.wtfQuiet(TAG, sb.toString());
13105                            proc.kill("idle maint (pss " + proc.lastPss
13106                                    + " from " + proc.initialIdlePss + ")", true);
13107                        }
13108                    }
13109                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13110                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13111                    proc.notCachedSinceIdle = true;
13112                    proc.initialIdlePss = 0;
13113                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13114                            mTestPssMode, isSleepingLocked(), now);
13115                }
13116            }
13117
13118            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13119            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13120        }
13121    }
13122
13123    @Override
13124    public void sendIdleJobTrigger() {
13125        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13126                != PackageManager.PERMISSION_GRANTED) {
13127            throw new SecurityException("Requires permission "
13128                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13129        }
13130
13131        final long ident = Binder.clearCallingIdentity();
13132        try {
13133            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13134                    .setPackage("android")
13135                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13136            broadcastIntent(null, intent, null, null, 0, null, null, null,
13137                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13138        } finally {
13139            Binder.restoreCallingIdentity(ident);
13140        }
13141    }
13142
13143    private void retrieveSettings() {
13144        final ContentResolver resolver = mContext.getContentResolver();
13145        final boolean freeformWindowManagement =
13146                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13147                        || Settings.Global.getInt(
13148                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13149        final boolean supportsPictureInPicture =
13150                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13151
13152        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13153        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13154        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13155        final boolean alwaysFinishActivities =
13156                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13157        final boolean lenientBackgroundCheck =
13158                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13159        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13160        final boolean forceResizable = Settings.Global.getInt(
13161                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13162        final boolean supportsLeanbackOnly =
13163                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13164
13165        // Transfer any global setting for forcing RTL layout, into a System Property
13166        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13167
13168        final Configuration configuration = new Configuration();
13169        Settings.System.getConfiguration(resolver, configuration);
13170        if (forceRtl) {
13171            // This will take care of setting the correct layout direction flags
13172            configuration.setLayoutDirection(configuration.locale);
13173        }
13174
13175        synchronized (this) {
13176            mDebugApp = mOrigDebugApp = debugApp;
13177            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13178            mAlwaysFinishActivities = alwaysFinishActivities;
13179            mLenientBackgroundCheck = lenientBackgroundCheck;
13180            mSupportsLeanbackOnly = supportsLeanbackOnly;
13181            mForceResizableActivities = forceResizable;
13182            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13183            if (supportsMultiWindow || forceResizable) {
13184                mSupportsMultiWindow = true;
13185                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13186                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13187            } else {
13188                mSupportsMultiWindow = false;
13189                mSupportsFreeformWindowManagement = false;
13190                mSupportsPictureInPicture = false;
13191            }
13192            // This happens before any activities are started, so we can
13193            // change mConfiguration in-place.
13194            updateConfigurationLocked(configuration, null, true);
13195            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13196                    "Initial config: " + mConfiguration);
13197
13198            // Load resources only after the current configuration has been set.
13199            final Resources res = mContext.getResources();
13200            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13201            mThumbnailWidth = res.getDimensionPixelSize(
13202                    com.android.internal.R.dimen.thumbnail_width);
13203            mThumbnailHeight = res.getDimensionPixelSize(
13204                    com.android.internal.R.dimen.thumbnail_height);
13205            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13206                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13207            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13208                    com.android.internal.R.string.config_appsNotReportingCrashes));
13209            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13210                mFullscreenThumbnailScale = (float) res
13211                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13212                    (float) mConfiguration.screenWidthDp;
13213            } else {
13214                mFullscreenThumbnailScale = res.getFraction(
13215                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13216            }
13217        }
13218    }
13219
13220    public boolean testIsSystemReady() {
13221        // no need to synchronize(this) just to read & return the value
13222        return mSystemReady;
13223    }
13224
13225    public void systemReady(final Runnable goingCallback) {
13226        synchronized(this) {
13227            if (mSystemReady) {
13228                // If we're done calling all the receivers, run the next "boot phase" passed in
13229                // by the SystemServer
13230                if (goingCallback != null) {
13231                    goingCallback.run();
13232                }
13233                return;
13234            }
13235
13236            mLocalDeviceIdleController
13237                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13238
13239            // Make sure we have the current profile info, since it is needed for security checks.
13240            mUserController.onSystemReady();
13241            mRecentTasks.onSystemReadyLocked();
13242            mAppOpsService.systemReady();
13243            mSystemReady = true;
13244        }
13245
13246        ArrayList<ProcessRecord> procsToKill = null;
13247        synchronized(mPidsSelfLocked) {
13248            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13249                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13250                if (!isAllowedWhileBooting(proc.info)){
13251                    if (procsToKill == null) {
13252                        procsToKill = new ArrayList<ProcessRecord>();
13253                    }
13254                    procsToKill.add(proc);
13255                }
13256            }
13257        }
13258
13259        synchronized(this) {
13260            if (procsToKill != null) {
13261                for (int i=procsToKill.size()-1; i>=0; i--) {
13262                    ProcessRecord proc = procsToKill.get(i);
13263                    Slog.i(TAG, "Removing system update proc: " + proc);
13264                    removeProcessLocked(proc, true, false, "system update done");
13265                }
13266            }
13267
13268            // Now that we have cleaned up any update processes, we
13269            // are ready to start launching real processes and know that
13270            // we won't trample on them any more.
13271            mProcessesReady = true;
13272        }
13273
13274        Slog.i(TAG, "System now ready");
13275        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13276            SystemClock.uptimeMillis());
13277
13278        synchronized(this) {
13279            // Make sure we have no pre-ready processes sitting around.
13280
13281            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13282                ResolveInfo ri = mContext.getPackageManager()
13283                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13284                                STOCK_PM_FLAGS);
13285                CharSequence errorMsg = null;
13286                if (ri != null) {
13287                    ActivityInfo ai = ri.activityInfo;
13288                    ApplicationInfo app = ai.applicationInfo;
13289                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13290                        mTopAction = Intent.ACTION_FACTORY_TEST;
13291                        mTopData = null;
13292                        mTopComponent = new ComponentName(app.packageName,
13293                                ai.name);
13294                    } else {
13295                        errorMsg = mContext.getResources().getText(
13296                                com.android.internal.R.string.factorytest_not_system);
13297                    }
13298                } else {
13299                    errorMsg = mContext.getResources().getText(
13300                            com.android.internal.R.string.factorytest_no_action);
13301                }
13302                if (errorMsg != null) {
13303                    mTopAction = null;
13304                    mTopData = null;
13305                    mTopComponent = null;
13306                    Message msg = Message.obtain();
13307                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13308                    msg.getData().putCharSequence("msg", errorMsg);
13309                    mUiHandler.sendMessage(msg);
13310                }
13311            }
13312        }
13313
13314        retrieveSettings();
13315        final int currentUserId;
13316        synchronized (this) {
13317            currentUserId = mUserController.getCurrentUserIdLocked();
13318            readGrantedUriPermissionsLocked();
13319        }
13320
13321        if (goingCallback != null) goingCallback.run();
13322
13323        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13324                Integer.toString(currentUserId), currentUserId);
13325        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13326                Integer.toString(currentUserId), currentUserId);
13327        mSystemServiceManager.startUser(currentUserId);
13328
13329        synchronized (this) {
13330            // Only start up encryption-aware persistent apps; once user is
13331            // unlocked we'll come back around and start unaware apps
13332            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13333
13334            // Start up initial activity.
13335            mBooting = true;
13336            // Enable home activity for system user, so that the system can always boot
13337            if (UserManager.isSplitSystemUser()) {
13338                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13339                try {
13340                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13341                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13342                            UserHandle.USER_SYSTEM);
13343                } catch (RemoteException e) {
13344                    throw e.rethrowAsRuntimeException();
13345                }
13346            }
13347            startHomeActivityLocked(currentUserId, "systemReady");
13348
13349            try {
13350                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13351                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13352                            + " data partition or your device will be unstable.");
13353                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13354                }
13355            } catch (RemoteException e) {
13356            }
13357
13358            if (!Build.isBuildConsistent()) {
13359                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13360                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13361            }
13362
13363            long ident = Binder.clearCallingIdentity();
13364            try {
13365                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13366                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13367                        | Intent.FLAG_RECEIVER_FOREGROUND);
13368                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13369                broadcastIntentLocked(null, null, intent,
13370                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13371                        null, false, false, MY_PID, Process.SYSTEM_UID,
13372                        currentUserId);
13373                intent = new Intent(Intent.ACTION_USER_STARTING);
13374                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13375                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13376                broadcastIntentLocked(null, null, intent,
13377                        null, new IIntentReceiver.Stub() {
13378                            @Override
13379                            public void performReceive(Intent intent, int resultCode, String data,
13380                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13381                                    throws RemoteException {
13382                            }
13383                        }, 0, null, null,
13384                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13385                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13386            } catch (Throwable t) {
13387                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13388            } finally {
13389                Binder.restoreCallingIdentity(ident);
13390            }
13391            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13392            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13393        }
13394    }
13395
13396    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13397        synchronized (this) {
13398            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13399        }
13400    }
13401
13402    void skipCurrentReceiverLocked(ProcessRecord app) {
13403        for (BroadcastQueue queue : mBroadcastQueues) {
13404            queue.skipCurrentReceiverLocked(app);
13405        }
13406    }
13407
13408    /**
13409     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13410     * The application process will exit immediately after this call returns.
13411     * @param app object of the crashing app, null for the system server
13412     * @param crashInfo describing the exception
13413     */
13414    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13415        ProcessRecord r = findAppProcess(app, "Crash");
13416        final String processName = app == null ? "system_server"
13417                : (r == null ? "unknown" : r.processName);
13418
13419        handleApplicationCrashInner("crash", r, processName, crashInfo);
13420    }
13421
13422    /* Native crash reporting uses this inner version because it needs to be somewhat
13423     * decoupled from the AM-managed cleanup lifecycle
13424     */
13425    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13426            ApplicationErrorReport.CrashInfo crashInfo) {
13427        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13428                UserHandle.getUserId(Binder.getCallingUid()), processName,
13429                r == null ? -1 : r.info.flags,
13430                crashInfo.exceptionClassName,
13431                crashInfo.exceptionMessage,
13432                crashInfo.throwFileName,
13433                crashInfo.throwLineNumber);
13434
13435        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13436
13437        mAppErrors.crashApplication(r, crashInfo);
13438    }
13439
13440    public void handleApplicationStrictModeViolation(
13441            IBinder app,
13442            int violationMask,
13443            StrictMode.ViolationInfo info) {
13444        ProcessRecord r = findAppProcess(app, "StrictMode");
13445        if (r == null) {
13446            return;
13447        }
13448
13449        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13450            Integer stackFingerprint = info.hashCode();
13451            boolean logIt = true;
13452            synchronized (mAlreadyLoggedViolatedStacks) {
13453                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13454                    logIt = false;
13455                    // TODO: sub-sample into EventLog for these, with
13456                    // the info.durationMillis?  Then we'd get
13457                    // the relative pain numbers, without logging all
13458                    // the stack traces repeatedly.  We'd want to do
13459                    // likewise in the client code, which also does
13460                    // dup suppression, before the Binder call.
13461                } else {
13462                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13463                        mAlreadyLoggedViolatedStacks.clear();
13464                    }
13465                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13466                }
13467            }
13468            if (logIt) {
13469                logStrictModeViolationToDropBox(r, info);
13470            }
13471        }
13472
13473        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13474            AppErrorResult result = new AppErrorResult();
13475            synchronized (this) {
13476                final long origId = Binder.clearCallingIdentity();
13477
13478                Message msg = Message.obtain();
13479                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13480                HashMap<String, Object> data = new HashMap<String, Object>();
13481                data.put("result", result);
13482                data.put("app", r);
13483                data.put("violationMask", violationMask);
13484                data.put("info", info);
13485                msg.obj = data;
13486                mUiHandler.sendMessage(msg);
13487
13488                Binder.restoreCallingIdentity(origId);
13489            }
13490            int res = result.get();
13491            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13492        }
13493    }
13494
13495    // Depending on the policy in effect, there could be a bunch of
13496    // these in quick succession so we try to batch these together to
13497    // minimize disk writes, number of dropbox entries, and maximize
13498    // compression, by having more fewer, larger records.
13499    private void logStrictModeViolationToDropBox(
13500            ProcessRecord process,
13501            StrictMode.ViolationInfo info) {
13502        if (info == null) {
13503            return;
13504        }
13505        final boolean isSystemApp = process == null ||
13506                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13507                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13508        final String processName = process == null ? "unknown" : process.processName;
13509        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13510        final DropBoxManager dbox = (DropBoxManager)
13511                mContext.getSystemService(Context.DROPBOX_SERVICE);
13512
13513        // Exit early if the dropbox isn't configured to accept this report type.
13514        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13515
13516        boolean bufferWasEmpty;
13517        boolean needsFlush;
13518        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13519        synchronized (sb) {
13520            bufferWasEmpty = sb.length() == 0;
13521            appendDropBoxProcessHeaders(process, processName, sb);
13522            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13523            sb.append("System-App: ").append(isSystemApp).append("\n");
13524            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13525            if (info.violationNumThisLoop != 0) {
13526                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13527            }
13528            if (info.numAnimationsRunning != 0) {
13529                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13530            }
13531            if (info.broadcastIntentAction != null) {
13532                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13533            }
13534            if (info.durationMillis != -1) {
13535                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13536            }
13537            if (info.numInstances != -1) {
13538                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13539            }
13540            if (info.tags != null) {
13541                for (String tag : info.tags) {
13542                    sb.append("Span-Tag: ").append(tag).append("\n");
13543                }
13544            }
13545            sb.append("\n");
13546            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13547                sb.append(info.crashInfo.stackTrace);
13548                sb.append("\n");
13549            }
13550            if (info.message != null) {
13551                sb.append(info.message);
13552                sb.append("\n");
13553            }
13554
13555            // Only buffer up to ~64k.  Various logging bits truncate
13556            // things at 128k.
13557            needsFlush = (sb.length() > 64 * 1024);
13558        }
13559
13560        // Flush immediately if the buffer's grown too large, or this
13561        // is a non-system app.  Non-system apps are isolated with a
13562        // different tag & policy and not batched.
13563        //
13564        // Batching is useful during internal testing with
13565        // StrictMode settings turned up high.  Without batching,
13566        // thousands of separate files could be created on boot.
13567        if (!isSystemApp || needsFlush) {
13568            new Thread("Error dump: " + dropboxTag) {
13569                @Override
13570                public void run() {
13571                    String report;
13572                    synchronized (sb) {
13573                        report = sb.toString();
13574                        sb.delete(0, sb.length());
13575                        sb.trimToSize();
13576                    }
13577                    if (report.length() != 0) {
13578                        dbox.addText(dropboxTag, report);
13579                    }
13580                }
13581            }.start();
13582            return;
13583        }
13584
13585        // System app batching:
13586        if (!bufferWasEmpty) {
13587            // An existing dropbox-writing thread is outstanding, so
13588            // we don't need to start it up.  The existing thread will
13589            // catch the buffer appends we just did.
13590            return;
13591        }
13592
13593        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13594        // (After this point, we shouldn't access AMS internal data structures.)
13595        new Thread("Error dump: " + dropboxTag) {
13596            @Override
13597            public void run() {
13598                // 5 second sleep to let stacks arrive and be batched together
13599                try {
13600                    Thread.sleep(5000);  // 5 seconds
13601                } catch (InterruptedException e) {}
13602
13603                String errorReport;
13604                synchronized (mStrictModeBuffer) {
13605                    errorReport = mStrictModeBuffer.toString();
13606                    if (errorReport.length() == 0) {
13607                        return;
13608                    }
13609                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13610                    mStrictModeBuffer.trimToSize();
13611                }
13612                dbox.addText(dropboxTag, errorReport);
13613            }
13614        }.start();
13615    }
13616
13617    /**
13618     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13619     * @param app object of the crashing app, null for the system server
13620     * @param tag reported by the caller
13621     * @param system whether this wtf is coming from the system
13622     * @param crashInfo describing the context of the error
13623     * @return true if the process should exit immediately (WTF is fatal)
13624     */
13625    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13626            final ApplicationErrorReport.CrashInfo crashInfo) {
13627        final int callingUid = Binder.getCallingUid();
13628        final int callingPid = Binder.getCallingPid();
13629
13630        if (system) {
13631            // If this is coming from the system, we could very well have low-level
13632            // system locks held, so we want to do this all asynchronously.  And we
13633            // never want this to become fatal, so there is that too.
13634            mHandler.post(new Runnable() {
13635                @Override public void run() {
13636                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13637                }
13638            });
13639            return false;
13640        }
13641
13642        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13643                crashInfo);
13644
13645        if (r != null && r.pid != Process.myPid() &&
13646                Settings.Global.getInt(mContext.getContentResolver(),
13647                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13648            mAppErrors.crashApplication(r, crashInfo);
13649            return true;
13650        } else {
13651            return false;
13652        }
13653    }
13654
13655    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13656            final ApplicationErrorReport.CrashInfo crashInfo) {
13657        final ProcessRecord r = findAppProcess(app, "WTF");
13658        final String processName = app == null ? "system_server"
13659                : (r == null ? "unknown" : r.processName);
13660
13661        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13662                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13663
13664        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13665
13666        return r;
13667    }
13668
13669    /**
13670     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13671     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13672     */
13673    private ProcessRecord findAppProcess(IBinder app, String reason) {
13674        if (app == null) {
13675            return null;
13676        }
13677
13678        synchronized (this) {
13679            final int NP = mProcessNames.getMap().size();
13680            for (int ip=0; ip<NP; ip++) {
13681                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13682                final int NA = apps.size();
13683                for (int ia=0; ia<NA; ia++) {
13684                    ProcessRecord p = apps.valueAt(ia);
13685                    if (p.thread != null && p.thread.asBinder() == app) {
13686                        return p;
13687                    }
13688                }
13689            }
13690
13691            Slog.w(TAG, "Can't find mystery application for " + reason
13692                    + " from pid=" + Binder.getCallingPid()
13693                    + " uid=" + Binder.getCallingUid() + ": " + app);
13694            return null;
13695        }
13696    }
13697
13698    /**
13699     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13700     * to append various headers to the dropbox log text.
13701     */
13702    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13703            StringBuilder sb) {
13704        // Watchdog thread ends up invoking this function (with
13705        // a null ProcessRecord) to add the stack file to dropbox.
13706        // Do not acquire a lock on this (am) in such cases, as it
13707        // could cause a potential deadlock, if and when watchdog
13708        // is invoked due to unavailability of lock on am and it
13709        // would prevent watchdog from killing system_server.
13710        if (process == null) {
13711            sb.append("Process: ").append(processName).append("\n");
13712            return;
13713        }
13714        // Note: ProcessRecord 'process' is guarded by the service
13715        // instance.  (notably process.pkgList, which could otherwise change
13716        // concurrently during execution of this method)
13717        synchronized (this) {
13718            sb.append("Process: ").append(processName).append("\n");
13719            int flags = process.info.flags;
13720            IPackageManager pm = AppGlobals.getPackageManager();
13721            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13722            for (int ip=0; ip<process.pkgList.size(); ip++) {
13723                String pkg = process.pkgList.keyAt(ip);
13724                sb.append("Package: ").append(pkg);
13725                try {
13726                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13727                    if (pi != null) {
13728                        sb.append(" v").append(pi.versionCode);
13729                        if (pi.versionName != null) {
13730                            sb.append(" (").append(pi.versionName).append(")");
13731                        }
13732                    }
13733                } catch (RemoteException e) {
13734                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13735                }
13736                sb.append("\n");
13737            }
13738        }
13739    }
13740
13741    private static String processClass(ProcessRecord process) {
13742        if (process == null || process.pid == MY_PID) {
13743            return "system_server";
13744        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13745            return "system_app";
13746        } else {
13747            return "data_app";
13748        }
13749    }
13750
13751    private volatile long mWtfClusterStart;
13752    private volatile int mWtfClusterCount;
13753
13754    /**
13755     * Write a description of an error (crash, WTF, ANR) to the drop box.
13756     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13757     * @param process which caused the error, null means the system server
13758     * @param activity which triggered the error, null if unknown
13759     * @param parent activity related to the error, null if unknown
13760     * @param subject line related to the error, null if absent
13761     * @param report in long form describing the error, null if absent
13762     * @param dataFile text file to include in the report, null if none
13763     * @param crashInfo giving an application stack trace, null if absent
13764     */
13765    public void addErrorToDropBox(String eventType,
13766            ProcessRecord process, String processName, ActivityRecord activity,
13767            ActivityRecord parent, String subject,
13768            final String report, final File dataFile,
13769            final ApplicationErrorReport.CrashInfo crashInfo) {
13770        // NOTE -- this must never acquire the ActivityManagerService lock,
13771        // otherwise the watchdog may be prevented from resetting the system.
13772
13773        final String dropboxTag = processClass(process) + "_" + eventType;
13774        final DropBoxManager dbox = (DropBoxManager)
13775                mContext.getSystemService(Context.DROPBOX_SERVICE);
13776
13777        // Exit early if the dropbox isn't configured to accept this report type.
13778        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13779
13780        // Rate-limit how often we're willing to do the heavy lifting below to
13781        // collect and record logs; currently 5 logs per 10 second period.
13782        final long now = SystemClock.elapsedRealtime();
13783        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13784            mWtfClusterStart = now;
13785            mWtfClusterCount = 1;
13786        } else {
13787            if (mWtfClusterCount++ >= 5) return;
13788        }
13789
13790        final StringBuilder sb = new StringBuilder(1024);
13791        appendDropBoxProcessHeaders(process, processName, sb);
13792        if (process != null) {
13793            sb.append("Foreground: ")
13794                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13795                    .append("\n");
13796        }
13797        if (activity != null) {
13798            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13799        }
13800        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13801            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13802        }
13803        if (parent != null && parent != activity) {
13804            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13805        }
13806        if (subject != null) {
13807            sb.append("Subject: ").append(subject).append("\n");
13808        }
13809        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13810        if (Debug.isDebuggerConnected()) {
13811            sb.append("Debugger: Connected\n");
13812        }
13813        sb.append("\n");
13814
13815        // Do the rest in a worker thread to avoid blocking the caller on I/O
13816        // (After this point, we shouldn't access AMS internal data structures.)
13817        Thread worker = new Thread("Error dump: " + dropboxTag) {
13818            @Override
13819            public void run() {
13820                if (report != null) {
13821                    sb.append(report);
13822                }
13823
13824                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13825                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13826                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13827                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13828
13829                if (dataFile != null && maxDataFileSize > 0) {
13830                    try {
13831                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13832                                    "\n\n[[TRUNCATED]]"));
13833                    } catch (IOException e) {
13834                        Slog.e(TAG, "Error reading " + dataFile, e);
13835                    }
13836                }
13837                if (crashInfo != null && crashInfo.stackTrace != null) {
13838                    sb.append(crashInfo.stackTrace);
13839                }
13840
13841                if (lines > 0) {
13842                    sb.append("\n");
13843
13844                    // Merge several logcat streams, and take the last N lines
13845                    InputStreamReader input = null;
13846                    try {
13847                        java.lang.Process logcat = new ProcessBuilder(
13848                                "/system/bin/timeout", "-k", "15s", "10s",
13849                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13850                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13851                                        .redirectErrorStream(true).start();
13852
13853                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13854                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13855                        input = new InputStreamReader(logcat.getInputStream());
13856
13857                        int num;
13858                        char[] buf = new char[8192];
13859                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13860                    } catch (IOException e) {
13861                        Slog.e(TAG, "Error running logcat", e);
13862                    } finally {
13863                        if (input != null) try { input.close(); } catch (IOException e) {}
13864                    }
13865                }
13866
13867                dbox.addText(dropboxTag, sb.toString());
13868            }
13869        };
13870
13871        if (process == null) {
13872            // If process is null, we are being called from some internal code
13873            // and may be about to die -- run this synchronously.
13874            worker.run();
13875        } else {
13876            worker.start();
13877        }
13878    }
13879
13880    @Override
13881    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13882        enforceNotIsolatedCaller("getProcessesInErrorState");
13883        // assume our apps are happy - lazy create the list
13884        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13885
13886        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13887                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13888        int userId = UserHandle.getUserId(Binder.getCallingUid());
13889
13890        synchronized (this) {
13891
13892            // iterate across all processes
13893            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13894                ProcessRecord app = mLruProcesses.get(i);
13895                if (!allUsers && app.userId != userId) {
13896                    continue;
13897                }
13898                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13899                    // This one's in trouble, so we'll generate a report for it
13900                    // crashes are higher priority (in case there's a crash *and* an anr)
13901                    ActivityManager.ProcessErrorStateInfo report = null;
13902                    if (app.crashing) {
13903                        report = app.crashingReport;
13904                    } else if (app.notResponding) {
13905                        report = app.notRespondingReport;
13906                    }
13907
13908                    if (report != null) {
13909                        if (errList == null) {
13910                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13911                        }
13912                        errList.add(report);
13913                    } else {
13914                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13915                                " crashing = " + app.crashing +
13916                                " notResponding = " + app.notResponding);
13917                    }
13918                }
13919            }
13920        }
13921
13922        return errList;
13923    }
13924
13925    static int procStateToImportance(int procState, int memAdj,
13926            ActivityManager.RunningAppProcessInfo currApp) {
13927        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13928        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13929            currApp.lru = memAdj;
13930        } else {
13931            currApp.lru = 0;
13932        }
13933        return imp;
13934    }
13935
13936    private void fillInProcMemInfo(ProcessRecord app,
13937            ActivityManager.RunningAppProcessInfo outInfo) {
13938        outInfo.pid = app.pid;
13939        outInfo.uid = app.info.uid;
13940        if (mHeavyWeightProcess == app) {
13941            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13942        }
13943        if (app.persistent) {
13944            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13945        }
13946        if (app.activities.size() > 0) {
13947            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13948        }
13949        outInfo.lastTrimLevel = app.trimMemoryLevel;
13950        int adj = app.curAdj;
13951        int procState = app.curProcState;
13952        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13953        outInfo.importanceReasonCode = app.adjTypeCode;
13954        outInfo.processState = app.curProcState;
13955    }
13956
13957    @Override
13958    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13959        enforceNotIsolatedCaller("getRunningAppProcesses");
13960
13961        final int callingUid = Binder.getCallingUid();
13962
13963        // Lazy instantiation of list
13964        List<ActivityManager.RunningAppProcessInfo> runList = null;
13965        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13966                callingUid) == PackageManager.PERMISSION_GRANTED;
13967        final int userId = UserHandle.getUserId(callingUid);
13968        final boolean allUids = isGetTasksAllowed(
13969                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13970
13971        synchronized (this) {
13972            // Iterate across all processes
13973            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13974                ProcessRecord app = mLruProcesses.get(i);
13975                if ((!allUsers && app.userId != userId)
13976                        || (!allUids && app.uid != callingUid)) {
13977                    continue;
13978                }
13979                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13980                    // Generate process state info for running application
13981                    ActivityManager.RunningAppProcessInfo currApp =
13982                        new ActivityManager.RunningAppProcessInfo(app.processName,
13983                                app.pid, app.getPackageList());
13984                    fillInProcMemInfo(app, currApp);
13985                    if (app.adjSource instanceof ProcessRecord) {
13986                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13987                        currApp.importanceReasonImportance =
13988                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13989                                        app.adjSourceProcState);
13990                    } else if (app.adjSource instanceof ActivityRecord) {
13991                        ActivityRecord r = (ActivityRecord)app.adjSource;
13992                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13993                    }
13994                    if (app.adjTarget instanceof ComponentName) {
13995                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13996                    }
13997                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13998                    //        + " lru=" + currApp.lru);
13999                    if (runList == null) {
14000                        runList = new ArrayList<>();
14001                    }
14002                    runList.add(currApp);
14003                }
14004            }
14005        }
14006        return runList;
14007    }
14008
14009    @Override
14010    public List<ApplicationInfo> getRunningExternalApplications() {
14011        enforceNotIsolatedCaller("getRunningExternalApplications");
14012        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14013        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14014        if (runningApps != null && runningApps.size() > 0) {
14015            Set<String> extList = new HashSet<String>();
14016            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14017                if (app.pkgList != null) {
14018                    for (String pkg : app.pkgList) {
14019                        extList.add(pkg);
14020                    }
14021                }
14022            }
14023            IPackageManager pm = AppGlobals.getPackageManager();
14024            for (String pkg : extList) {
14025                try {
14026                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14027                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14028                        retList.add(info);
14029                    }
14030                } catch (RemoteException e) {
14031                }
14032            }
14033        }
14034        return retList;
14035    }
14036
14037    @Override
14038    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14039        enforceNotIsolatedCaller("getMyMemoryState");
14040        synchronized (this) {
14041            ProcessRecord proc;
14042            synchronized (mPidsSelfLocked) {
14043                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14044            }
14045            fillInProcMemInfo(proc, outInfo);
14046        }
14047    }
14048
14049    @Override
14050    public int getMemoryTrimLevel() {
14051        enforceNotIsolatedCaller("getMyMemoryState");
14052        synchronized (this) {
14053            return mLastMemoryLevel;
14054        }
14055    }
14056
14057    @Override
14058    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14059            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14060        (new ActivityManagerShellCommand(this, false)).exec(
14061                this, in, out, err, args, resultReceiver);
14062    }
14063
14064    @Override
14065    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14066        if (checkCallingPermission(android.Manifest.permission.DUMP)
14067                != PackageManager.PERMISSION_GRANTED) {
14068            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14069                    + Binder.getCallingPid()
14070                    + ", uid=" + Binder.getCallingUid()
14071                    + " without permission "
14072                    + android.Manifest.permission.DUMP);
14073            return;
14074        }
14075
14076        boolean dumpAll = false;
14077        boolean dumpClient = false;
14078        boolean dumpCheckin = false;
14079        boolean dumpCheckinFormat = false;
14080        String dumpPackage = null;
14081
14082        int opti = 0;
14083        while (opti < args.length) {
14084            String opt = args[opti];
14085            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14086                break;
14087            }
14088            opti++;
14089            if ("-a".equals(opt)) {
14090                dumpAll = true;
14091            } else if ("-c".equals(opt)) {
14092                dumpClient = true;
14093            } else if ("-p".equals(opt)) {
14094                if (opti < args.length) {
14095                    dumpPackage = args[opti];
14096                    opti++;
14097                } else {
14098                    pw.println("Error: -p option requires package argument");
14099                    return;
14100                }
14101                dumpClient = true;
14102            } else if ("--checkin".equals(opt)) {
14103                dumpCheckin = dumpCheckinFormat = true;
14104            } else if ("-C".equals(opt)) {
14105                dumpCheckinFormat = true;
14106            } else if ("-h".equals(opt)) {
14107                ActivityManagerShellCommand.dumpHelp(pw, true);
14108                return;
14109            } else {
14110                pw.println("Unknown argument: " + opt + "; use -h for help");
14111            }
14112        }
14113
14114        long origId = Binder.clearCallingIdentity();
14115        boolean more = false;
14116        // Is the caller requesting to dump a particular piece of data?
14117        if (opti < args.length) {
14118            String cmd = args[opti];
14119            opti++;
14120            if ("activities".equals(cmd) || "a".equals(cmd)) {
14121                synchronized (this) {
14122                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14123                }
14124            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14125                synchronized (this) {
14126                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14127                }
14128            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14129                String[] newArgs;
14130                String name;
14131                if (opti >= args.length) {
14132                    name = null;
14133                    newArgs = EMPTY_STRING_ARRAY;
14134                } else {
14135                    dumpPackage = args[opti];
14136                    opti++;
14137                    newArgs = new String[args.length - opti];
14138                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14139                            args.length - opti);
14140                }
14141                synchronized (this) {
14142                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14143                }
14144            } else if ("broadcast-stats".equals(cmd)) {
14145                String[] newArgs;
14146                String name;
14147                if (opti >= args.length) {
14148                    name = null;
14149                    newArgs = EMPTY_STRING_ARRAY;
14150                } else {
14151                    dumpPackage = args[opti];
14152                    opti++;
14153                    newArgs = new String[args.length - opti];
14154                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14155                            args.length - opti);
14156                }
14157                synchronized (this) {
14158                    if (dumpCheckinFormat) {
14159                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14160                                dumpPackage);
14161                    } else {
14162                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14163                    }
14164                }
14165            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14166                String[] newArgs;
14167                String name;
14168                if (opti >= args.length) {
14169                    name = null;
14170                    newArgs = EMPTY_STRING_ARRAY;
14171                } else {
14172                    dumpPackage = args[opti];
14173                    opti++;
14174                    newArgs = new String[args.length - opti];
14175                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14176                            args.length - opti);
14177                }
14178                synchronized (this) {
14179                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14180                }
14181            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14182                String[] newArgs;
14183                String name;
14184                if (opti >= args.length) {
14185                    name = null;
14186                    newArgs = EMPTY_STRING_ARRAY;
14187                } else {
14188                    dumpPackage = args[opti];
14189                    opti++;
14190                    newArgs = new String[args.length - opti];
14191                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14192                            args.length - opti);
14193                }
14194                synchronized (this) {
14195                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14196                }
14197            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14198                synchronized (this) {
14199                    dumpOomLocked(fd, pw, args, opti, true);
14200                }
14201            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14202                synchronized (this) {
14203                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14204                }
14205            } else if ("provider".equals(cmd)) {
14206                String[] newArgs;
14207                String name;
14208                if (opti >= args.length) {
14209                    name = null;
14210                    newArgs = EMPTY_STRING_ARRAY;
14211                } else {
14212                    name = args[opti];
14213                    opti++;
14214                    newArgs = new String[args.length - opti];
14215                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14216                }
14217                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14218                    pw.println("No providers match: " + name);
14219                    pw.println("Use -h for help.");
14220                }
14221            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14222                synchronized (this) {
14223                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14224                }
14225            } else if ("service".equals(cmd)) {
14226                String[] newArgs;
14227                String name;
14228                if (opti >= args.length) {
14229                    name = null;
14230                    newArgs = EMPTY_STRING_ARRAY;
14231                } else {
14232                    name = args[opti];
14233                    opti++;
14234                    newArgs = new String[args.length - opti];
14235                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14236                            args.length - opti);
14237                }
14238                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14239                    pw.println("No services match: " + name);
14240                    pw.println("Use -h for help.");
14241                }
14242            } else if ("package".equals(cmd)) {
14243                String[] newArgs;
14244                if (opti >= args.length) {
14245                    pw.println("package: no package name specified");
14246                    pw.println("Use -h for help.");
14247                } else {
14248                    dumpPackage = args[opti];
14249                    opti++;
14250                    newArgs = new String[args.length - opti];
14251                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14252                            args.length - opti);
14253                    args = newArgs;
14254                    opti = 0;
14255                    more = true;
14256                }
14257            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14258                synchronized (this) {
14259                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14260                }
14261            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14262                if (dumpClient) {
14263                    ActiveServices.ServiceDumper dumper;
14264                    synchronized (this) {
14265                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14266                                dumpPackage);
14267                    }
14268                    dumper.dumpWithClient();
14269                } else {
14270                    synchronized (this) {
14271                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14272                                dumpPackage).dumpLocked();
14273                    }
14274                }
14275            } else if ("locks".equals(cmd)) {
14276                LockGuard.dump(fd, pw, args);
14277            } else {
14278                // Dumping a single activity?
14279                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14280                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14281                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14282                    if (res < 0) {
14283                        pw.println("Bad activity command, or no activities match: " + cmd);
14284                        pw.println("Use -h for help.");
14285                    }
14286                }
14287            }
14288            if (!more) {
14289                Binder.restoreCallingIdentity(origId);
14290                return;
14291            }
14292        }
14293
14294        // No piece of data specified, dump everything.
14295        if (dumpCheckinFormat) {
14296            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14297        } else if (dumpClient) {
14298            ActiveServices.ServiceDumper sdumper;
14299            synchronized (this) {
14300                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14301                pw.println();
14302                if (dumpAll) {
14303                    pw.println("-------------------------------------------------------------------------------");
14304                }
14305                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14306                pw.println();
14307                if (dumpAll) {
14308                    pw.println("-------------------------------------------------------------------------------");
14309                }
14310                if (dumpAll || dumpPackage != null) {
14311                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14312                    pw.println();
14313                    if (dumpAll) {
14314                        pw.println("-------------------------------------------------------------------------------");
14315                    }
14316                }
14317                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14318                pw.println();
14319                if (dumpAll) {
14320                    pw.println("-------------------------------------------------------------------------------");
14321                }
14322                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14323                pw.println();
14324                if (dumpAll) {
14325                    pw.println("-------------------------------------------------------------------------------");
14326                }
14327                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14328                        dumpPackage);
14329            }
14330            sdumper.dumpWithClient();
14331            pw.println();
14332            synchronized (this) {
14333                if (dumpAll) {
14334                    pw.println("-------------------------------------------------------------------------------");
14335                }
14336                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14337                pw.println();
14338                if (dumpAll) {
14339                    pw.println("-------------------------------------------------------------------------------");
14340                }
14341                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14342                if (mAssociations.size() > 0) {
14343                    pw.println();
14344                    if (dumpAll) {
14345                        pw.println("-------------------------------------------------------------------------------");
14346                    }
14347                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14348                }
14349                pw.println();
14350                if (dumpAll) {
14351                    pw.println("-------------------------------------------------------------------------------");
14352                }
14353                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14354            }
14355
14356        } else {
14357            synchronized (this) {
14358                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14359                pw.println();
14360                if (dumpAll) {
14361                    pw.println("-------------------------------------------------------------------------------");
14362                }
14363                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14364                pw.println();
14365                if (dumpAll) {
14366                    pw.println("-------------------------------------------------------------------------------");
14367                }
14368                if (dumpAll || dumpPackage != null) {
14369                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14370                    pw.println();
14371                    if (dumpAll) {
14372                        pw.println("-------------------------------------------------------------------------------");
14373                    }
14374                }
14375                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14376                pw.println();
14377                if (dumpAll) {
14378                    pw.println("-------------------------------------------------------------------------------");
14379                }
14380                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14381                pw.println();
14382                if (dumpAll) {
14383                    pw.println("-------------------------------------------------------------------------------");
14384                }
14385                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14386                        .dumpLocked();
14387                pw.println();
14388                if (dumpAll) {
14389                    pw.println("-------------------------------------------------------------------------------");
14390                }
14391                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14392                pw.println();
14393                if (dumpAll) {
14394                    pw.println("-------------------------------------------------------------------------------");
14395                }
14396                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14397                if (mAssociations.size() > 0) {
14398                    pw.println();
14399                    if (dumpAll) {
14400                        pw.println("-------------------------------------------------------------------------------");
14401                    }
14402                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14403                }
14404                pw.println();
14405                if (dumpAll) {
14406                    pw.println("-------------------------------------------------------------------------------");
14407                }
14408                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14409            }
14410        }
14411        Binder.restoreCallingIdentity(origId);
14412    }
14413
14414    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14415            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14416        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14417
14418        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14419                dumpPackage);
14420        boolean needSep = printedAnything;
14421
14422        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14423                dumpPackage, needSep, "  mFocusedActivity: ");
14424        if (printed) {
14425            printedAnything = true;
14426            needSep = false;
14427        }
14428
14429        if (dumpPackage == null) {
14430            if (needSep) {
14431                pw.println();
14432            }
14433            needSep = true;
14434            printedAnything = true;
14435            mStackSupervisor.dump(pw, "  ");
14436        }
14437
14438        if (!printedAnything) {
14439            pw.println("  (nothing)");
14440        }
14441    }
14442
14443    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14444            int opti, boolean dumpAll, String dumpPackage) {
14445        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14446
14447        boolean printedAnything = false;
14448
14449        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14450            boolean printedHeader = false;
14451
14452            final int N = mRecentTasks.size();
14453            for (int i=0; i<N; i++) {
14454                TaskRecord tr = mRecentTasks.get(i);
14455                if (dumpPackage != null) {
14456                    if (tr.realActivity == null ||
14457                            !dumpPackage.equals(tr.realActivity)) {
14458                        continue;
14459                    }
14460                }
14461                if (!printedHeader) {
14462                    pw.println("  Recent tasks:");
14463                    printedHeader = true;
14464                    printedAnything = true;
14465                }
14466                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14467                        pw.println(tr);
14468                if (dumpAll) {
14469                    mRecentTasks.get(i).dump(pw, "    ");
14470                }
14471            }
14472        }
14473
14474        if (!printedAnything) {
14475            pw.println("  (nothing)");
14476        }
14477    }
14478
14479    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14480            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14481        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14482
14483        int dumpUid = 0;
14484        if (dumpPackage != null) {
14485            IPackageManager pm = AppGlobals.getPackageManager();
14486            try {
14487                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14488            } catch (RemoteException e) {
14489            }
14490        }
14491
14492        boolean printedAnything = false;
14493
14494        final long now = SystemClock.uptimeMillis();
14495
14496        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14497            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14498                    = mAssociations.valueAt(i1);
14499            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14500                SparseArray<ArrayMap<String, Association>> sourceUids
14501                        = targetComponents.valueAt(i2);
14502                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14503                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14504                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14505                        Association ass = sourceProcesses.valueAt(i4);
14506                        if (dumpPackage != null) {
14507                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14508                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14509                                continue;
14510                            }
14511                        }
14512                        printedAnything = true;
14513                        pw.print("  ");
14514                        pw.print(ass.mTargetProcess);
14515                        pw.print("/");
14516                        UserHandle.formatUid(pw, ass.mTargetUid);
14517                        pw.print(" <- ");
14518                        pw.print(ass.mSourceProcess);
14519                        pw.print("/");
14520                        UserHandle.formatUid(pw, ass.mSourceUid);
14521                        pw.println();
14522                        pw.print("    via ");
14523                        pw.print(ass.mTargetComponent.flattenToShortString());
14524                        pw.println();
14525                        pw.print("    ");
14526                        long dur = ass.mTime;
14527                        if (ass.mNesting > 0) {
14528                            dur += now - ass.mStartTime;
14529                        }
14530                        TimeUtils.formatDuration(dur, pw);
14531                        pw.print(" (");
14532                        pw.print(ass.mCount);
14533                        pw.print(" times)");
14534                        pw.print("  ");
14535                        for (int i=0; i<ass.mStateTimes.length; i++) {
14536                            long amt = ass.mStateTimes[i];
14537                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14538                                amt += now - ass.mLastStateUptime;
14539                            }
14540                            if (amt != 0) {
14541                                pw.print(" ");
14542                                pw.print(ProcessList.makeProcStateString(
14543                                            i + ActivityManager.MIN_PROCESS_STATE));
14544                                pw.print("=");
14545                                TimeUtils.formatDuration(amt, pw);
14546                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14547                                    pw.print("*");
14548                                }
14549                            }
14550                        }
14551                        pw.println();
14552                        if (ass.mNesting > 0) {
14553                            pw.print("    Currently active: ");
14554                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14555                            pw.println();
14556                        }
14557                    }
14558                }
14559            }
14560
14561        }
14562
14563        if (!printedAnything) {
14564            pw.println("  (nothing)");
14565        }
14566    }
14567
14568    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14569            String header, boolean needSep) {
14570        boolean printed = false;
14571        int whichAppId = -1;
14572        if (dumpPackage != null) {
14573            try {
14574                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14575                        dumpPackage, 0);
14576                whichAppId = UserHandle.getAppId(info.uid);
14577            } catch (NameNotFoundException e) {
14578                e.printStackTrace();
14579            }
14580        }
14581        for (int i=0; i<uids.size(); i++) {
14582            UidRecord uidRec = uids.valueAt(i);
14583            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14584                continue;
14585            }
14586            if (!printed) {
14587                printed = true;
14588                if (needSep) {
14589                    pw.println();
14590                }
14591                pw.print("  ");
14592                pw.println(header);
14593                needSep = true;
14594            }
14595            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14596            pw.print(": "); pw.println(uidRec);
14597        }
14598        return printed;
14599    }
14600
14601    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14602            int opti, boolean dumpAll, String dumpPackage) {
14603        boolean needSep = false;
14604        boolean printedAnything = false;
14605        int numPers = 0;
14606
14607        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14608
14609        if (dumpAll) {
14610            final int NP = mProcessNames.getMap().size();
14611            for (int ip=0; ip<NP; ip++) {
14612                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14613                final int NA = procs.size();
14614                for (int ia=0; ia<NA; ia++) {
14615                    ProcessRecord r = procs.valueAt(ia);
14616                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14617                        continue;
14618                    }
14619                    if (!needSep) {
14620                        pw.println("  All known processes:");
14621                        needSep = true;
14622                        printedAnything = true;
14623                    }
14624                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14625                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14626                        pw.print(" "); pw.println(r);
14627                    r.dump(pw, "    ");
14628                    if (r.persistent) {
14629                        numPers++;
14630                    }
14631                }
14632            }
14633        }
14634
14635        if (mIsolatedProcesses.size() > 0) {
14636            boolean printed = false;
14637            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14638                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14639                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14640                    continue;
14641                }
14642                if (!printed) {
14643                    if (needSep) {
14644                        pw.println();
14645                    }
14646                    pw.println("  Isolated process list (sorted by uid):");
14647                    printedAnything = true;
14648                    printed = true;
14649                    needSep = true;
14650                }
14651                pw.println(String.format("%sIsolated #%2d: %s",
14652                        "    ", i, r.toString()));
14653            }
14654        }
14655
14656        if (mActiveUids.size() > 0) {
14657            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14658                printedAnything = needSep = true;
14659            }
14660        }
14661        if (mValidateUids.size() > 0) {
14662            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14663                printedAnything = needSep = true;
14664            }
14665        }
14666
14667        if (mLruProcesses.size() > 0) {
14668            if (needSep) {
14669                pw.println();
14670            }
14671            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14672                    pw.print(" total, non-act at ");
14673                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14674                    pw.print(", non-svc at ");
14675                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14676                    pw.println("):");
14677            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14678            needSep = true;
14679            printedAnything = true;
14680        }
14681
14682        if (dumpAll || dumpPackage != null) {
14683            synchronized (mPidsSelfLocked) {
14684                boolean printed = false;
14685                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14686                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14687                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14688                        continue;
14689                    }
14690                    if (!printed) {
14691                        if (needSep) pw.println();
14692                        needSep = true;
14693                        pw.println("  PID mappings:");
14694                        printed = true;
14695                        printedAnything = true;
14696                    }
14697                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14698                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14699                }
14700            }
14701        }
14702
14703        if (mForegroundProcesses.size() > 0) {
14704            synchronized (mPidsSelfLocked) {
14705                boolean printed = false;
14706                for (int i=0; i<mForegroundProcesses.size(); i++) {
14707                    ProcessRecord r = mPidsSelfLocked.get(
14708                            mForegroundProcesses.valueAt(i).pid);
14709                    if (dumpPackage != null && (r == null
14710                            || !r.pkgList.containsKey(dumpPackage))) {
14711                        continue;
14712                    }
14713                    if (!printed) {
14714                        if (needSep) pw.println();
14715                        needSep = true;
14716                        pw.println("  Foreground Processes:");
14717                        printed = true;
14718                        printedAnything = true;
14719                    }
14720                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14721                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14722                }
14723            }
14724        }
14725
14726        if (mPersistentStartingProcesses.size() > 0) {
14727            if (needSep) pw.println();
14728            needSep = true;
14729            printedAnything = true;
14730            pw.println("  Persisent processes that are starting:");
14731            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14732                    "Starting Norm", "Restarting PERS", dumpPackage);
14733        }
14734
14735        if (mRemovedProcesses.size() > 0) {
14736            if (needSep) pw.println();
14737            needSep = true;
14738            printedAnything = true;
14739            pw.println("  Processes that are being removed:");
14740            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14741                    "Removed Norm", "Removed PERS", dumpPackage);
14742        }
14743
14744        if (mProcessesOnHold.size() > 0) {
14745            if (needSep) pw.println();
14746            needSep = true;
14747            printedAnything = true;
14748            pw.println("  Processes that are on old until the system is ready:");
14749            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14750                    "OnHold Norm", "OnHold PERS", dumpPackage);
14751        }
14752
14753        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14754
14755        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14756        if (needSep) {
14757            printedAnything = true;
14758        }
14759
14760        if (dumpPackage == null) {
14761            pw.println();
14762            needSep = false;
14763            mUserController.dump(pw, dumpAll);
14764        }
14765        if (mHomeProcess != null && (dumpPackage == null
14766                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14767            if (needSep) {
14768                pw.println();
14769                needSep = false;
14770            }
14771            pw.println("  mHomeProcess: " + mHomeProcess);
14772        }
14773        if (mPreviousProcess != null && (dumpPackage == null
14774                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14775            if (needSep) {
14776                pw.println();
14777                needSep = false;
14778            }
14779            pw.println("  mPreviousProcess: " + mPreviousProcess);
14780        }
14781        if (dumpAll) {
14782            StringBuilder sb = new StringBuilder(128);
14783            sb.append("  mPreviousProcessVisibleTime: ");
14784            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14785            pw.println(sb);
14786        }
14787        if (mHeavyWeightProcess != null && (dumpPackage == null
14788                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14789            if (needSep) {
14790                pw.println();
14791                needSep = false;
14792            }
14793            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14794        }
14795        if (dumpPackage == null) {
14796            pw.println("  mConfiguration: " + mConfiguration);
14797        }
14798        if (dumpAll) {
14799            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14800            if (mCompatModePackages.getPackages().size() > 0) {
14801                boolean printed = false;
14802                for (Map.Entry<String, Integer> entry
14803                        : mCompatModePackages.getPackages().entrySet()) {
14804                    String pkg = entry.getKey();
14805                    int mode = entry.getValue();
14806                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14807                        continue;
14808                    }
14809                    if (!printed) {
14810                        pw.println("  mScreenCompatPackages:");
14811                        printed = true;
14812                    }
14813                    pw.print("    "); pw.print(pkg); pw.print(": ");
14814                            pw.print(mode); pw.println();
14815                }
14816            }
14817        }
14818        if (dumpPackage == null) {
14819            pw.println("  mWakefulness="
14820                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14821            pw.println("  mSleepTokens=" + mSleepTokens);
14822            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14823                    + lockScreenShownToString());
14824            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14825            if (mRunningVoice != null) {
14826                pw.println("  mRunningVoice=" + mRunningVoice);
14827                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14828            }
14829        }
14830        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14831                || mOrigWaitForDebugger) {
14832            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14833                    || dumpPackage.equals(mOrigDebugApp)) {
14834                if (needSep) {
14835                    pw.println();
14836                    needSep = false;
14837                }
14838                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14839                        + " mDebugTransient=" + mDebugTransient
14840                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14841            }
14842        }
14843        if (mCurAppTimeTracker != null) {
14844            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14845        }
14846        if (mMemWatchProcesses.getMap().size() > 0) {
14847            pw.println("  Mem watch processes:");
14848            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14849                    = mMemWatchProcesses.getMap();
14850            for (int i=0; i<procs.size(); i++) {
14851                final String proc = procs.keyAt(i);
14852                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14853                for (int j=0; j<uids.size(); j++) {
14854                    if (needSep) {
14855                        pw.println();
14856                        needSep = false;
14857                    }
14858                    StringBuilder sb = new StringBuilder();
14859                    sb.append("    ").append(proc).append('/');
14860                    UserHandle.formatUid(sb, uids.keyAt(j));
14861                    Pair<Long, String> val = uids.valueAt(j);
14862                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14863                    if (val.second != null) {
14864                        sb.append(", report to ").append(val.second);
14865                    }
14866                    pw.println(sb.toString());
14867                }
14868            }
14869            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14870            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14871            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14872                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14873        }
14874        if (mTrackAllocationApp != null) {
14875            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14876                if (needSep) {
14877                    pw.println();
14878                    needSep = false;
14879                }
14880                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14881            }
14882        }
14883        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14884                || mProfileFd != null) {
14885            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14886                if (needSep) {
14887                    pw.println();
14888                    needSep = false;
14889                }
14890                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14891                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14892                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14893                        + mAutoStopProfiler);
14894                pw.println("  mProfileType=" + mProfileType);
14895            }
14896        }
14897        if (mNativeDebuggingApp != null) {
14898            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14899                if (needSep) {
14900                    pw.println();
14901                    needSep = false;
14902                }
14903                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14904            }
14905        }
14906        if (dumpPackage == null) {
14907            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14908                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14909                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14910            }
14911            if (mController != null) {
14912                pw.println("  mController=" + mController
14913                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14914            }
14915            if (dumpAll) {
14916                pw.println("  Total persistent processes: " + numPers);
14917                pw.println("  mProcessesReady=" + mProcessesReady
14918                        + " mSystemReady=" + mSystemReady
14919                        + " mBooted=" + mBooted
14920                        + " mFactoryTest=" + mFactoryTest);
14921                pw.println("  mBooting=" + mBooting
14922                        + " mCallFinishBooting=" + mCallFinishBooting
14923                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14924                pw.print("  mLastPowerCheckRealtime=");
14925                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14926                        pw.println("");
14927                pw.print("  mLastPowerCheckUptime=");
14928                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14929                        pw.println("");
14930                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14931                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14932                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14933                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14934                        + " (" + mLruProcesses.size() + " total)"
14935                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14936                        + " mNumServiceProcs=" + mNumServiceProcs
14937                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14938                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14939                        + " mLastMemoryLevel=" + mLastMemoryLevel
14940                        + " mLastNumProcesses=" + mLastNumProcesses);
14941                long now = SystemClock.uptimeMillis();
14942                pw.print("  mLastIdleTime=");
14943                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14944                        pw.print(" mLowRamSinceLastIdle=");
14945                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14946                        pw.println();
14947            }
14948        }
14949
14950        if (!printedAnything) {
14951            pw.println("  (nothing)");
14952        }
14953    }
14954
14955    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14956            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14957        if (mProcessesToGc.size() > 0) {
14958            boolean printed = false;
14959            long now = SystemClock.uptimeMillis();
14960            for (int i=0; i<mProcessesToGc.size(); i++) {
14961                ProcessRecord proc = mProcessesToGc.get(i);
14962                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14963                    continue;
14964                }
14965                if (!printed) {
14966                    if (needSep) pw.println();
14967                    needSep = true;
14968                    pw.println("  Processes that are waiting to GC:");
14969                    printed = true;
14970                }
14971                pw.print("    Process "); pw.println(proc);
14972                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14973                        pw.print(", last gced=");
14974                        pw.print(now-proc.lastRequestedGc);
14975                        pw.print(" ms ago, last lowMem=");
14976                        pw.print(now-proc.lastLowMemory);
14977                        pw.println(" ms ago");
14978
14979            }
14980        }
14981        return needSep;
14982    }
14983
14984    void printOomLevel(PrintWriter pw, String name, int adj) {
14985        pw.print("    ");
14986        if (adj >= 0) {
14987            pw.print(' ');
14988            if (adj < 10) pw.print(' ');
14989        } else {
14990            if (adj > -10) pw.print(' ');
14991        }
14992        pw.print(adj);
14993        pw.print(": ");
14994        pw.print(name);
14995        pw.print(" (");
14996        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14997        pw.println(")");
14998    }
14999
15000    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15001            int opti, boolean dumpAll) {
15002        boolean needSep = false;
15003
15004        if (mLruProcesses.size() > 0) {
15005            if (needSep) pw.println();
15006            needSep = true;
15007            pw.println("  OOM levels:");
15008            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15009            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15010            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15011            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15012            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15013            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15014            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15015            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15016            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15017            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15018            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15019            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15020            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15021            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15022
15023            if (needSep) pw.println();
15024            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15025                    pw.print(" total, non-act at ");
15026                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15027                    pw.print(", non-svc at ");
15028                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15029                    pw.println("):");
15030            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15031            needSep = true;
15032        }
15033
15034        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15035
15036        pw.println();
15037        pw.println("  mHomeProcess: " + mHomeProcess);
15038        pw.println("  mPreviousProcess: " + mPreviousProcess);
15039        if (mHeavyWeightProcess != null) {
15040            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15041        }
15042
15043        return true;
15044    }
15045
15046    /**
15047     * There are three ways to call this:
15048     *  - no provider specified: dump all the providers
15049     *  - a flattened component name that matched an existing provider was specified as the
15050     *    first arg: dump that one provider
15051     *  - the first arg isn't the flattened component name of an existing provider:
15052     *    dump all providers whose component contains the first arg as a substring
15053     */
15054    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15055            int opti, boolean dumpAll) {
15056        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15057    }
15058
15059    static class ItemMatcher {
15060        ArrayList<ComponentName> components;
15061        ArrayList<String> strings;
15062        ArrayList<Integer> objects;
15063        boolean all;
15064
15065        ItemMatcher() {
15066            all = true;
15067        }
15068
15069        void build(String name) {
15070            ComponentName componentName = ComponentName.unflattenFromString(name);
15071            if (componentName != null) {
15072                if (components == null) {
15073                    components = new ArrayList<ComponentName>();
15074                }
15075                components.add(componentName);
15076                all = false;
15077            } else {
15078                int objectId = 0;
15079                // Not a '/' separated full component name; maybe an object ID?
15080                try {
15081                    objectId = Integer.parseInt(name, 16);
15082                    if (objects == null) {
15083                        objects = new ArrayList<Integer>();
15084                    }
15085                    objects.add(objectId);
15086                    all = false;
15087                } catch (RuntimeException e) {
15088                    // Not an integer; just do string match.
15089                    if (strings == null) {
15090                        strings = new ArrayList<String>();
15091                    }
15092                    strings.add(name);
15093                    all = false;
15094                }
15095            }
15096        }
15097
15098        int build(String[] args, int opti) {
15099            for (; opti<args.length; opti++) {
15100                String name = args[opti];
15101                if ("--".equals(name)) {
15102                    return opti+1;
15103                }
15104                build(name);
15105            }
15106            return opti;
15107        }
15108
15109        boolean match(Object object, ComponentName comp) {
15110            if (all) {
15111                return true;
15112            }
15113            if (components != null) {
15114                for (int i=0; i<components.size(); i++) {
15115                    if (components.get(i).equals(comp)) {
15116                        return true;
15117                    }
15118                }
15119            }
15120            if (objects != null) {
15121                for (int i=0; i<objects.size(); i++) {
15122                    if (System.identityHashCode(object) == objects.get(i)) {
15123                        return true;
15124                    }
15125                }
15126            }
15127            if (strings != null) {
15128                String flat = comp.flattenToString();
15129                for (int i=0; i<strings.size(); i++) {
15130                    if (flat.contains(strings.get(i))) {
15131                        return true;
15132                    }
15133                }
15134            }
15135            return false;
15136        }
15137    }
15138
15139    /**
15140     * There are three things that cmd can be:
15141     *  - a flattened component name that matches an existing activity
15142     *  - the cmd arg isn't the flattened component name of an existing activity:
15143     *    dump all activity whose component contains the cmd as a substring
15144     *  - A hex number of the ActivityRecord object instance.
15145     */
15146    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15147            int opti, boolean dumpAll) {
15148        ArrayList<ActivityRecord> activities;
15149
15150        synchronized (this) {
15151            activities = mStackSupervisor.getDumpActivitiesLocked(name);
15152        }
15153
15154        if (activities.size() <= 0) {
15155            return false;
15156        }
15157
15158        String[] newArgs = new String[args.length - opti];
15159        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15160
15161        TaskRecord lastTask = null;
15162        boolean needSep = false;
15163        for (int i=activities.size()-1; i>=0; i--) {
15164            ActivityRecord r = activities.get(i);
15165            if (needSep) {
15166                pw.println();
15167            }
15168            needSep = true;
15169            synchronized (this) {
15170                if (lastTask != r.task) {
15171                    lastTask = r.task;
15172                    pw.print("TASK "); pw.print(lastTask.affinity);
15173                            pw.print(" id="); pw.println(lastTask.taskId);
15174                    if (dumpAll) {
15175                        lastTask.dump(pw, "  ");
15176                    }
15177                }
15178            }
15179            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15180        }
15181        return true;
15182    }
15183
15184    /**
15185     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15186     * there is a thread associated with the activity.
15187     */
15188    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15189            final ActivityRecord r, String[] args, boolean dumpAll) {
15190        String innerPrefix = prefix + "  ";
15191        synchronized (this) {
15192            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15193                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15194                    pw.print(" pid=");
15195                    if (r.app != null) pw.println(r.app.pid);
15196                    else pw.println("(not running)");
15197            if (dumpAll) {
15198                r.dump(pw, innerPrefix);
15199            }
15200        }
15201        if (r.app != null && r.app.thread != null) {
15202            // flush anything that is already in the PrintWriter since the thread is going
15203            // to write to the file descriptor directly
15204            pw.flush();
15205            try {
15206                TransferPipe tp = new TransferPipe();
15207                try {
15208                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15209                            r.appToken, innerPrefix, args);
15210                    tp.go(fd);
15211                } finally {
15212                    tp.kill();
15213                }
15214            } catch (IOException e) {
15215                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15216            } catch (RemoteException e) {
15217                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15218            }
15219        }
15220    }
15221
15222    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15223            int opti, boolean dumpAll, String dumpPackage) {
15224        boolean needSep = false;
15225        boolean onlyHistory = false;
15226        boolean printedAnything = false;
15227
15228        if ("history".equals(dumpPackage)) {
15229            if (opti < args.length && "-s".equals(args[opti])) {
15230                dumpAll = false;
15231            }
15232            onlyHistory = true;
15233            dumpPackage = null;
15234        }
15235
15236        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15237        if (!onlyHistory && dumpAll) {
15238            if (mRegisteredReceivers.size() > 0) {
15239                boolean printed = false;
15240                Iterator it = mRegisteredReceivers.values().iterator();
15241                while (it.hasNext()) {
15242                    ReceiverList r = (ReceiverList)it.next();
15243                    if (dumpPackage != null && (r.app == null ||
15244                            !dumpPackage.equals(r.app.info.packageName))) {
15245                        continue;
15246                    }
15247                    if (!printed) {
15248                        pw.println("  Registered Receivers:");
15249                        needSep = true;
15250                        printed = true;
15251                        printedAnything = true;
15252                    }
15253                    pw.print("  * "); pw.println(r);
15254                    r.dump(pw, "    ");
15255                }
15256            }
15257
15258            if (mReceiverResolver.dump(pw, needSep ?
15259                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15260                    "    ", dumpPackage, false, false)) {
15261                needSep = true;
15262                printedAnything = true;
15263            }
15264        }
15265
15266        for (BroadcastQueue q : mBroadcastQueues) {
15267            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15268            printedAnything |= needSep;
15269        }
15270
15271        needSep = true;
15272
15273        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15274            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15275                if (needSep) {
15276                    pw.println();
15277                }
15278                needSep = true;
15279                printedAnything = true;
15280                pw.print("  Sticky broadcasts for user ");
15281                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15282                StringBuilder sb = new StringBuilder(128);
15283                for (Map.Entry<String, ArrayList<Intent>> ent
15284                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15285                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15286                    if (dumpAll) {
15287                        pw.println(":");
15288                        ArrayList<Intent> intents = ent.getValue();
15289                        final int N = intents.size();
15290                        for (int i=0; i<N; i++) {
15291                            sb.setLength(0);
15292                            sb.append("    Intent: ");
15293                            intents.get(i).toShortString(sb, false, true, false, false);
15294                            pw.println(sb.toString());
15295                            Bundle bundle = intents.get(i).getExtras();
15296                            if (bundle != null) {
15297                                pw.print("      ");
15298                                pw.println(bundle.toString());
15299                            }
15300                        }
15301                    } else {
15302                        pw.println("");
15303                    }
15304                }
15305            }
15306        }
15307
15308        if (!onlyHistory && dumpAll) {
15309            pw.println();
15310            for (BroadcastQueue queue : mBroadcastQueues) {
15311                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15312                        + queue.mBroadcastsScheduled);
15313            }
15314            pw.println("  mHandler:");
15315            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15316            needSep = true;
15317            printedAnything = true;
15318        }
15319
15320        if (!printedAnything) {
15321            pw.println("  (nothing)");
15322        }
15323    }
15324
15325    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15326            int opti, boolean dumpAll, String dumpPackage) {
15327        if (mCurBroadcastStats == null) {
15328            return;
15329        }
15330
15331        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15332        final long now = SystemClock.elapsedRealtime();
15333        if (mLastBroadcastStats != null) {
15334            pw.print("  Last stats (from ");
15335            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15336            pw.print(" to ");
15337            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15338            pw.print(", ");
15339            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15340                    - mLastBroadcastStats.mStartUptime, pw);
15341            pw.println(" uptime):");
15342            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15343                pw.println("    (nothing)");
15344            }
15345            pw.println();
15346        }
15347        pw.print("  Current stats (from ");
15348        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15349        pw.print(" to now, ");
15350        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15351                - mCurBroadcastStats.mStartUptime, pw);
15352        pw.println(" uptime):");
15353        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15354            pw.println("    (nothing)");
15355        }
15356    }
15357
15358    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15359            int opti, boolean fullCheckin, String dumpPackage) {
15360        if (mCurBroadcastStats == null) {
15361            return;
15362        }
15363
15364        if (mLastBroadcastStats != null) {
15365            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15366            if (fullCheckin) {
15367                mLastBroadcastStats = null;
15368                return;
15369            }
15370        }
15371        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15372        if (fullCheckin) {
15373            mCurBroadcastStats = null;
15374        }
15375    }
15376
15377    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15378            int opti, boolean dumpAll, String dumpPackage) {
15379        boolean needSep;
15380        boolean printedAnything = false;
15381
15382        ItemMatcher matcher = new ItemMatcher();
15383        matcher.build(args, opti);
15384
15385        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15386
15387        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15388        printedAnything |= needSep;
15389
15390        if (mLaunchingProviders.size() > 0) {
15391            boolean printed = false;
15392            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15393                ContentProviderRecord r = mLaunchingProviders.get(i);
15394                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15395                    continue;
15396                }
15397                if (!printed) {
15398                    if (needSep) pw.println();
15399                    needSep = true;
15400                    pw.println("  Launching content providers:");
15401                    printed = true;
15402                    printedAnything = true;
15403                }
15404                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15405                        pw.println(r);
15406            }
15407        }
15408
15409        if (!printedAnything) {
15410            pw.println("  (nothing)");
15411        }
15412    }
15413
15414    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15415            int opti, boolean dumpAll, String dumpPackage) {
15416        boolean needSep = false;
15417        boolean printedAnything = false;
15418
15419        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15420
15421        if (mGrantedUriPermissions.size() > 0) {
15422            boolean printed = false;
15423            int dumpUid = -2;
15424            if (dumpPackage != null) {
15425                try {
15426                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15427                            MATCH_UNINSTALLED_PACKAGES, 0);
15428                } catch (NameNotFoundException e) {
15429                    dumpUid = -1;
15430                }
15431            }
15432            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15433                int uid = mGrantedUriPermissions.keyAt(i);
15434                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15435                    continue;
15436                }
15437                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15438                if (!printed) {
15439                    if (needSep) pw.println();
15440                    needSep = true;
15441                    pw.println("  Granted Uri Permissions:");
15442                    printed = true;
15443                    printedAnything = true;
15444                }
15445                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15446                for (UriPermission perm : perms.values()) {
15447                    pw.print("    "); pw.println(perm);
15448                    if (dumpAll) {
15449                        perm.dump(pw, "      ");
15450                    }
15451                }
15452            }
15453        }
15454
15455        if (!printedAnything) {
15456            pw.println("  (nothing)");
15457        }
15458    }
15459
15460    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15461            int opti, boolean dumpAll, String dumpPackage) {
15462        boolean printed = false;
15463
15464        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15465
15466        if (mIntentSenderRecords.size() > 0) {
15467            Iterator<WeakReference<PendingIntentRecord>> it
15468                    = mIntentSenderRecords.values().iterator();
15469            while (it.hasNext()) {
15470                WeakReference<PendingIntentRecord> ref = it.next();
15471                PendingIntentRecord rec = ref != null ? ref.get(): null;
15472                if (dumpPackage != null && (rec == null
15473                        || !dumpPackage.equals(rec.key.packageName))) {
15474                    continue;
15475                }
15476                printed = true;
15477                if (rec != null) {
15478                    pw.print("  * "); pw.println(rec);
15479                    if (dumpAll) {
15480                        rec.dump(pw, "    ");
15481                    }
15482                } else {
15483                    pw.print("  * "); pw.println(ref);
15484                }
15485            }
15486        }
15487
15488        if (!printed) {
15489            pw.println("  (nothing)");
15490        }
15491    }
15492
15493    private static final int dumpProcessList(PrintWriter pw,
15494            ActivityManagerService service, List list,
15495            String prefix, String normalLabel, String persistentLabel,
15496            String dumpPackage) {
15497        int numPers = 0;
15498        final int N = list.size()-1;
15499        for (int i=N; i>=0; i--) {
15500            ProcessRecord r = (ProcessRecord)list.get(i);
15501            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15502                continue;
15503            }
15504            pw.println(String.format("%s%s #%2d: %s",
15505                    prefix, (r.persistent ? persistentLabel : normalLabel),
15506                    i, r.toString()));
15507            if (r.persistent) {
15508                numPers++;
15509            }
15510        }
15511        return numPers;
15512    }
15513
15514    private static final boolean dumpProcessOomList(PrintWriter pw,
15515            ActivityManagerService service, List<ProcessRecord> origList,
15516            String prefix, String normalLabel, String persistentLabel,
15517            boolean inclDetails, String dumpPackage) {
15518
15519        ArrayList<Pair<ProcessRecord, Integer>> list
15520                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15521        for (int i=0; i<origList.size(); i++) {
15522            ProcessRecord r = origList.get(i);
15523            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15524                continue;
15525            }
15526            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15527        }
15528
15529        if (list.size() <= 0) {
15530            return false;
15531        }
15532
15533        Comparator<Pair<ProcessRecord, Integer>> comparator
15534                = new Comparator<Pair<ProcessRecord, Integer>>() {
15535            @Override
15536            public int compare(Pair<ProcessRecord, Integer> object1,
15537                    Pair<ProcessRecord, Integer> object2) {
15538                if (object1.first.setAdj != object2.first.setAdj) {
15539                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15540                }
15541                if (object1.first.setProcState != object2.first.setProcState) {
15542                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15543                }
15544                if (object1.second.intValue() != object2.second.intValue()) {
15545                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15546                }
15547                return 0;
15548            }
15549        };
15550
15551        Collections.sort(list, comparator);
15552
15553        final long curRealtime = SystemClock.elapsedRealtime();
15554        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15555        final long curUptime = SystemClock.uptimeMillis();
15556        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15557
15558        for (int i=list.size()-1; i>=0; i--) {
15559            ProcessRecord r = list.get(i).first;
15560            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15561            char schedGroup;
15562            switch (r.setSchedGroup) {
15563                case ProcessList.SCHED_GROUP_BACKGROUND:
15564                    schedGroup = 'B';
15565                    break;
15566                case ProcessList.SCHED_GROUP_DEFAULT:
15567                    schedGroup = 'F';
15568                    break;
15569                case ProcessList.SCHED_GROUP_TOP_APP:
15570                    schedGroup = 'T';
15571                    break;
15572                default:
15573                    schedGroup = '?';
15574                    break;
15575            }
15576            char foreground;
15577            if (r.foregroundActivities) {
15578                foreground = 'A';
15579            } else if (r.foregroundServices) {
15580                foreground = 'S';
15581            } else {
15582                foreground = ' ';
15583            }
15584            String procState = ProcessList.makeProcStateString(r.curProcState);
15585            pw.print(prefix);
15586            pw.print(r.persistent ? persistentLabel : normalLabel);
15587            pw.print(" #");
15588            int num = (origList.size()-1)-list.get(i).second;
15589            if (num < 10) pw.print(' ');
15590            pw.print(num);
15591            pw.print(": ");
15592            pw.print(oomAdj);
15593            pw.print(' ');
15594            pw.print(schedGroup);
15595            pw.print('/');
15596            pw.print(foreground);
15597            pw.print('/');
15598            pw.print(procState);
15599            pw.print(" trm:");
15600            if (r.trimMemoryLevel < 10) pw.print(' ');
15601            pw.print(r.trimMemoryLevel);
15602            pw.print(' ');
15603            pw.print(r.toShortString());
15604            pw.print(" (");
15605            pw.print(r.adjType);
15606            pw.println(')');
15607            if (r.adjSource != null || r.adjTarget != null) {
15608                pw.print(prefix);
15609                pw.print("    ");
15610                if (r.adjTarget instanceof ComponentName) {
15611                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15612                } else if (r.adjTarget != null) {
15613                    pw.print(r.adjTarget.toString());
15614                } else {
15615                    pw.print("{null}");
15616                }
15617                pw.print("<=");
15618                if (r.adjSource instanceof ProcessRecord) {
15619                    pw.print("Proc{");
15620                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15621                    pw.println("}");
15622                } else if (r.adjSource != null) {
15623                    pw.println(r.adjSource.toString());
15624                } else {
15625                    pw.println("{null}");
15626                }
15627            }
15628            if (inclDetails) {
15629                pw.print(prefix);
15630                pw.print("    ");
15631                pw.print("oom: max="); pw.print(r.maxAdj);
15632                pw.print(" curRaw="); pw.print(r.curRawAdj);
15633                pw.print(" setRaw="); pw.print(r.setRawAdj);
15634                pw.print(" cur="); pw.print(r.curAdj);
15635                pw.print(" set="); pw.println(r.setAdj);
15636                pw.print(prefix);
15637                pw.print("    ");
15638                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15639                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15640                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15641                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15642                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15643                pw.println();
15644                pw.print(prefix);
15645                pw.print("    ");
15646                pw.print("cached="); pw.print(r.cached);
15647                pw.print(" empty="); pw.print(r.empty);
15648                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15649
15650                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15651                    if (r.lastWakeTime != 0) {
15652                        long wtime;
15653                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15654                        synchronized (stats) {
15655                            wtime = stats.getProcessWakeTime(r.info.uid,
15656                                    r.pid, curRealtime);
15657                        }
15658                        long timeUsed = wtime - r.lastWakeTime;
15659                        pw.print(prefix);
15660                        pw.print("    ");
15661                        pw.print("keep awake over ");
15662                        TimeUtils.formatDuration(realtimeSince, pw);
15663                        pw.print(" used ");
15664                        TimeUtils.formatDuration(timeUsed, pw);
15665                        pw.print(" (");
15666                        pw.print((timeUsed*100)/realtimeSince);
15667                        pw.println("%)");
15668                    }
15669                    if (r.lastCpuTime != 0) {
15670                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15671                        pw.print(prefix);
15672                        pw.print("    ");
15673                        pw.print("run cpu over ");
15674                        TimeUtils.formatDuration(uptimeSince, pw);
15675                        pw.print(" used ");
15676                        TimeUtils.formatDuration(timeUsed, pw);
15677                        pw.print(" (");
15678                        pw.print((timeUsed*100)/uptimeSince);
15679                        pw.println("%)");
15680                    }
15681                }
15682            }
15683        }
15684        return true;
15685    }
15686
15687    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15688            String[] args) {
15689        ArrayList<ProcessRecord> procs;
15690        synchronized (this) {
15691            if (args != null && args.length > start
15692                    && args[start].charAt(0) != '-') {
15693                procs = new ArrayList<ProcessRecord>();
15694                int pid = -1;
15695                try {
15696                    pid = Integer.parseInt(args[start]);
15697                } catch (NumberFormatException e) {
15698                }
15699                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15700                    ProcessRecord proc = mLruProcesses.get(i);
15701                    if (proc.pid == pid) {
15702                        procs.add(proc);
15703                    } else if (allPkgs && proc.pkgList != null
15704                            && proc.pkgList.containsKey(args[start])) {
15705                        procs.add(proc);
15706                    } else if (proc.processName.equals(args[start])) {
15707                        procs.add(proc);
15708                    }
15709                }
15710                if (procs.size() <= 0) {
15711                    return null;
15712                }
15713            } else {
15714                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15715            }
15716        }
15717        return procs;
15718    }
15719
15720    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15721            PrintWriter pw, String[] args) {
15722        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15723        if (procs == null) {
15724            pw.println("No process found for: " + args[0]);
15725            return;
15726        }
15727
15728        long uptime = SystemClock.uptimeMillis();
15729        long realtime = SystemClock.elapsedRealtime();
15730        pw.println("Applications Graphics Acceleration Info:");
15731        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15732
15733        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15734            ProcessRecord r = procs.get(i);
15735            if (r.thread != null) {
15736                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15737                pw.flush();
15738                try {
15739                    TransferPipe tp = new TransferPipe();
15740                    try {
15741                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15742                        tp.go(fd);
15743                    } finally {
15744                        tp.kill();
15745                    }
15746                } catch (IOException e) {
15747                    pw.println("Failure while dumping the app: " + r);
15748                    pw.flush();
15749                } catch (RemoteException e) {
15750                    pw.println("Got a RemoteException while dumping the app " + r);
15751                    pw.flush();
15752                }
15753            }
15754        }
15755    }
15756
15757    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15758        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15759        if (procs == null) {
15760            pw.println("No process found for: " + args[0]);
15761            return;
15762        }
15763
15764        pw.println("Applications Database Info:");
15765
15766        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15767            ProcessRecord r = procs.get(i);
15768            if (r.thread != null) {
15769                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15770                pw.flush();
15771                try {
15772                    TransferPipe tp = new TransferPipe();
15773                    try {
15774                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15775                        tp.go(fd);
15776                    } finally {
15777                        tp.kill();
15778                    }
15779                } catch (IOException e) {
15780                    pw.println("Failure while dumping the app: " + r);
15781                    pw.flush();
15782                } catch (RemoteException e) {
15783                    pw.println("Got a RemoteException while dumping the app " + r);
15784                    pw.flush();
15785                }
15786            }
15787        }
15788    }
15789
15790    final static class MemItem {
15791        final boolean isProc;
15792        final String label;
15793        final String shortLabel;
15794        final long pss;
15795        final long swapPss;
15796        final int id;
15797        final boolean hasActivities;
15798        ArrayList<MemItem> subitems;
15799
15800        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15801                boolean _hasActivities) {
15802            isProc = true;
15803            label = _label;
15804            shortLabel = _shortLabel;
15805            pss = _pss;
15806            swapPss = _swapPss;
15807            id = _id;
15808            hasActivities = _hasActivities;
15809        }
15810
15811        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15812            isProc = false;
15813            label = _label;
15814            shortLabel = _shortLabel;
15815            pss = _pss;
15816            swapPss = _swapPss;
15817            id = _id;
15818            hasActivities = false;
15819        }
15820    }
15821
15822    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15823            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15824        if (sort && !isCompact) {
15825            Collections.sort(items, new Comparator<MemItem>() {
15826                @Override
15827                public int compare(MemItem lhs, MemItem rhs) {
15828                    if (lhs.pss < rhs.pss) {
15829                        return 1;
15830                    } else if (lhs.pss > rhs.pss) {
15831                        return -1;
15832                    }
15833                    return 0;
15834                }
15835            });
15836        }
15837
15838        for (int i=0; i<items.size(); i++) {
15839            MemItem mi = items.get(i);
15840            if (!isCompact) {
15841                if (dumpSwapPss) {
15842                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15843                            mi.label, stringifyKBSize(mi.swapPss));
15844                } else {
15845                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15846                }
15847            } else if (mi.isProc) {
15848                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15849                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15850                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15851                pw.println(mi.hasActivities ? ",a" : ",e");
15852            } else {
15853                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15854                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15855            }
15856            if (mi.subitems != null) {
15857                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15858                        true, isCompact, dumpSwapPss);
15859            }
15860        }
15861    }
15862
15863    // These are in KB.
15864    static final long[] DUMP_MEM_BUCKETS = new long[] {
15865        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15866        120*1024, 160*1024, 200*1024,
15867        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15868        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15869    };
15870
15871    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15872            boolean stackLike) {
15873        int start = label.lastIndexOf('.');
15874        if (start >= 0) start++;
15875        else start = 0;
15876        int end = label.length();
15877        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15878            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15879                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15880                out.append(bucket);
15881                out.append(stackLike ? "MB." : "MB ");
15882                out.append(label, start, end);
15883                return;
15884            }
15885        }
15886        out.append(memKB/1024);
15887        out.append(stackLike ? "MB." : "MB ");
15888        out.append(label, start, end);
15889    }
15890
15891    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15892            ProcessList.NATIVE_ADJ,
15893            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15894            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15895            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15896            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15897            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15898            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15899    };
15900    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15901            "Native",
15902            "System", "Persistent", "Persistent Service", "Foreground",
15903            "Visible", "Perceptible",
15904            "Heavy Weight", "Backup",
15905            "A Services", "Home",
15906            "Previous", "B Services", "Cached"
15907    };
15908    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15909            "native",
15910            "sys", "pers", "persvc", "fore",
15911            "vis", "percept",
15912            "heavy", "backup",
15913            "servicea", "home",
15914            "prev", "serviceb", "cached"
15915    };
15916
15917    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15918            long realtime, boolean isCheckinRequest, boolean isCompact) {
15919        if (isCompact) {
15920            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15921        }
15922        if (isCheckinRequest || isCompact) {
15923            // short checkin version
15924            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15925        } else {
15926            pw.println("Applications Memory Usage (in Kilobytes):");
15927            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15928        }
15929    }
15930
15931    private static final int KSM_SHARED = 0;
15932    private static final int KSM_SHARING = 1;
15933    private static final int KSM_UNSHARED = 2;
15934    private static final int KSM_VOLATILE = 3;
15935
15936    private final long[] getKsmInfo() {
15937        long[] longOut = new long[4];
15938        final int[] SINGLE_LONG_FORMAT = new int[] {
15939            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15940        };
15941        long[] longTmp = new long[1];
15942        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15943                SINGLE_LONG_FORMAT, null, longTmp, null);
15944        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15945        longTmp[0] = 0;
15946        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15947                SINGLE_LONG_FORMAT, null, longTmp, null);
15948        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15949        longTmp[0] = 0;
15950        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15951                SINGLE_LONG_FORMAT, null, longTmp, null);
15952        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15953        longTmp[0] = 0;
15954        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15955                SINGLE_LONG_FORMAT, null, longTmp, null);
15956        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15957        return longOut;
15958    }
15959
15960    private static String stringifySize(long size, int order) {
15961        Locale locale = Locale.US;
15962        switch (order) {
15963            case 1:
15964                return String.format(locale, "%,13d", size);
15965            case 1024:
15966                return String.format(locale, "%,9dK", size / 1024);
15967            case 1024 * 1024:
15968                return String.format(locale, "%,5dM", size / 1024 / 1024);
15969            case 1024 * 1024 * 1024:
15970                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15971            default:
15972                throw new IllegalArgumentException("Invalid size order");
15973        }
15974    }
15975
15976    private static String stringifyKBSize(long size) {
15977        return stringifySize(size * 1024, 1024);
15978    }
15979
15980    // Update this version number in case you change the 'compact' format
15981    private static final int MEMINFO_COMPACT_VERSION = 1;
15982
15983    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15984            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15985        boolean dumpDetails = false;
15986        boolean dumpFullDetails = false;
15987        boolean dumpDalvik = false;
15988        boolean dumpSummaryOnly = false;
15989        boolean dumpUnreachable = false;
15990        boolean oomOnly = false;
15991        boolean isCompact = false;
15992        boolean localOnly = false;
15993        boolean packages = false;
15994        boolean isCheckinRequest = false;
15995        boolean dumpSwapPss = false;
15996
15997        int opti = 0;
15998        while (opti < args.length) {
15999            String opt = args[opti];
16000            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16001                break;
16002            }
16003            opti++;
16004            if ("-a".equals(opt)) {
16005                dumpDetails = true;
16006                dumpFullDetails = true;
16007                dumpDalvik = true;
16008                dumpSwapPss = true;
16009            } else if ("-d".equals(opt)) {
16010                dumpDalvik = true;
16011            } else if ("-c".equals(opt)) {
16012                isCompact = true;
16013            } else if ("-s".equals(opt)) {
16014                dumpDetails = true;
16015                dumpSummaryOnly = true;
16016            } else if ("-S".equals(opt)) {
16017                dumpSwapPss = true;
16018            } else if ("--unreachable".equals(opt)) {
16019                dumpUnreachable = true;
16020            } else if ("--oom".equals(opt)) {
16021                oomOnly = true;
16022            } else if ("--local".equals(opt)) {
16023                localOnly = true;
16024            } else if ("--package".equals(opt)) {
16025                packages = true;
16026            } else if ("--checkin".equals(opt)) {
16027                isCheckinRequest = true;
16028
16029            } else if ("-h".equals(opt)) {
16030                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16031                pw.println("  -a: include all available information for each process.");
16032                pw.println("  -d: include dalvik details.");
16033                pw.println("  -c: dump in a compact machine-parseable representation.");
16034                pw.println("  -s: dump only summary of application memory usage.");
16035                pw.println("  -S: dump also SwapPss.");
16036                pw.println("  --oom: only show processes organized by oom adj.");
16037                pw.println("  --local: only collect details locally, don't call process.");
16038                pw.println("  --package: interpret process arg as package, dumping all");
16039                pw.println("             processes that have loaded that package.");
16040                pw.println("  --checkin: dump data for a checkin");
16041                pw.println("If [process] is specified it can be the name or ");
16042                pw.println("pid of a specific process to dump.");
16043                return;
16044            } else {
16045                pw.println("Unknown argument: " + opt + "; use -h for help");
16046            }
16047        }
16048
16049        long uptime = SystemClock.uptimeMillis();
16050        long realtime = SystemClock.elapsedRealtime();
16051        final long[] tmpLong = new long[1];
16052
16053        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16054        if (procs == null) {
16055            // No Java processes.  Maybe they want to print a native process.
16056            if (args != null && args.length > opti
16057                    && args[opti].charAt(0) != '-') {
16058                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16059                        = new ArrayList<ProcessCpuTracker.Stats>();
16060                updateCpuStatsNow();
16061                int findPid = -1;
16062                try {
16063                    findPid = Integer.parseInt(args[opti]);
16064                } catch (NumberFormatException e) {
16065                }
16066                synchronized (mProcessCpuTracker) {
16067                    final int N = mProcessCpuTracker.countStats();
16068                    for (int i=0; i<N; i++) {
16069                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16070                        if (st.pid == findPid || (st.baseName != null
16071                                && st.baseName.equals(args[opti]))) {
16072                            nativeProcs.add(st);
16073                        }
16074                    }
16075                }
16076                if (nativeProcs.size() > 0) {
16077                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16078                            isCompact);
16079                    Debug.MemoryInfo mi = null;
16080                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16081                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16082                        final int pid = r.pid;
16083                        if (!isCheckinRequest && dumpDetails) {
16084                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16085                        }
16086                        if (mi == null) {
16087                            mi = new Debug.MemoryInfo();
16088                        }
16089                        if (dumpDetails || (!brief && !oomOnly)) {
16090                            Debug.getMemoryInfo(pid, mi);
16091                        } else {
16092                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16093                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16094                        }
16095                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16096                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16097                        if (isCheckinRequest) {
16098                            pw.println();
16099                        }
16100                    }
16101                    return;
16102                }
16103            }
16104            pw.println("No process found for: " + args[opti]);
16105            return;
16106        }
16107
16108        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16109            dumpDetails = true;
16110        }
16111
16112        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16113
16114        String[] innerArgs = new String[args.length-opti];
16115        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16116
16117        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16118        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16119        long nativePss = 0;
16120        long nativeSwapPss = 0;
16121        long dalvikPss = 0;
16122        long dalvikSwapPss = 0;
16123        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16124                EmptyArray.LONG;
16125        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16126                EmptyArray.LONG;
16127        long otherPss = 0;
16128        long otherSwapPss = 0;
16129        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16130        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16131
16132        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16133        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16134        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16135                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16136
16137        long totalPss = 0;
16138        long totalSwapPss = 0;
16139        long cachedPss = 0;
16140        long cachedSwapPss = 0;
16141        boolean hasSwapPss = false;
16142
16143        Debug.MemoryInfo mi = null;
16144        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16145            final ProcessRecord r = procs.get(i);
16146            final IApplicationThread thread;
16147            final int pid;
16148            final int oomAdj;
16149            final boolean hasActivities;
16150            synchronized (this) {
16151                thread = r.thread;
16152                pid = r.pid;
16153                oomAdj = r.getSetAdjWithServices();
16154                hasActivities = r.activities.size() > 0;
16155            }
16156            if (thread != null) {
16157                if (!isCheckinRequest && dumpDetails) {
16158                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16159                }
16160                if (mi == null) {
16161                    mi = new Debug.MemoryInfo();
16162                }
16163                if (dumpDetails || (!brief && !oomOnly)) {
16164                    Debug.getMemoryInfo(pid, mi);
16165                    hasSwapPss = mi.hasSwappedOutPss;
16166                } else {
16167                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16168                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16169                }
16170                if (dumpDetails) {
16171                    if (localOnly) {
16172                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16173                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16174                        if (isCheckinRequest) {
16175                            pw.println();
16176                        }
16177                    } else {
16178                        try {
16179                            pw.flush();
16180                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16181                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16182                        } catch (RemoteException e) {
16183                            if (!isCheckinRequest) {
16184                                pw.println("Got RemoteException!");
16185                                pw.flush();
16186                            }
16187                        }
16188                    }
16189                }
16190
16191                final long myTotalPss = mi.getTotalPss();
16192                final long myTotalUss = mi.getTotalUss();
16193                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16194
16195                synchronized (this) {
16196                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16197                        // Record this for posterity if the process has been stable.
16198                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16199                    }
16200                }
16201
16202                if (!isCheckinRequest && mi != null) {
16203                    totalPss += myTotalPss;
16204                    totalSwapPss += myTotalSwapPss;
16205                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16206                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16207                            myTotalSwapPss, pid, hasActivities);
16208                    procMems.add(pssItem);
16209                    procMemsMap.put(pid, pssItem);
16210
16211                    nativePss += mi.nativePss;
16212                    nativeSwapPss += mi.nativeSwappedOutPss;
16213                    dalvikPss += mi.dalvikPss;
16214                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16215                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16216                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16217                        dalvikSubitemSwapPss[j] +=
16218                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16219                    }
16220                    otherPss += mi.otherPss;
16221                    otherSwapPss += mi.otherSwappedOutPss;
16222                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16223                        long mem = mi.getOtherPss(j);
16224                        miscPss[j] += mem;
16225                        otherPss -= mem;
16226                        mem = mi.getOtherSwappedOutPss(j);
16227                        miscSwapPss[j] += mem;
16228                        otherSwapPss -= mem;
16229                    }
16230
16231                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16232                        cachedPss += myTotalPss;
16233                        cachedSwapPss += myTotalSwapPss;
16234                    }
16235
16236                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16237                        if (oomIndex == (oomPss.length - 1)
16238                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16239                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16240                            oomPss[oomIndex] += myTotalPss;
16241                            oomSwapPss[oomIndex] += myTotalSwapPss;
16242                            if (oomProcs[oomIndex] == null) {
16243                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16244                            }
16245                            oomProcs[oomIndex].add(pssItem);
16246                            break;
16247                        }
16248                    }
16249                }
16250            }
16251        }
16252
16253        long nativeProcTotalPss = 0;
16254
16255        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16256            // If we are showing aggregations, also look for native processes to
16257            // include so that our aggregations are more accurate.
16258            updateCpuStatsNow();
16259            mi = null;
16260            synchronized (mProcessCpuTracker) {
16261                final int N = mProcessCpuTracker.countStats();
16262                for (int i=0; i<N; i++) {
16263                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16264                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16265                        if (mi == null) {
16266                            mi = new Debug.MemoryInfo();
16267                        }
16268                        if (!brief && !oomOnly) {
16269                            Debug.getMemoryInfo(st.pid, mi);
16270                        } else {
16271                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16272                            mi.nativePrivateDirty = (int)tmpLong[0];
16273                        }
16274
16275                        final long myTotalPss = mi.getTotalPss();
16276                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16277                        totalPss += myTotalPss;
16278                        nativeProcTotalPss += myTotalPss;
16279
16280                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16281                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16282                        procMems.add(pssItem);
16283
16284                        nativePss += mi.nativePss;
16285                        nativeSwapPss += mi.nativeSwappedOutPss;
16286                        dalvikPss += mi.dalvikPss;
16287                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16288                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16289                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16290                            dalvikSubitemSwapPss[j] +=
16291                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16292                        }
16293                        otherPss += mi.otherPss;
16294                        otherSwapPss += mi.otherSwappedOutPss;
16295                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16296                            long mem = mi.getOtherPss(j);
16297                            miscPss[j] += mem;
16298                            otherPss -= mem;
16299                            mem = mi.getOtherSwappedOutPss(j);
16300                            miscSwapPss[j] += mem;
16301                            otherSwapPss -= mem;
16302                        }
16303                        oomPss[0] += myTotalPss;
16304                        oomSwapPss[0] += myTotalSwapPss;
16305                        if (oomProcs[0] == null) {
16306                            oomProcs[0] = new ArrayList<MemItem>();
16307                        }
16308                        oomProcs[0].add(pssItem);
16309                    }
16310                }
16311            }
16312
16313            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16314
16315            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16316            final MemItem dalvikItem =
16317                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16318            if (dalvikSubitemPss.length > 0) {
16319                dalvikItem.subitems = new ArrayList<MemItem>();
16320                for (int j=0; j<dalvikSubitemPss.length; j++) {
16321                    final String name = Debug.MemoryInfo.getOtherLabel(
16322                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16323                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16324                                    dalvikSubitemSwapPss[j], j));
16325                }
16326            }
16327            catMems.add(dalvikItem);
16328            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16329            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16330                String label = Debug.MemoryInfo.getOtherLabel(j);
16331                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16332            }
16333
16334            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16335            for (int j=0; j<oomPss.length; j++) {
16336                if (oomPss[j] != 0) {
16337                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16338                            : DUMP_MEM_OOM_LABEL[j];
16339                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16340                            DUMP_MEM_OOM_ADJ[j]);
16341                    item.subitems = oomProcs[j];
16342                    oomMems.add(item);
16343                }
16344            }
16345
16346            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16347            if (!brief && !oomOnly && !isCompact) {
16348                pw.println();
16349                pw.println("Total PSS by process:");
16350                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16351                pw.println();
16352            }
16353            if (!isCompact) {
16354                pw.println("Total PSS by OOM adjustment:");
16355            }
16356            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16357            if (!brief && !oomOnly) {
16358                PrintWriter out = categoryPw != null ? categoryPw : pw;
16359                if (!isCompact) {
16360                    out.println();
16361                    out.println("Total PSS by category:");
16362                }
16363                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16364            }
16365            if (!isCompact) {
16366                pw.println();
16367            }
16368            MemInfoReader memInfo = new MemInfoReader();
16369            memInfo.readMemInfo();
16370            if (nativeProcTotalPss > 0) {
16371                synchronized (this) {
16372                    final long cachedKb = memInfo.getCachedSizeKb();
16373                    final long freeKb = memInfo.getFreeSizeKb();
16374                    final long zramKb = memInfo.getZramTotalSizeKb();
16375                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16376                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16377                            kernelKb*1024, nativeProcTotalPss*1024);
16378                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16379                            nativeProcTotalPss);
16380                }
16381            }
16382            if (!brief) {
16383                if (!isCompact) {
16384                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16385                    pw.print(" (status ");
16386                    switch (mLastMemoryLevel) {
16387                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16388                            pw.println("normal)");
16389                            break;
16390                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16391                            pw.println("moderate)");
16392                            break;
16393                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16394                            pw.println("low)");
16395                            break;
16396                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16397                            pw.println("critical)");
16398                            break;
16399                        default:
16400                            pw.print(mLastMemoryLevel);
16401                            pw.println(")");
16402                            break;
16403                    }
16404                    pw.print(" Free RAM: ");
16405                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16406                            + memInfo.getFreeSizeKb()));
16407                    pw.print(" (");
16408                    pw.print(stringifyKBSize(cachedPss));
16409                    pw.print(" cached pss + ");
16410                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16411                    pw.print(" cached kernel + ");
16412                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16413                    pw.println(" free)");
16414                } else {
16415                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16416                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16417                            + memInfo.getFreeSizeKb()); pw.print(",");
16418                    pw.println(totalPss - cachedPss);
16419                }
16420            }
16421            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16422                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16423                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16424            if (!isCompact) {
16425                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16426                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16427                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16428                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16429                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16430            } else {
16431                pw.print("lostram,"); pw.println(lostRAM);
16432            }
16433            if (!brief) {
16434                if (memInfo.getZramTotalSizeKb() != 0) {
16435                    if (!isCompact) {
16436                        pw.print("     ZRAM: ");
16437                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16438                                pw.print(" physical used for ");
16439                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16440                                        - memInfo.getSwapFreeSizeKb()));
16441                                pw.print(" in swap (");
16442                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16443                                pw.println(" total swap)");
16444                    } else {
16445                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16446                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16447                                pw.println(memInfo.getSwapFreeSizeKb());
16448                    }
16449                }
16450                final long[] ksm = getKsmInfo();
16451                if (!isCompact) {
16452                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16453                            || ksm[KSM_VOLATILE] != 0) {
16454                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16455                                pw.print(" saved from shared ");
16456                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16457                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16458                                pw.print(" unshared; ");
16459                                pw.print(stringifyKBSize(
16460                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16461                    }
16462                    pw.print("   Tuning: ");
16463                    pw.print(ActivityManager.staticGetMemoryClass());
16464                    pw.print(" (large ");
16465                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16466                    pw.print("), oom ");
16467                    pw.print(stringifySize(
16468                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16469                    pw.print(", restore limit ");
16470                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16471                    if (ActivityManager.isLowRamDeviceStatic()) {
16472                        pw.print(" (low-ram)");
16473                    }
16474                    if (ActivityManager.isHighEndGfx()) {
16475                        pw.print(" (high-end-gfx)");
16476                    }
16477                    pw.println();
16478                } else {
16479                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16480                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16481                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16482                    pw.print("tuning,");
16483                    pw.print(ActivityManager.staticGetMemoryClass());
16484                    pw.print(',');
16485                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16486                    pw.print(',');
16487                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16488                    if (ActivityManager.isLowRamDeviceStatic()) {
16489                        pw.print(",low-ram");
16490                    }
16491                    if (ActivityManager.isHighEndGfx()) {
16492                        pw.print(",high-end-gfx");
16493                    }
16494                    pw.println();
16495                }
16496            }
16497        }
16498    }
16499
16500    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16501            long memtrack, String name) {
16502        sb.append("  ");
16503        sb.append(ProcessList.makeOomAdjString(oomAdj));
16504        sb.append(' ');
16505        sb.append(ProcessList.makeProcStateString(procState));
16506        sb.append(' ');
16507        ProcessList.appendRamKb(sb, pss);
16508        sb.append(": ");
16509        sb.append(name);
16510        if (memtrack > 0) {
16511            sb.append(" (");
16512            sb.append(stringifyKBSize(memtrack));
16513            sb.append(" memtrack)");
16514        }
16515    }
16516
16517    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16518        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16519        sb.append(" (pid ");
16520        sb.append(mi.pid);
16521        sb.append(") ");
16522        sb.append(mi.adjType);
16523        sb.append('\n');
16524        if (mi.adjReason != null) {
16525            sb.append("                      ");
16526            sb.append(mi.adjReason);
16527            sb.append('\n');
16528        }
16529    }
16530
16531    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16532        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16533        for (int i=0, N=memInfos.size(); i<N; i++) {
16534            ProcessMemInfo mi = memInfos.get(i);
16535            infoMap.put(mi.pid, mi);
16536        }
16537        updateCpuStatsNow();
16538        long[] memtrackTmp = new long[1];
16539        final List<ProcessCpuTracker.Stats> stats;
16540        // Get a list of Stats that have vsize > 0
16541        synchronized (mProcessCpuTracker) {
16542            stats = mProcessCpuTracker.getStats((st) -> {
16543                return st.vsize > 0;
16544            });
16545        }
16546        final int statsCount = stats.size();
16547        for (int i = 0; i < statsCount; i++) {
16548            ProcessCpuTracker.Stats st = stats.get(i);
16549            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16550            if (pss > 0) {
16551                if (infoMap.indexOfKey(st.pid) < 0) {
16552                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16553                            ProcessList.NATIVE_ADJ, -1, "native", null);
16554                    mi.pss = pss;
16555                    mi.memtrack = memtrackTmp[0];
16556                    memInfos.add(mi);
16557                }
16558            }
16559        }
16560
16561        long totalPss = 0;
16562        long totalMemtrack = 0;
16563        for (int i=0, N=memInfos.size(); i<N; i++) {
16564            ProcessMemInfo mi = memInfos.get(i);
16565            if (mi.pss == 0) {
16566                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16567                mi.memtrack = memtrackTmp[0];
16568            }
16569            totalPss += mi.pss;
16570            totalMemtrack += mi.memtrack;
16571        }
16572        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16573            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16574                if (lhs.oomAdj != rhs.oomAdj) {
16575                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16576                }
16577                if (lhs.pss != rhs.pss) {
16578                    return lhs.pss < rhs.pss ? 1 : -1;
16579                }
16580                return 0;
16581            }
16582        });
16583
16584        StringBuilder tag = new StringBuilder(128);
16585        StringBuilder stack = new StringBuilder(128);
16586        tag.append("Low on memory -- ");
16587        appendMemBucket(tag, totalPss, "total", false);
16588        appendMemBucket(stack, totalPss, "total", true);
16589
16590        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16591        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16592        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16593
16594        boolean firstLine = true;
16595        int lastOomAdj = Integer.MIN_VALUE;
16596        long extraNativeRam = 0;
16597        long extraNativeMemtrack = 0;
16598        long cachedPss = 0;
16599        for (int i=0, N=memInfos.size(); i<N; i++) {
16600            ProcessMemInfo mi = memInfos.get(i);
16601
16602            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16603                cachedPss += mi.pss;
16604            }
16605
16606            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16607                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16608                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16609                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16610                if (lastOomAdj != mi.oomAdj) {
16611                    lastOomAdj = mi.oomAdj;
16612                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16613                        tag.append(" / ");
16614                    }
16615                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16616                        if (firstLine) {
16617                            stack.append(":");
16618                            firstLine = false;
16619                        }
16620                        stack.append("\n\t at ");
16621                    } else {
16622                        stack.append("$");
16623                    }
16624                } else {
16625                    tag.append(" ");
16626                    stack.append("$");
16627                }
16628                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16629                    appendMemBucket(tag, mi.pss, mi.name, false);
16630                }
16631                appendMemBucket(stack, mi.pss, mi.name, true);
16632                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16633                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16634                    stack.append("(");
16635                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16636                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16637                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16638                            stack.append(":");
16639                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16640                        }
16641                    }
16642                    stack.append(")");
16643                }
16644            }
16645
16646            appendMemInfo(fullNativeBuilder, mi);
16647            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16648                // The short form only has native processes that are >= 512K.
16649                if (mi.pss >= 512) {
16650                    appendMemInfo(shortNativeBuilder, mi);
16651                } else {
16652                    extraNativeRam += mi.pss;
16653                    extraNativeMemtrack += mi.memtrack;
16654                }
16655            } else {
16656                // Short form has all other details, but if we have collected RAM
16657                // from smaller native processes let's dump a summary of that.
16658                if (extraNativeRam > 0) {
16659                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16660                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16661                    shortNativeBuilder.append('\n');
16662                    extraNativeRam = 0;
16663                }
16664                appendMemInfo(fullJavaBuilder, mi);
16665            }
16666        }
16667
16668        fullJavaBuilder.append("           ");
16669        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16670        fullJavaBuilder.append(": TOTAL");
16671        if (totalMemtrack > 0) {
16672            fullJavaBuilder.append(" (");
16673            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16674            fullJavaBuilder.append(" memtrack)");
16675        } else {
16676        }
16677        fullJavaBuilder.append("\n");
16678
16679        MemInfoReader memInfo = new MemInfoReader();
16680        memInfo.readMemInfo();
16681        final long[] infos = memInfo.getRawInfo();
16682
16683        StringBuilder memInfoBuilder = new StringBuilder(1024);
16684        Debug.getMemInfo(infos);
16685        memInfoBuilder.append("  MemInfo: ");
16686        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16687        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16688        memInfoBuilder.append(stringifyKBSize(
16689                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16690        memInfoBuilder.append(stringifyKBSize(
16691                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16692        memInfoBuilder.append(stringifyKBSize(
16693                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16694        memInfoBuilder.append("           ");
16695        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16696        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16697        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16698        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16699        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16700            memInfoBuilder.append("  ZRAM: ");
16701            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16702            memInfoBuilder.append(" RAM, ");
16703            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16704            memInfoBuilder.append(" swap total, ");
16705            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16706            memInfoBuilder.append(" swap free\n");
16707        }
16708        final long[] ksm = getKsmInfo();
16709        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16710                || ksm[KSM_VOLATILE] != 0) {
16711            memInfoBuilder.append("  KSM: ");
16712            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16713            memInfoBuilder.append(" saved from shared ");
16714            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16715            memInfoBuilder.append("\n       ");
16716            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16717            memInfoBuilder.append(" unshared; ");
16718            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16719            memInfoBuilder.append(" volatile\n");
16720        }
16721        memInfoBuilder.append("  Free RAM: ");
16722        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16723                + memInfo.getFreeSizeKb()));
16724        memInfoBuilder.append("\n");
16725        memInfoBuilder.append("  Used RAM: ");
16726        memInfoBuilder.append(stringifyKBSize(
16727                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16728        memInfoBuilder.append("\n");
16729        memInfoBuilder.append("  Lost RAM: ");
16730        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16731                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16732                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16733        memInfoBuilder.append("\n");
16734        Slog.i(TAG, "Low on memory:");
16735        Slog.i(TAG, shortNativeBuilder.toString());
16736        Slog.i(TAG, fullJavaBuilder.toString());
16737        Slog.i(TAG, memInfoBuilder.toString());
16738
16739        StringBuilder dropBuilder = new StringBuilder(1024);
16740        /*
16741        StringWriter oomSw = new StringWriter();
16742        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16743        StringWriter catSw = new StringWriter();
16744        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16745        String[] emptyArgs = new String[] { };
16746        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16747        oomPw.flush();
16748        String oomString = oomSw.toString();
16749        */
16750        dropBuilder.append("Low on memory:");
16751        dropBuilder.append(stack);
16752        dropBuilder.append('\n');
16753        dropBuilder.append(fullNativeBuilder);
16754        dropBuilder.append(fullJavaBuilder);
16755        dropBuilder.append('\n');
16756        dropBuilder.append(memInfoBuilder);
16757        dropBuilder.append('\n');
16758        /*
16759        dropBuilder.append(oomString);
16760        dropBuilder.append('\n');
16761        */
16762        StringWriter catSw = new StringWriter();
16763        synchronized (ActivityManagerService.this) {
16764            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16765            String[] emptyArgs = new String[] { };
16766            catPw.println();
16767            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16768            catPw.println();
16769            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16770                    false, null).dumpLocked();
16771            catPw.println();
16772            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16773            catPw.flush();
16774        }
16775        dropBuilder.append(catSw.toString());
16776        addErrorToDropBox("lowmem", null, "system_server", null,
16777                null, tag.toString(), dropBuilder.toString(), null, null);
16778        //Slog.i(TAG, "Sent to dropbox:");
16779        //Slog.i(TAG, dropBuilder.toString());
16780        synchronized (ActivityManagerService.this) {
16781            long now = SystemClock.uptimeMillis();
16782            if (mLastMemUsageReportTime < now) {
16783                mLastMemUsageReportTime = now;
16784            }
16785        }
16786    }
16787
16788    /**
16789     * Searches array of arguments for the specified string
16790     * @param args array of argument strings
16791     * @param value value to search for
16792     * @return true if the value is contained in the array
16793     */
16794    private static boolean scanArgs(String[] args, String value) {
16795        if (args != null) {
16796            for (String arg : args) {
16797                if (value.equals(arg)) {
16798                    return true;
16799                }
16800            }
16801        }
16802        return false;
16803    }
16804
16805    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16806            ContentProviderRecord cpr, boolean always) {
16807        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16808
16809        if (!inLaunching || always) {
16810            synchronized (cpr) {
16811                cpr.launchingApp = null;
16812                cpr.notifyAll();
16813            }
16814            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16815            String names[] = cpr.info.authority.split(";");
16816            for (int j = 0; j < names.length; j++) {
16817                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16818            }
16819        }
16820
16821        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16822            ContentProviderConnection conn = cpr.connections.get(i);
16823            if (conn.waiting) {
16824                // If this connection is waiting for the provider, then we don't
16825                // need to mess with its process unless we are always removing
16826                // or for some reason the provider is not currently launching.
16827                if (inLaunching && !always) {
16828                    continue;
16829                }
16830            }
16831            ProcessRecord capp = conn.client;
16832            conn.dead = true;
16833            if (conn.stableCount > 0) {
16834                if (!capp.persistent && capp.thread != null
16835                        && capp.pid != 0
16836                        && capp.pid != MY_PID) {
16837                    capp.kill("depends on provider "
16838                            + cpr.name.flattenToShortString()
16839                            + " in dying proc " + (proc != null ? proc.processName : "??")
16840                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16841                }
16842            } else if (capp.thread != null && conn.provider.provider != null) {
16843                try {
16844                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16845                } catch (RemoteException e) {
16846                }
16847                // In the protocol here, we don't expect the client to correctly
16848                // clean up this connection, we'll just remove it.
16849                cpr.connections.remove(i);
16850                if (conn.client.conProviders.remove(conn)) {
16851                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16852                }
16853            }
16854        }
16855
16856        if (inLaunching && always) {
16857            mLaunchingProviders.remove(cpr);
16858        }
16859        return inLaunching;
16860    }
16861
16862    /**
16863     * Main code for cleaning up a process when it has gone away.  This is
16864     * called both as a result of the process dying, or directly when stopping
16865     * a process when running in single process mode.
16866     *
16867     * @return Returns true if the given process has been restarted, so the
16868     * app that was passed in must remain on the process lists.
16869     */
16870    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16871            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16872        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16873        if (index >= 0) {
16874            removeLruProcessLocked(app);
16875            ProcessList.remove(app.pid);
16876        }
16877
16878        mProcessesToGc.remove(app);
16879        mPendingPssProcesses.remove(app);
16880
16881        // Dismiss any open dialogs.
16882        if (app.crashDialog != null && !app.forceCrashReport) {
16883            app.crashDialog.dismiss();
16884            app.crashDialog = null;
16885        }
16886        if (app.anrDialog != null) {
16887            app.anrDialog.dismiss();
16888            app.anrDialog = null;
16889        }
16890        if (app.waitDialog != null) {
16891            app.waitDialog.dismiss();
16892            app.waitDialog = null;
16893        }
16894
16895        app.crashing = false;
16896        app.notResponding = false;
16897
16898        app.resetPackageList(mProcessStats);
16899        app.unlinkDeathRecipient();
16900        app.makeInactive(mProcessStats);
16901        app.waitingToKill = null;
16902        app.forcingToForeground = null;
16903        updateProcessForegroundLocked(app, false, false);
16904        app.foregroundActivities = false;
16905        app.hasShownUi = false;
16906        app.treatLikeActivity = false;
16907        app.hasAboveClient = false;
16908        app.hasClientActivities = false;
16909
16910        mServices.killServicesLocked(app, allowRestart);
16911
16912        boolean restart = false;
16913
16914        // Remove published content providers.
16915        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16916            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16917            final boolean always = app.bad || !allowRestart;
16918            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16919            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16920                // We left the provider in the launching list, need to
16921                // restart it.
16922                restart = true;
16923            }
16924
16925            cpr.provider = null;
16926            cpr.proc = null;
16927        }
16928        app.pubProviders.clear();
16929
16930        // Take care of any launching providers waiting for this process.
16931        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16932            restart = true;
16933        }
16934
16935        // Unregister from connected content providers.
16936        if (!app.conProviders.isEmpty()) {
16937            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16938                ContentProviderConnection conn = app.conProviders.get(i);
16939                conn.provider.connections.remove(conn);
16940                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16941                        conn.provider.name);
16942            }
16943            app.conProviders.clear();
16944        }
16945
16946        // At this point there may be remaining entries in mLaunchingProviders
16947        // where we were the only one waiting, so they are no longer of use.
16948        // Look for these and clean up if found.
16949        // XXX Commented out for now.  Trying to figure out a way to reproduce
16950        // the actual situation to identify what is actually going on.
16951        if (false) {
16952            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16953                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16954                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16955                    synchronized (cpr) {
16956                        cpr.launchingApp = null;
16957                        cpr.notifyAll();
16958                    }
16959                }
16960            }
16961        }
16962
16963        skipCurrentReceiverLocked(app);
16964
16965        // Unregister any receivers.
16966        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16967            removeReceiverLocked(app.receivers.valueAt(i));
16968        }
16969        app.receivers.clear();
16970
16971        // If the app is undergoing backup, tell the backup manager about it
16972        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16973            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16974                    + mBackupTarget.appInfo + " died during backup");
16975            try {
16976                IBackupManager bm = IBackupManager.Stub.asInterface(
16977                        ServiceManager.getService(Context.BACKUP_SERVICE));
16978                bm.agentDisconnected(app.info.packageName);
16979            } catch (RemoteException e) {
16980                // can't happen; backup manager is local
16981            }
16982        }
16983
16984        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16985            ProcessChangeItem item = mPendingProcessChanges.get(i);
16986            if (item.pid == app.pid) {
16987                mPendingProcessChanges.remove(i);
16988                mAvailProcessChanges.add(item);
16989            }
16990        }
16991        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16992                null).sendToTarget();
16993
16994        // If the caller is restarting this app, then leave it in its
16995        // current lists and let the caller take care of it.
16996        if (restarting) {
16997            return false;
16998        }
16999
17000        if (!app.persistent || app.isolated) {
17001            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17002                    "Removing non-persistent process during cleanup: " + app);
17003            if (!replacingPid) {
17004                removeProcessNameLocked(app.processName, app.uid);
17005            }
17006            if (mHeavyWeightProcess == app) {
17007                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17008                        mHeavyWeightProcess.userId, 0));
17009                mHeavyWeightProcess = null;
17010            }
17011        } else if (!app.removed) {
17012            // This app is persistent, so we need to keep its record around.
17013            // If it is not already on the pending app list, add it there
17014            // and start a new process for it.
17015            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17016                mPersistentStartingProcesses.add(app);
17017                restart = true;
17018            }
17019        }
17020        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17021                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17022        mProcessesOnHold.remove(app);
17023
17024        if (app == mHomeProcess) {
17025            mHomeProcess = null;
17026        }
17027        if (app == mPreviousProcess) {
17028            mPreviousProcess = null;
17029        }
17030
17031        if (restart && !app.isolated) {
17032            // We have components that still need to be running in the
17033            // process, so re-launch it.
17034            if (index < 0) {
17035                ProcessList.remove(app.pid);
17036            }
17037            addProcessNameLocked(app);
17038            startProcessLocked(app, "restart", app.processName);
17039            return true;
17040        } else if (app.pid > 0 && app.pid != MY_PID) {
17041            // Goodbye!
17042            boolean removed;
17043            synchronized (mPidsSelfLocked) {
17044                mPidsSelfLocked.remove(app.pid);
17045                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17046            }
17047            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17048            if (app.isolated) {
17049                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17050            }
17051            app.setPid(0);
17052        }
17053        return false;
17054    }
17055
17056    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17057        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17058            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17059            if (cpr.launchingApp == app) {
17060                return true;
17061            }
17062        }
17063        return false;
17064    }
17065
17066    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17067        // Look through the content providers we are waiting to have launched,
17068        // and if any run in this process then either schedule a restart of
17069        // the process or kill the client waiting for it if this process has
17070        // gone bad.
17071        boolean restart = false;
17072        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17073            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17074            if (cpr.launchingApp == app) {
17075                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17076                    restart = true;
17077                } else {
17078                    removeDyingProviderLocked(app, cpr, true);
17079                }
17080            }
17081        }
17082        return restart;
17083    }
17084
17085    // =========================================================
17086    // SERVICES
17087    // =========================================================
17088
17089    @Override
17090    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17091            int flags) {
17092        enforceNotIsolatedCaller("getServices");
17093        synchronized (this) {
17094            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17095        }
17096    }
17097
17098    @Override
17099    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17100        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17101        synchronized (this) {
17102            return mServices.getRunningServiceControlPanelLocked(name);
17103        }
17104    }
17105
17106    @Override
17107    public ComponentName startService(IApplicationThread caller, Intent service,
17108            String resolvedType, String callingPackage, int userId)
17109            throws TransactionTooLargeException {
17110        enforceNotIsolatedCaller("startService");
17111        // Refuse possible leaked file descriptors
17112        if (service != null && service.hasFileDescriptors() == true) {
17113            throw new IllegalArgumentException("File descriptors passed in Intent");
17114        }
17115
17116        if (callingPackage == null) {
17117            throw new IllegalArgumentException("callingPackage cannot be null");
17118        }
17119
17120        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17121                "startService: " + service + " type=" + resolvedType);
17122        synchronized(this) {
17123            final int callingPid = Binder.getCallingPid();
17124            final int callingUid = Binder.getCallingUid();
17125            final long origId = Binder.clearCallingIdentity();
17126            ComponentName res = mServices.startServiceLocked(caller, service,
17127                    resolvedType, callingPid, callingUid, callingPackage, userId);
17128            Binder.restoreCallingIdentity(origId);
17129            return res;
17130        }
17131    }
17132
17133    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17134            String callingPackage, int userId)
17135            throws TransactionTooLargeException {
17136        synchronized(this) {
17137            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17138                    "startServiceInPackage: " + service + " type=" + resolvedType);
17139            final long origId = Binder.clearCallingIdentity();
17140            ComponentName res = mServices.startServiceLocked(null, service,
17141                    resolvedType, -1, uid, callingPackage, userId);
17142            Binder.restoreCallingIdentity(origId);
17143            return res;
17144        }
17145    }
17146
17147    @Override
17148    public int stopService(IApplicationThread caller, Intent service,
17149            String resolvedType, int userId) {
17150        enforceNotIsolatedCaller("stopService");
17151        // Refuse possible leaked file descriptors
17152        if (service != null && service.hasFileDescriptors() == true) {
17153            throw new IllegalArgumentException("File descriptors passed in Intent");
17154        }
17155
17156        synchronized(this) {
17157            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17158        }
17159    }
17160
17161    @Override
17162    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17163        enforceNotIsolatedCaller("peekService");
17164        // Refuse possible leaked file descriptors
17165        if (service != null && service.hasFileDescriptors() == true) {
17166            throw new IllegalArgumentException("File descriptors passed in Intent");
17167        }
17168
17169        if (callingPackage == null) {
17170            throw new IllegalArgumentException("callingPackage cannot be null");
17171        }
17172
17173        synchronized(this) {
17174            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17175        }
17176    }
17177
17178    @Override
17179    public boolean stopServiceToken(ComponentName className, IBinder token,
17180            int startId) {
17181        synchronized(this) {
17182            return mServices.stopServiceTokenLocked(className, token, startId);
17183        }
17184    }
17185
17186    @Override
17187    public void setServiceForeground(ComponentName className, IBinder token,
17188            int id, Notification notification, int flags) {
17189        synchronized(this) {
17190            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17191        }
17192    }
17193
17194    @Override
17195    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17196            boolean requireFull, String name, String callerPackage) {
17197        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17198                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17199    }
17200
17201    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17202            String className, int flags) {
17203        boolean result = false;
17204        // For apps that don't have pre-defined UIDs, check for permission
17205        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17206            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17207                if (ActivityManager.checkUidPermission(
17208                        INTERACT_ACROSS_USERS,
17209                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17210                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17211                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17212                            + " requests FLAG_SINGLE_USER, but app does not hold "
17213                            + INTERACT_ACROSS_USERS;
17214                    Slog.w(TAG, msg);
17215                    throw new SecurityException(msg);
17216                }
17217                // Permission passed
17218                result = true;
17219            }
17220        } else if ("system".equals(componentProcessName)) {
17221            result = true;
17222        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17223            // Phone app and persistent apps are allowed to export singleuser providers.
17224            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17225                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17226        }
17227        if (DEBUG_MU) Slog.v(TAG_MU,
17228                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17229                + Integer.toHexString(flags) + ") = " + result);
17230        return result;
17231    }
17232
17233    /**
17234     * Checks to see if the caller is in the same app as the singleton
17235     * component, or the component is in a special app. It allows special apps
17236     * to export singleton components but prevents exporting singleton
17237     * components for regular apps.
17238     */
17239    boolean isValidSingletonCall(int callingUid, int componentUid) {
17240        int componentAppId = UserHandle.getAppId(componentUid);
17241        return UserHandle.isSameApp(callingUid, componentUid)
17242                || componentAppId == Process.SYSTEM_UID
17243                || componentAppId == Process.PHONE_UID
17244                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17245                        == PackageManager.PERMISSION_GRANTED;
17246    }
17247
17248    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17249            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17250            int userId) throws TransactionTooLargeException {
17251        enforceNotIsolatedCaller("bindService");
17252
17253        // Refuse possible leaked file descriptors
17254        if (service != null && service.hasFileDescriptors() == true) {
17255            throw new IllegalArgumentException("File descriptors passed in Intent");
17256        }
17257
17258        if (callingPackage == null) {
17259            throw new IllegalArgumentException("callingPackage cannot be null");
17260        }
17261
17262        synchronized(this) {
17263            return mServices.bindServiceLocked(caller, token, service,
17264                    resolvedType, connection, flags, callingPackage, userId);
17265        }
17266    }
17267
17268    public boolean unbindService(IServiceConnection connection) {
17269        synchronized (this) {
17270            return mServices.unbindServiceLocked(connection);
17271        }
17272    }
17273
17274    public void publishService(IBinder token, Intent intent, IBinder service) {
17275        // Refuse possible leaked file descriptors
17276        if (intent != null && intent.hasFileDescriptors() == true) {
17277            throw new IllegalArgumentException("File descriptors passed in Intent");
17278        }
17279
17280        synchronized(this) {
17281            if (!(token instanceof ServiceRecord)) {
17282                throw new IllegalArgumentException("Invalid service token");
17283            }
17284            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17285        }
17286    }
17287
17288    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17289        // Refuse possible leaked file descriptors
17290        if (intent != null && intent.hasFileDescriptors() == true) {
17291            throw new IllegalArgumentException("File descriptors passed in Intent");
17292        }
17293
17294        synchronized(this) {
17295            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17296        }
17297    }
17298
17299    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17300        synchronized(this) {
17301            if (!(token instanceof ServiceRecord)) {
17302                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17303                throw new IllegalArgumentException("Invalid service token");
17304            }
17305            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17306        }
17307    }
17308
17309    // =========================================================
17310    // BACKUP AND RESTORE
17311    // =========================================================
17312
17313    // Cause the target app to be launched if necessary and its backup agent
17314    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17315    // activity manager to announce its creation.
17316    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17317        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17318        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17319
17320        IPackageManager pm = AppGlobals.getPackageManager();
17321        ApplicationInfo app = null;
17322        try {
17323            app = pm.getApplicationInfo(packageName, 0, userId);
17324        } catch (RemoteException e) {
17325            // can't happen; package manager is process-local
17326        }
17327        if (app == null) {
17328            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17329            return false;
17330        }
17331
17332        synchronized(this) {
17333            // !!! TODO: currently no check here that we're already bound
17334            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17335            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17336            synchronized (stats) {
17337                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17338            }
17339
17340            // Backup agent is now in use, its package can't be stopped.
17341            try {
17342                AppGlobals.getPackageManager().setPackageStoppedState(
17343                        app.packageName, false, UserHandle.getUserId(app.uid));
17344            } catch (RemoteException e) {
17345            } catch (IllegalArgumentException e) {
17346                Slog.w(TAG, "Failed trying to unstop package "
17347                        + app.packageName + ": " + e);
17348            }
17349
17350            BackupRecord r = new BackupRecord(ss, app, backupMode);
17351            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17352                    ? new ComponentName(app.packageName, app.backupAgentName)
17353                    : new ComponentName("android", "FullBackupAgent");
17354            // startProcessLocked() returns existing proc's record if it's already running
17355            ProcessRecord proc = startProcessLocked(app.processName, app,
17356                    false, 0, "backup", hostingName, false, false, false);
17357            if (proc == null) {
17358                Slog.e(TAG, "Unable to start backup agent process " + r);
17359                return false;
17360            }
17361
17362            // If the app is a regular app (uid >= 10000) and not the system server or phone
17363            // process, etc, then mark it as being in full backup so that certain calls to the
17364            // process can be blocked. This is not reset to false anywhere because we kill the
17365            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17366            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17367                proc.inFullBackup = true;
17368            }
17369            r.app = proc;
17370            mBackupTarget = r;
17371            mBackupAppName = app.packageName;
17372
17373            // Try not to kill the process during backup
17374            updateOomAdjLocked(proc);
17375
17376            // If the process is already attached, schedule the creation of the backup agent now.
17377            // If it is not yet live, this will be done when it attaches to the framework.
17378            if (proc.thread != null) {
17379                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17380                try {
17381                    proc.thread.scheduleCreateBackupAgent(app,
17382                            compatibilityInfoForPackageLocked(app), backupMode);
17383                } catch (RemoteException e) {
17384                    // Will time out on the backup manager side
17385                }
17386            } else {
17387                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17388            }
17389            // Invariants: at this point, the target app process exists and the application
17390            // is either already running or in the process of coming up.  mBackupTarget and
17391            // mBackupAppName describe the app, so that when it binds back to the AM we
17392            // know that it's scheduled for a backup-agent operation.
17393        }
17394
17395        return true;
17396    }
17397
17398    @Override
17399    public void clearPendingBackup() {
17400        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17401        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17402
17403        synchronized (this) {
17404            mBackupTarget = null;
17405            mBackupAppName = null;
17406        }
17407    }
17408
17409    // A backup agent has just come up
17410    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17411        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17412                + " = " + agent);
17413
17414        synchronized(this) {
17415            if (!agentPackageName.equals(mBackupAppName)) {
17416                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17417                return;
17418            }
17419        }
17420
17421        long oldIdent = Binder.clearCallingIdentity();
17422        try {
17423            IBackupManager bm = IBackupManager.Stub.asInterface(
17424                    ServiceManager.getService(Context.BACKUP_SERVICE));
17425            bm.agentConnected(agentPackageName, agent);
17426        } catch (RemoteException e) {
17427            // can't happen; the backup manager service is local
17428        } catch (Exception e) {
17429            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17430            e.printStackTrace();
17431        } finally {
17432            Binder.restoreCallingIdentity(oldIdent);
17433        }
17434    }
17435
17436    // done with this agent
17437    public void unbindBackupAgent(ApplicationInfo appInfo) {
17438        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17439        if (appInfo == null) {
17440            Slog.w(TAG, "unbind backup agent for null app");
17441            return;
17442        }
17443
17444        synchronized(this) {
17445            try {
17446                if (mBackupAppName == null) {
17447                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17448                    return;
17449                }
17450
17451                if (!mBackupAppName.equals(appInfo.packageName)) {
17452                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17453                    return;
17454                }
17455
17456                // Not backing this app up any more; reset its OOM adjustment
17457                final ProcessRecord proc = mBackupTarget.app;
17458                updateOomAdjLocked(proc);
17459
17460                // If the app crashed during backup, 'thread' will be null here
17461                if (proc.thread != null) {
17462                    try {
17463                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17464                                compatibilityInfoForPackageLocked(appInfo));
17465                    } catch (Exception e) {
17466                        Slog.e(TAG, "Exception when unbinding backup agent:");
17467                        e.printStackTrace();
17468                    }
17469                }
17470            } finally {
17471                mBackupTarget = null;
17472                mBackupAppName = null;
17473            }
17474        }
17475    }
17476    // =========================================================
17477    // BROADCASTS
17478    // =========================================================
17479
17480    boolean isPendingBroadcastProcessLocked(int pid) {
17481        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17482                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17483    }
17484
17485    void skipPendingBroadcastLocked(int pid) {
17486            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17487            for (BroadcastQueue queue : mBroadcastQueues) {
17488                queue.skipPendingBroadcastLocked(pid);
17489            }
17490    }
17491
17492    // The app just attached; send any pending broadcasts that it should receive
17493    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17494        boolean didSomething = false;
17495        for (BroadcastQueue queue : mBroadcastQueues) {
17496            didSomething |= queue.sendPendingBroadcastsLocked(app);
17497        }
17498        return didSomething;
17499    }
17500
17501    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17502            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17503        enforceNotIsolatedCaller("registerReceiver");
17504        ArrayList<Intent> stickyIntents = null;
17505        ProcessRecord callerApp = null;
17506        int callingUid;
17507        int callingPid;
17508        synchronized(this) {
17509            if (caller != null) {
17510                callerApp = getRecordForAppLocked(caller);
17511                if (callerApp == null) {
17512                    throw new SecurityException(
17513                            "Unable to find app for caller " + caller
17514                            + " (pid=" + Binder.getCallingPid()
17515                            + ") when registering receiver " + receiver);
17516                }
17517                if (callerApp.info.uid != Process.SYSTEM_UID &&
17518                        !callerApp.pkgList.containsKey(callerPackage) &&
17519                        !"android".equals(callerPackage)) {
17520                    throw new SecurityException("Given caller package " + callerPackage
17521                            + " is not running in process " + callerApp);
17522                }
17523                callingUid = callerApp.info.uid;
17524                callingPid = callerApp.pid;
17525            } else {
17526                callerPackage = null;
17527                callingUid = Binder.getCallingUid();
17528                callingPid = Binder.getCallingPid();
17529            }
17530
17531            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17532                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17533
17534            Iterator<String> actions = filter.actionsIterator();
17535            if (actions == null) {
17536                ArrayList<String> noAction = new ArrayList<String>(1);
17537                noAction.add(null);
17538                actions = noAction.iterator();
17539            }
17540
17541            // Collect stickies of users
17542            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17543            while (actions.hasNext()) {
17544                String action = actions.next();
17545                for (int id : userIds) {
17546                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17547                    if (stickies != null) {
17548                        ArrayList<Intent> intents = stickies.get(action);
17549                        if (intents != null) {
17550                            if (stickyIntents == null) {
17551                                stickyIntents = new ArrayList<Intent>();
17552                            }
17553                            stickyIntents.addAll(intents);
17554                        }
17555                    }
17556                }
17557            }
17558        }
17559
17560        ArrayList<Intent> allSticky = null;
17561        if (stickyIntents != null) {
17562            final ContentResolver resolver = mContext.getContentResolver();
17563            // Look for any matching sticky broadcasts...
17564            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17565                Intent intent = stickyIntents.get(i);
17566                // If intent has scheme "content", it will need to acccess
17567                // provider that needs to lock mProviderMap in ActivityThread
17568                // and also it may need to wait application response, so we
17569                // cannot lock ActivityManagerService here.
17570                if (filter.match(resolver, intent, true, TAG) >= 0) {
17571                    if (allSticky == null) {
17572                        allSticky = new ArrayList<Intent>();
17573                    }
17574                    allSticky.add(intent);
17575                }
17576            }
17577        }
17578
17579        // The first sticky in the list is returned directly back to the client.
17580        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17581        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17582        if (receiver == null) {
17583            return sticky;
17584        }
17585
17586        synchronized (this) {
17587            if (callerApp != null && (callerApp.thread == null
17588                    || callerApp.thread.asBinder() != caller.asBinder())) {
17589                // Original caller already died
17590                return null;
17591            }
17592            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17593            if (rl == null) {
17594                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17595                        userId, receiver);
17596                if (rl.app != null) {
17597                    rl.app.receivers.add(rl);
17598                } else {
17599                    try {
17600                        receiver.asBinder().linkToDeath(rl, 0);
17601                    } catch (RemoteException e) {
17602                        return sticky;
17603                    }
17604                    rl.linkedToDeath = true;
17605                }
17606                mRegisteredReceivers.put(receiver.asBinder(), rl);
17607            } else if (rl.uid != callingUid) {
17608                throw new IllegalArgumentException(
17609                        "Receiver requested to register for uid " + callingUid
17610                        + " was previously registered for uid " + rl.uid);
17611            } else if (rl.pid != callingPid) {
17612                throw new IllegalArgumentException(
17613                        "Receiver requested to register for pid " + callingPid
17614                        + " was previously registered for pid " + rl.pid);
17615            } else if (rl.userId != userId) {
17616                throw new IllegalArgumentException(
17617                        "Receiver requested to register for user " + userId
17618                        + " was previously registered for user " + rl.userId);
17619            }
17620            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17621                    permission, callingUid, userId);
17622            rl.add(bf);
17623            if (!bf.debugCheck()) {
17624                Slog.w(TAG, "==> For Dynamic broadcast");
17625            }
17626            mReceiverResolver.addFilter(bf);
17627
17628            // Enqueue broadcasts for all existing stickies that match
17629            // this filter.
17630            if (allSticky != null) {
17631                ArrayList receivers = new ArrayList();
17632                receivers.add(bf);
17633
17634                final int stickyCount = allSticky.size();
17635                for (int i = 0; i < stickyCount; i++) {
17636                    Intent intent = allSticky.get(i);
17637                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17638                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17639                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17640                            null, 0, null, null, false, true, true, -1);
17641                    queue.enqueueParallelBroadcastLocked(r);
17642                    queue.scheduleBroadcastsLocked();
17643                }
17644            }
17645
17646            return sticky;
17647        }
17648    }
17649
17650    public void unregisterReceiver(IIntentReceiver receiver) {
17651        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17652
17653        final long origId = Binder.clearCallingIdentity();
17654        try {
17655            boolean doTrim = false;
17656
17657            synchronized(this) {
17658                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17659                if (rl != null) {
17660                    final BroadcastRecord r = rl.curBroadcast;
17661                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17662                        final boolean doNext = r.queue.finishReceiverLocked(
17663                                r, r.resultCode, r.resultData, r.resultExtras,
17664                                r.resultAbort, false);
17665                        if (doNext) {
17666                            doTrim = true;
17667                            r.queue.processNextBroadcast(false);
17668                        }
17669                    }
17670
17671                    if (rl.app != null) {
17672                        rl.app.receivers.remove(rl);
17673                    }
17674                    removeReceiverLocked(rl);
17675                    if (rl.linkedToDeath) {
17676                        rl.linkedToDeath = false;
17677                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17678                    }
17679                }
17680            }
17681
17682            // If we actually concluded any broadcasts, we might now be able
17683            // to trim the recipients' apps from our working set
17684            if (doTrim) {
17685                trimApplications();
17686                return;
17687            }
17688
17689        } finally {
17690            Binder.restoreCallingIdentity(origId);
17691        }
17692    }
17693
17694    void removeReceiverLocked(ReceiverList rl) {
17695        mRegisteredReceivers.remove(rl.receiver.asBinder());
17696        for (int i = rl.size() - 1; i >= 0; i--) {
17697            mReceiverResolver.removeFilter(rl.get(i));
17698        }
17699    }
17700
17701    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17702        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17703            ProcessRecord r = mLruProcesses.get(i);
17704            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17705                try {
17706                    r.thread.dispatchPackageBroadcast(cmd, packages);
17707                } catch (RemoteException ex) {
17708                }
17709            }
17710        }
17711    }
17712
17713    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17714            int callingUid, int[] users) {
17715        // TODO: come back and remove this assumption to triage all broadcasts
17716        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17717
17718        List<ResolveInfo> receivers = null;
17719        try {
17720            HashSet<ComponentName> singleUserReceivers = null;
17721            boolean scannedFirstReceivers = false;
17722            for (int user : users) {
17723                // Skip users that have Shell restrictions, with exception of always permitted
17724                // Shell broadcasts
17725                if (callingUid == Process.SHELL_UID
17726                        && mUserController.hasUserRestriction(
17727                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17728                        && !isPermittedShellBroadcast(intent)) {
17729                    continue;
17730                }
17731                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17732                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17733                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17734                    // If this is not the system user, we need to check for
17735                    // any receivers that should be filtered out.
17736                    for (int i=0; i<newReceivers.size(); i++) {
17737                        ResolveInfo ri = newReceivers.get(i);
17738                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17739                            newReceivers.remove(i);
17740                            i--;
17741                        }
17742                    }
17743                }
17744                if (newReceivers != null && newReceivers.size() == 0) {
17745                    newReceivers = null;
17746                }
17747                if (receivers == null) {
17748                    receivers = newReceivers;
17749                } else if (newReceivers != null) {
17750                    // We need to concatenate the additional receivers
17751                    // found with what we have do far.  This would be easy,
17752                    // but we also need to de-dup any receivers that are
17753                    // singleUser.
17754                    if (!scannedFirstReceivers) {
17755                        // Collect any single user receivers we had already retrieved.
17756                        scannedFirstReceivers = true;
17757                        for (int i=0; i<receivers.size(); i++) {
17758                            ResolveInfo ri = receivers.get(i);
17759                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17760                                ComponentName cn = new ComponentName(
17761                                        ri.activityInfo.packageName, ri.activityInfo.name);
17762                                if (singleUserReceivers == null) {
17763                                    singleUserReceivers = new HashSet<ComponentName>();
17764                                }
17765                                singleUserReceivers.add(cn);
17766                            }
17767                        }
17768                    }
17769                    // Add the new results to the existing results, tracking
17770                    // and de-dupping single user receivers.
17771                    for (int i=0; i<newReceivers.size(); i++) {
17772                        ResolveInfo ri = newReceivers.get(i);
17773                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17774                            ComponentName cn = new ComponentName(
17775                                    ri.activityInfo.packageName, ri.activityInfo.name);
17776                            if (singleUserReceivers == null) {
17777                                singleUserReceivers = new HashSet<ComponentName>();
17778                            }
17779                            if (!singleUserReceivers.contains(cn)) {
17780                                singleUserReceivers.add(cn);
17781                                receivers.add(ri);
17782                            }
17783                        } else {
17784                            receivers.add(ri);
17785                        }
17786                    }
17787                }
17788            }
17789        } catch (RemoteException ex) {
17790            // pm is in same process, this will never happen.
17791        }
17792        return receivers;
17793    }
17794
17795    private boolean isPermittedShellBroadcast(Intent intent) {
17796        // remote bugreport should always be allowed to be taken
17797        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17798    }
17799
17800    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17801            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17802        final String action = intent.getAction();
17803        if (isProtectedBroadcast
17804                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17805                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17806                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17807                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17808                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17809                || Intent.ACTION_MASTER_CLEAR.equals(action)
17810                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17811                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17812                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17813                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17814                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17815            // Broadcast is either protected, or it's a public action that
17816            // we've relaxed, so it's fine for system internals to send.
17817            return;
17818        }
17819
17820        // This broadcast may be a problem...  but there are often system components that
17821        // want to send an internal broadcast to themselves, which is annoying to have to
17822        // explicitly list each action as a protected broadcast, so we will check for that
17823        // one safe case and allow it: an explicit broadcast, only being received by something
17824        // that has protected itself.
17825        if (receivers != null && receivers.size() > 0
17826                && (intent.getPackage() != null || intent.getComponent() != null)) {
17827            boolean allProtected = true;
17828            for (int i = receivers.size()-1; i >= 0; i--) {
17829                Object target = receivers.get(i);
17830                if (target instanceof ResolveInfo) {
17831                    ResolveInfo ri = (ResolveInfo)target;
17832                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17833                        allProtected = false;
17834                        break;
17835                    }
17836                } else {
17837                    BroadcastFilter bf = (BroadcastFilter)target;
17838                    if (bf.requiredPermission == null) {
17839                        allProtected = false;
17840                        break;
17841                    }
17842                }
17843            }
17844            if (allProtected) {
17845                // All safe!
17846                return;
17847            }
17848        }
17849
17850        // The vast majority of broadcasts sent from system internals
17851        // should be protected to avoid security holes, so yell loudly
17852        // to ensure we examine these cases.
17853        if (callerApp != null) {
17854            Log.wtf(TAG, "Sending non-protected broadcast " + action
17855                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17856                    new Throwable());
17857        } else {
17858            Log.wtf(TAG, "Sending non-protected broadcast " + action
17859                            + " from system uid " + UserHandle.formatUid(callingUid)
17860                            + " pkg " + callerPackage,
17861                    new Throwable());
17862        }
17863    }
17864
17865    final int broadcastIntentLocked(ProcessRecord callerApp,
17866            String callerPackage, Intent intent, String resolvedType,
17867            IIntentReceiver resultTo, int resultCode, String resultData,
17868            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17869            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17870        intent = new Intent(intent);
17871
17872        // By default broadcasts do not go to stopped apps.
17873        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17874
17875        // If we have not finished booting, don't allow this to launch new processes.
17876        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17877            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17878        }
17879
17880        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17881                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17882                + " ordered=" + ordered + " userid=" + userId);
17883        if ((resultTo != null) && !ordered) {
17884            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17885        }
17886
17887        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17888                ALLOW_NON_FULL, "broadcast", callerPackage);
17889
17890        // Make sure that the user who is receiving this broadcast is running.
17891        // If not, we will just skip it. Make an exception for shutdown broadcasts
17892        // and upgrade steps.
17893
17894        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17895            if ((callingUid != Process.SYSTEM_UID
17896                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17897                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17898                Slog.w(TAG, "Skipping broadcast of " + intent
17899                        + ": user " + userId + " is stopped");
17900                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17901            }
17902        }
17903
17904        BroadcastOptions brOptions = null;
17905        if (bOptions != null) {
17906            brOptions = new BroadcastOptions(bOptions);
17907            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17908                // See if the caller is allowed to do this.  Note we are checking against
17909                // the actual real caller (not whoever provided the operation as say a
17910                // PendingIntent), because that who is actually supplied the arguments.
17911                if (checkComponentPermission(
17912                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17913                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17914                        != PackageManager.PERMISSION_GRANTED) {
17915                    String msg = "Permission Denial: " + intent.getAction()
17916                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17917                            + ", uid=" + callingUid + ")"
17918                            + " requires "
17919                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17920                    Slog.w(TAG, msg);
17921                    throw new SecurityException(msg);
17922                }
17923            }
17924        }
17925
17926        // Verify that protected broadcasts are only being sent by system code,
17927        // and that system code is only sending protected broadcasts.
17928        final String action = intent.getAction();
17929        final boolean isProtectedBroadcast;
17930        try {
17931            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17932        } catch (RemoteException e) {
17933            Slog.w(TAG, "Remote exception", e);
17934            return ActivityManager.BROADCAST_SUCCESS;
17935        }
17936
17937        final boolean isCallerSystem;
17938        switch (UserHandle.getAppId(callingUid)) {
17939            case Process.ROOT_UID:
17940            case Process.SYSTEM_UID:
17941            case Process.PHONE_UID:
17942            case Process.BLUETOOTH_UID:
17943            case Process.NFC_UID:
17944                isCallerSystem = true;
17945                break;
17946            default:
17947                isCallerSystem = (callerApp != null) && callerApp.persistent;
17948                break;
17949        }
17950
17951        // First line security check before anything else: stop non-system apps from
17952        // sending protected broadcasts.
17953        if (!isCallerSystem) {
17954            if (isProtectedBroadcast) {
17955                String msg = "Permission Denial: not allowed to send broadcast "
17956                        + action + " from pid="
17957                        + callingPid + ", uid=" + callingUid;
17958                Slog.w(TAG, msg);
17959                throw new SecurityException(msg);
17960
17961            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17962                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17963                // Special case for compatibility: we don't want apps to send this,
17964                // but historically it has not been protected and apps may be using it
17965                // to poke their own app widget.  So, instead of making it protected,
17966                // just limit it to the caller.
17967                if (callerPackage == null) {
17968                    String msg = "Permission Denial: not allowed to send broadcast "
17969                            + action + " from unknown caller.";
17970                    Slog.w(TAG, msg);
17971                    throw new SecurityException(msg);
17972                } else if (intent.getComponent() != null) {
17973                    // They are good enough to send to an explicit component...  verify
17974                    // it is being sent to the calling app.
17975                    if (!intent.getComponent().getPackageName().equals(
17976                            callerPackage)) {
17977                        String msg = "Permission Denial: not allowed to send broadcast "
17978                                + action + " to "
17979                                + intent.getComponent().getPackageName() + " from "
17980                                + callerPackage;
17981                        Slog.w(TAG, msg);
17982                        throw new SecurityException(msg);
17983                    }
17984                } else {
17985                    // Limit broadcast to their own package.
17986                    intent.setPackage(callerPackage);
17987                }
17988            }
17989        }
17990
17991        if (action != null) {
17992            switch (action) {
17993                case Intent.ACTION_UID_REMOVED:
17994                case Intent.ACTION_PACKAGE_REMOVED:
17995                case Intent.ACTION_PACKAGE_CHANGED:
17996                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17997                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17998                case Intent.ACTION_PACKAGES_SUSPENDED:
17999                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18000                    // Handle special intents: if this broadcast is from the package
18001                    // manager about a package being removed, we need to remove all of
18002                    // its activities from the history stack.
18003                    if (checkComponentPermission(
18004                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18005                            callingPid, callingUid, -1, true)
18006                            != PackageManager.PERMISSION_GRANTED) {
18007                        String msg = "Permission Denial: " + intent.getAction()
18008                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18009                                + ", uid=" + callingUid + ")"
18010                                + " requires "
18011                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18012                        Slog.w(TAG, msg);
18013                        throw new SecurityException(msg);
18014                    }
18015                    switch (action) {
18016                        case Intent.ACTION_UID_REMOVED:
18017                            final Bundle intentExtras = intent.getExtras();
18018                            final int uid = intentExtras != null
18019                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18020                            if (uid >= 0) {
18021                                mBatteryStatsService.removeUid(uid);
18022                                mAppOpsService.uidRemoved(uid);
18023                            }
18024                            break;
18025                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18026                            // If resources are unavailable just force stop all those packages
18027                            // and flush the attribute cache as well.
18028                            String list[] =
18029                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18030                            if (list != null && list.length > 0) {
18031                                for (int i = 0; i < list.length; i++) {
18032                                    forceStopPackageLocked(list[i], -1, false, true, true,
18033                                            false, false, userId, "storage unmount");
18034                                }
18035                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18036                                sendPackageBroadcastLocked(
18037                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18038                                        userId);
18039                            }
18040                            break;
18041                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18042                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18043                            break;
18044                        case Intent.ACTION_PACKAGE_REMOVED:
18045                        case Intent.ACTION_PACKAGE_CHANGED:
18046                            Uri data = intent.getData();
18047                            String ssp;
18048                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18049                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18050                                final boolean replacing =
18051                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18052                                final boolean killProcess =
18053                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18054                                final boolean fullUninstall = removed && !replacing;
18055                                if (removed) {
18056                                    if (killProcess) {
18057                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18058                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18059                                                false, true, true, false, fullUninstall, userId,
18060                                                removed ? "pkg removed" : "pkg changed");
18061                                    }
18062                                    final int cmd = killProcess
18063                                            ? IApplicationThread.PACKAGE_REMOVED
18064                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18065                                    sendPackageBroadcastLocked(cmd,
18066                                            new String[] {ssp}, userId);
18067                                    if (fullUninstall) {
18068                                        mAppOpsService.packageRemoved(
18069                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18070
18071                                        // Remove all permissions granted from/to this package
18072                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18073
18074                                        removeTasksByPackageNameLocked(ssp, userId);
18075
18076                                        // Hide the "unsupported display" dialog if necessary.
18077                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18078                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18079                                            mUnsupportedDisplaySizeDialog.dismiss();
18080                                            mUnsupportedDisplaySizeDialog = null;
18081                                        }
18082                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18083                                        mBatteryStatsService.notePackageUninstalled(ssp);
18084                                    }
18085                                } else {
18086                                    if (killProcess) {
18087                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18088                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18089                                                userId, ProcessList.INVALID_ADJ,
18090                                                false, true, true, false, "change " + ssp);
18091                                    }
18092                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18093                                            intent.getStringArrayExtra(
18094                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18095                                }
18096                            }
18097                            break;
18098                        case Intent.ACTION_PACKAGES_SUSPENDED:
18099                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18100                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18101                                    intent.getAction());
18102                            final String[] packageNames = intent.getStringArrayExtra(
18103                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18104                            final int userHandle = intent.getIntExtra(
18105                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18106
18107                            synchronized(ActivityManagerService.this) {
18108                                mRecentTasks.onPackagesSuspendedChanged(
18109                                        packageNames, suspended, userHandle);
18110                            }
18111                            break;
18112                    }
18113                    break;
18114                case Intent.ACTION_PACKAGE_REPLACED:
18115                {
18116                    final Uri data = intent.getData();
18117                    final String ssp;
18118                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18119                        final ApplicationInfo aInfo =
18120                                getPackageManagerInternalLocked().getApplicationInfo(
18121                                        ssp,
18122                                        userId);
18123                        if (aInfo == null) {
18124                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18125                                    + " ssp=" + ssp + " data=" + data);
18126                            return ActivityManager.BROADCAST_SUCCESS;
18127                        }
18128                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18129                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18130                                new String[] {ssp}, userId);
18131                    }
18132                    break;
18133                }
18134                case Intent.ACTION_PACKAGE_ADDED:
18135                {
18136                    // Special case for adding a package: by default turn on compatibility mode.
18137                    Uri data = intent.getData();
18138                    String ssp;
18139                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18140                        final boolean replacing =
18141                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18142                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18143
18144                        try {
18145                            ApplicationInfo ai = AppGlobals.getPackageManager().
18146                                    getApplicationInfo(ssp, 0, 0);
18147                            mBatteryStatsService.notePackageInstalled(ssp,
18148                                    ai != null ? ai.versionCode : 0);
18149                        } catch (RemoteException e) {
18150                        }
18151                    }
18152                    break;
18153                }
18154                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18155                {
18156                    Uri data = intent.getData();
18157                    String ssp;
18158                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18159                        // Hide the "unsupported display" dialog if necessary.
18160                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18161                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18162                            mUnsupportedDisplaySizeDialog.dismiss();
18163                            mUnsupportedDisplaySizeDialog = null;
18164                        }
18165                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18166                    }
18167                    break;
18168                }
18169                case Intent.ACTION_TIMEZONE_CHANGED:
18170                    // If this is the time zone changed action, queue up a message that will reset
18171                    // the timezone of all currently running processes. This message will get
18172                    // queued up before the broadcast happens.
18173                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18174                    break;
18175                case Intent.ACTION_TIME_CHANGED:
18176                    // If the user set the time, let all running processes know.
18177                    final int is24Hour =
18178                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18179                                    : 0;
18180                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18181                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18182                    synchronized (stats) {
18183                        stats.noteCurrentTimeChangedLocked();
18184                    }
18185                    break;
18186                case Intent.ACTION_CLEAR_DNS_CACHE:
18187                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18188                    break;
18189                case Proxy.PROXY_CHANGE_ACTION:
18190                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18191                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18192                    break;
18193                case android.hardware.Camera.ACTION_NEW_PICTURE:
18194                case android.hardware.Camera.ACTION_NEW_VIDEO:
18195                    // These broadcasts are no longer allowed by the system, since they can
18196                    // cause significant thrashing at a crictical point (using the camera).
18197                    // Apps should use JobScehduler to monitor for media provider changes.
18198                    Slog.w(TAG, action + " no longer allowed; dropping from "
18199                            + UserHandle.formatUid(callingUid));
18200                    if (resultTo != null) {
18201                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18202                        try {
18203                            queue.performReceiveLocked(callerApp, resultTo, intent,
18204                                    Activity.RESULT_CANCELED, null, null,
18205                                    false, false, userId);
18206                        } catch (RemoteException e) {
18207                            Slog.w(TAG, "Failure ["
18208                                    + queue.mQueueName + "] sending broadcast result of "
18209                                    + intent, e);
18210
18211                        }
18212                    }
18213                    // Lie; we don't want to crash the app.
18214                    return ActivityManager.BROADCAST_SUCCESS;
18215            }
18216        }
18217
18218        // Add to the sticky list if requested.
18219        if (sticky) {
18220            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18221                    callingPid, callingUid)
18222                    != PackageManager.PERMISSION_GRANTED) {
18223                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18224                        + callingPid + ", uid=" + callingUid
18225                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18226                Slog.w(TAG, msg);
18227                throw new SecurityException(msg);
18228            }
18229            if (requiredPermissions != null && requiredPermissions.length > 0) {
18230                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18231                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18232                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18233            }
18234            if (intent.getComponent() != null) {
18235                throw new SecurityException(
18236                        "Sticky broadcasts can't target a specific component");
18237            }
18238            // We use userId directly here, since the "all" target is maintained
18239            // as a separate set of sticky broadcasts.
18240            if (userId != UserHandle.USER_ALL) {
18241                // But first, if this is not a broadcast to all users, then
18242                // make sure it doesn't conflict with an existing broadcast to
18243                // all users.
18244                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18245                        UserHandle.USER_ALL);
18246                if (stickies != null) {
18247                    ArrayList<Intent> list = stickies.get(intent.getAction());
18248                    if (list != null) {
18249                        int N = list.size();
18250                        int i;
18251                        for (i=0; i<N; i++) {
18252                            if (intent.filterEquals(list.get(i))) {
18253                                throw new IllegalArgumentException(
18254                                        "Sticky broadcast " + intent + " for user "
18255                                        + userId + " conflicts with existing global broadcast");
18256                            }
18257                        }
18258                    }
18259                }
18260            }
18261            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18262            if (stickies == null) {
18263                stickies = new ArrayMap<>();
18264                mStickyBroadcasts.put(userId, stickies);
18265            }
18266            ArrayList<Intent> list = stickies.get(intent.getAction());
18267            if (list == null) {
18268                list = new ArrayList<>();
18269                stickies.put(intent.getAction(), list);
18270            }
18271            final int stickiesCount = list.size();
18272            int i;
18273            for (i = 0; i < stickiesCount; i++) {
18274                if (intent.filterEquals(list.get(i))) {
18275                    // This sticky already exists, replace it.
18276                    list.set(i, new Intent(intent));
18277                    break;
18278                }
18279            }
18280            if (i >= stickiesCount) {
18281                list.add(new Intent(intent));
18282            }
18283        }
18284
18285        int[] users;
18286        if (userId == UserHandle.USER_ALL) {
18287            // Caller wants broadcast to go to all started users.
18288            users = mUserController.getStartedUserArrayLocked();
18289        } else {
18290            // Caller wants broadcast to go to one specific user.
18291            users = new int[] {userId};
18292        }
18293
18294        // Figure out who all will receive this broadcast.
18295        List receivers = null;
18296        List<BroadcastFilter> registeredReceivers = null;
18297        // Need to resolve the intent to interested receivers...
18298        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18299                 == 0) {
18300            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18301        }
18302        if (intent.getComponent() == null) {
18303            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18304                // Query one target user at a time, excluding shell-restricted users
18305                for (int i = 0; i < users.length; i++) {
18306                    if (mUserController.hasUserRestriction(
18307                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18308                        continue;
18309                    }
18310                    List<BroadcastFilter> registeredReceiversForUser =
18311                            mReceiverResolver.queryIntent(intent,
18312                                    resolvedType, false, users[i]);
18313                    if (registeredReceivers == null) {
18314                        registeredReceivers = registeredReceiversForUser;
18315                    } else if (registeredReceiversForUser != null) {
18316                        registeredReceivers.addAll(registeredReceiversForUser);
18317                    }
18318                }
18319            } else {
18320                registeredReceivers = mReceiverResolver.queryIntent(intent,
18321                        resolvedType, false, userId);
18322            }
18323        }
18324
18325        final boolean replacePending =
18326                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18327
18328        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18329                + " replacePending=" + replacePending);
18330
18331        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18332        if (!ordered && NR > 0) {
18333            // If we are not serializing this broadcast, then send the
18334            // registered receivers separately so they don't wait for the
18335            // components to be launched.
18336            if (isCallerSystem) {
18337                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18338                        isProtectedBroadcast, registeredReceivers);
18339            }
18340            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18341            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18342                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18343                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18344                    resultExtras, ordered, sticky, false, userId);
18345            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18346            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18347            if (!replaced) {
18348                queue.enqueueParallelBroadcastLocked(r);
18349                queue.scheduleBroadcastsLocked();
18350            }
18351            registeredReceivers = null;
18352            NR = 0;
18353        }
18354
18355        // Merge into one list.
18356        int ir = 0;
18357        if (receivers != null) {
18358            // A special case for PACKAGE_ADDED: do not allow the package
18359            // being added to see this broadcast.  This prevents them from
18360            // using this as a back door to get run as soon as they are
18361            // installed.  Maybe in the future we want to have a special install
18362            // broadcast or such for apps, but we'd like to deliberately make
18363            // this decision.
18364            String skipPackages[] = null;
18365            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18366                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18367                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18368                Uri data = intent.getData();
18369                if (data != null) {
18370                    String pkgName = data.getSchemeSpecificPart();
18371                    if (pkgName != null) {
18372                        skipPackages = new String[] { pkgName };
18373                    }
18374                }
18375            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18376                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18377            }
18378            if (skipPackages != null && (skipPackages.length > 0)) {
18379                for (String skipPackage : skipPackages) {
18380                    if (skipPackage != null) {
18381                        int NT = receivers.size();
18382                        for (int it=0; it<NT; it++) {
18383                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18384                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18385                                receivers.remove(it);
18386                                it--;
18387                                NT--;
18388                            }
18389                        }
18390                    }
18391                }
18392            }
18393
18394            int NT = receivers != null ? receivers.size() : 0;
18395            int it = 0;
18396            ResolveInfo curt = null;
18397            BroadcastFilter curr = null;
18398            while (it < NT && ir < NR) {
18399                if (curt == null) {
18400                    curt = (ResolveInfo)receivers.get(it);
18401                }
18402                if (curr == null) {
18403                    curr = registeredReceivers.get(ir);
18404                }
18405                if (curr.getPriority() >= curt.priority) {
18406                    // Insert this broadcast record into the final list.
18407                    receivers.add(it, curr);
18408                    ir++;
18409                    curr = null;
18410                    it++;
18411                    NT++;
18412                } else {
18413                    // Skip to the next ResolveInfo in the final list.
18414                    it++;
18415                    curt = null;
18416                }
18417            }
18418        }
18419        while (ir < NR) {
18420            if (receivers == null) {
18421                receivers = new ArrayList();
18422            }
18423            receivers.add(registeredReceivers.get(ir));
18424            ir++;
18425        }
18426
18427        if (isCallerSystem) {
18428            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18429                    isProtectedBroadcast, receivers);
18430        }
18431
18432        if ((receivers != null && receivers.size() > 0)
18433                || resultTo != null) {
18434            BroadcastQueue queue = broadcastQueueForIntent(intent);
18435            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18436                    callerPackage, callingPid, callingUid, resolvedType,
18437                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18438                    resultData, resultExtras, ordered, sticky, false, userId);
18439
18440            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18441                    + ": prev had " + queue.mOrderedBroadcasts.size());
18442            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18443                    "Enqueueing broadcast " + r.intent.getAction());
18444
18445            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18446            if (!replaced) {
18447                queue.enqueueOrderedBroadcastLocked(r);
18448                queue.scheduleBroadcastsLocked();
18449            }
18450        } else {
18451            // There was nobody interested in the broadcast, but we still want to record
18452            // that it happened.
18453            if (intent.getComponent() == null && intent.getPackage() == null
18454                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18455                // This was an implicit broadcast... let's record it for posterity.
18456                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18457            }
18458        }
18459
18460        return ActivityManager.BROADCAST_SUCCESS;
18461    }
18462
18463    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18464            int skipCount, long dispatchTime) {
18465        final long now = SystemClock.elapsedRealtime();
18466        if (mCurBroadcastStats == null ||
18467                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18468            mLastBroadcastStats = mCurBroadcastStats;
18469            if (mLastBroadcastStats != null) {
18470                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18471                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18472            }
18473            mCurBroadcastStats = new BroadcastStats();
18474        }
18475        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18476    }
18477
18478    final Intent verifyBroadcastLocked(Intent intent) {
18479        // Refuse possible leaked file descriptors
18480        if (intent != null && intent.hasFileDescriptors() == true) {
18481            throw new IllegalArgumentException("File descriptors passed in Intent");
18482        }
18483
18484        int flags = intent.getFlags();
18485
18486        if (!mProcessesReady) {
18487            // if the caller really truly claims to know what they're doing, go
18488            // ahead and allow the broadcast without launching any receivers
18489            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18490                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18491            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18492                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18493                        + " before boot completion");
18494                throw new IllegalStateException("Cannot broadcast before boot completed");
18495            }
18496        }
18497
18498        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18499            throw new IllegalArgumentException(
18500                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18501        }
18502
18503        return intent;
18504    }
18505
18506    public final int broadcastIntent(IApplicationThread caller,
18507            Intent intent, String resolvedType, IIntentReceiver resultTo,
18508            int resultCode, String resultData, Bundle resultExtras,
18509            String[] requiredPermissions, int appOp, Bundle bOptions,
18510            boolean serialized, boolean sticky, int userId) {
18511        enforceNotIsolatedCaller("broadcastIntent");
18512        synchronized(this) {
18513            intent = verifyBroadcastLocked(intent);
18514
18515            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18516            final int callingPid = Binder.getCallingPid();
18517            final int callingUid = Binder.getCallingUid();
18518            final long origId = Binder.clearCallingIdentity();
18519            int res = broadcastIntentLocked(callerApp,
18520                    callerApp != null ? callerApp.info.packageName : null,
18521                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18522                    requiredPermissions, appOp, bOptions, serialized, sticky,
18523                    callingPid, callingUid, userId);
18524            Binder.restoreCallingIdentity(origId);
18525            return res;
18526        }
18527    }
18528
18529
18530    int broadcastIntentInPackage(String packageName, int uid,
18531            Intent intent, String resolvedType, IIntentReceiver resultTo,
18532            int resultCode, String resultData, Bundle resultExtras,
18533            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18534            int userId) {
18535        synchronized(this) {
18536            intent = verifyBroadcastLocked(intent);
18537
18538            final long origId = Binder.clearCallingIdentity();
18539            String[] requiredPermissions = requiredPermission == null ? null
18540                    : new String[] {requiredPermission};
18541            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18542                    resultTo, resultCode, resultData, resultExtras,
18543                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18544                    sticky, -1, uid, userId);
18545            Binder.restoreCallingIdentity(origId);
18546            return res;
18547        }
18548    }
18549
18550    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18551        // Refuse possible leaked file descriptors
18552        if (intent != null && intent.hasFileDescriptors() == true) {
18553            throw new IllegalArgumentException("File descriptors passed in Intent");
18554        }
18555
18556        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18557                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18558
18559        synchronized(this) {
18560            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18561                    != PackageManager.PERMISSION_GRANTED) {
18562                String msg = "Permission Denial: unbroadcastIntent() from pid="
18563                        + Binder.getCallingPid()
18564                        + ", uid=" + Binder.getCallingUid()
18565                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18566                Slog.w(TAG, msg);
18567                throw new SecurityException(msg);
18568            }
18569            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18570            if (stickies != null) {
18571                ArrayList<Intent> list = stickies.get(intent.getAction());
18572                if (list != null) {
18573                    int N = list.size();
18574                    int i;
18575                    for (i=0; i<N; i++) {
18576                        if (intent.filterEquals(list.get(i))) {
18577                            list.remove(i);
18578                            break;
18579                        }
18580                    }
18581                    if (list.size() <= 0) {
18582                        stickies.remove(intent.getAction());
18583                    }
18584                }
18585                if (stickies.size() <= 0) {
18586                    mStickyBroadcasts.remove(userId);
18587                }
18588            }
18589        }
18590    }
18591
18592    void backgroundServicesFinishedLocked(int userId) {
18593        for (BroadcastQueue queue : mBroadcastQueues) {
18594            queue.backgroundServicesFinishedLocked(userId);
18595        }
18596    }
18597
18598    public void finishReceiver(IBinder who, int resultCode, String resultData,
18599            Bundle resultExtras, boolean resultAbort, int flags) {
18600        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18601
18602        // Refuse possible leaked file descriptors
18603        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18604            throw new IllegalArgumentException("File descriptors passed in Bundle");
18605        }
18606
18607        final long origId = Binder.clearCallingIdentity();
18608        try {
18609            boolean doNext = false;
18610            BroadcastRecord r;
18611
18612            synchronized(this) {
18613                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18614                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18615                r = queue.getMatchingOrderedReceiver(who);
18616                if (r != null) {
18617                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18618                        resultData, resultExtras, resultAbort, true);
18619                }
18620            }
18621
18622            if (doNext) {
18623                r.queue.processNextBroadcast(false);
18624            }
18625            trimApplications();
18626        } finally {
18627            Binder.restoreCallingIdentity(origId);
18628        }
18629    }
18630
18631    // =========================================================
18632    // INSTRUMENTATION
18633    // =========================================================
18634
18635    public boolean startInstrumentation(ComponentName className,
18636            String profileFile, int flags, Bundle arguments,
18637            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18638            int userId, String abiOverride) {
18639        enforceNotIsolatedCaller("startInstrumentation");
18640        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18641                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18642        // Refuse possible leaked file descriptors
18643        if (arguments != null && arguments.hasFileDescriptors()) {
18644            throw new IllegalArgumentException("File descriptors passed in Bundle");
18645        }
18646
18647        synchronized(this) {
18648            InstrumentationInfo ii = null;
18649            ApplicationInfo ai = null;
18650            try {
18651                ii = mContext.getPackageManager().getInstrumentationInfo(
18652                    className, STOCK_PM_FLAGS);
18653                ai = AppGlobals.getPackageManager().getApplicationInfo(
18654                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18655            } catch (PackageManager.NameNotFoundException e) {
18656            } catch (RemoteException e) {
18657            }
18658            if (ii == null) {
18659                reportStartInstrumentationFailureLocked(watcher, className,
18660                        "Unable to find instrumentation info for: " + className);
18661                return false;
18662            }
18663            if (ai == null) {
18664                reportStartInstrumentationFailureLocked(watcher, className,
18665                        "Unable to find instrumentation target package: " + ii.targetPackage);
18666                return false;
18667            }
18668            if (!ai.hasCode()) {
18669                reportStartInstrumentationFailureLocked(watcher, className,
18670                        "Instrumentation target has no code: " + ii.targetPackage);
18671                return false;
18672            }
18673
18674            int match = mContext.getPackageManager().checkSignatures(
18675                    ii.targetPackage, ii.packageName);
18676            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18677                String msg = "Permission Denial: starting instrumentation "
18678                        + className + " from pid="
18679                        + Binder.getCallingPid()
18680                        + ", uid=" + Binder.getCallingPid()
18681                        + " not allowed because package " + ii.packageName
18682                        + " does not have a signature matching the target "
18683                        + ii.targetPackage;
18684                reportStartInstrumentationFailureLocked(watcher, className, msg);
18685                throw new SecurityException(msg);
18686            }
18687
18688            final long origId = Binder.clearCallingIdentity();
18689            // Instrumentation can kill and relaunch even persistent processes
18690            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18691                    "start instr");
18692            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18693            app.instrumentationClass = className;
18694            app.instrumentationInfo = ai;
18695            app.instrumentationProfileFile = profileFile;
18696            app.instrumentationArguments = arguments;
18697            app.instrumentationWatcher = watcher;
18698            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18699            app.instrumentationResultClass = className;
18700            Binder.restoreCallingIdentity(origId);
18701        }
18702
18703        return true;
18704    }
18705
18706    /**
18707     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18708     * error to the logs, but if somebody is watching, send the report there too.  This enables
18709     * the "am" command to report errors with more information.
18710     *
18711     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18712     * @param cn The component name of the instrumentation.
18713     * @param report The error report.
18714     */
18715    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18716            ComponentName cn, String report) {
18717        Slog.w(TAG, report);
18718        if (watcher != null) {
18719            Bundle results = new Bundle();
18720            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18721            results.putString("Error", report);
18722            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18723        }
18724    }
18725
18726    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18727        if (app.instrumentationWatcher != null) {
18728            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18729                    app.instrumentationClass, resultCode, results);
18730        }
18731
18732        // Can't call out of the system process with a lock held, so post a message.
18733        if (app.instrumentationUiAutomationConnection != null) {
18734            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18735                    app.instrumentationUiAutomationConnection).sendToTarget();
18736        }
18737
18738        app.instrumentationWatcher = null;
18739        app.instrumentationUiAutomationConnection = null;
18740        app.instrumentationClass = null;
18741        app.instrumentationInfo = null;
18742        app.instrumentationProfileFile = null;
18743        app.instrumentationArguments = null;
18744
18745        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18746                "finished inst");
18747    }
18748
18749    public void finishInstrumentation(IApplicationThread target,
18750            int resultCode, Bundle results) {
18751        int userId = UserHandle.getCallingUserId();
18752        // Refuse possible leaked file descriptors
18753        if (results != null && results.hasFileDescriptors()) {
18754            throw new IllegalArgumentException("File descriptors passed in Intent");
18755        }
18756
18757        synchronized(this) {
18758            ProcessRecord app = getRecordForAppLocked(target);
18759            if (app == null) {
18760                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18761                return;
18762            }
18763            final long origId = Binder.clearCallingIdentity();
18764            finishInstrumentationLocked(app, resultCode, results);
18765            Binder.restoreCallingIdentity(origId);
18766        }
18767    }
18768
18769    // =========================================================
18770    // CONFIGURATION
18771    // =========================================================
18772
18773    public ConfigurationInfo getDeviceConfigurationInfo() {
18774        ConfigurationInfo config = new ConfigurationInfo();
18775        synchronized (this) {
18776            config.reqTouchScreen = mConfiguration.touchscreen;
18777            config.reqKeyboardType = mConfiguration.keyboard;
18778            config.reqNavigation = mConfiguration.navigation;
18779            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18780                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18781                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18782            }
18783            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18784                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18785                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18786            }
18787            config.reqGlEsVersion = GL_ES_VERSION;
18788        }
18789        return config;
18790    }
18791
18792    ActivityStack getFocusedStack() {
18793        return mStackSupervisor.getFocusedStack();
18794    }
18795
18796    @Override
18797    public int getFocusedStackId() throws RemoteException {
18798        ActivityStack focusedStack = getFocusedStack();
18799        if (focusedStack != null) {
18800            return focusedStack.getStackId();
18801        }
18802        return -1;
18803    }
18804
18805    public Configuration getConfiguration() {
18806        Configuration ci;
18807        synchronized(this) {
18808            ci = new Configuration(mConfiguration);
18809            ci.userSetLocale = false;
18810        }
18811        return ci;
18812    }
18813
18814    @Override
18815    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18816        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18817        synchronized (this) {
18818            mSuppressResizeConfigChanges = suppress;
18819        }
18820    }
18821
18822    @Override
18823    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18824        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18825        if (fromStackId == HOME_STACK_ID) {
18826            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18827        }
18828        synchronized (this) {
18829            final long origId = Binder.clearCallingIdentity();
18830            try {
18831                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18832            } finally {
18833                Binder.restoreCallingIdentity(origId);
18834            }
18835        }
18836    }
18837
18838    @Override
18839    public void updatePersistentConfiguration(Configuration values) {
18840        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18841                "updateConfiguration()");
18842        enforceWriteSettingsPermission("updateConfiguration()");
18843        if (values == null) {
18844            throw new NullPointerException("Configuration must not be null");
18845        }
18846
18847        int userId = UserHandle.getCallingUserId();
18848
18849        synchronized(this) {
18850            updatePersistentConfigurationLocked(values, userId);
18851        }
18852    }
18853
18854    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18855        final long origId = Binder.clearCallingIdentity();
18856        try {
18857            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18858        } finally {
18859            Binder.restoreCallingIdentity(origId);
18860        }
18861    }
18862
18863    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18864        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18865                FONT_SCALE, 1.0f, userId);
18866        if (mConfiguration.fontScale != scaleFactor) {
18867            final Configuration configuration = mWindowManager.computeNewConfiguration();
18868            configuration.fontScale = scaleFactor;
18869            synchronized (this) {
18870                updatePersistentConfigurationLocked(configuration, userId);
18871            }
18872        }
18873    }
18874
18875    private void enforceWriteSettingsPermission(String func) {
18876        int uid = Binder.getCallingUid();
18877        if (uid == Process.ROOT_UID) {
18878            return;
18879        }
18880
18881        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18882                Settings.getPackageNameForUid(mContext, uid), false)) {
18883            return;
18884        }
18885
18886        String msg = "Permission Denial: " + func + " from pid="
18887                + Binder.getCallingPid()
18888                + ", uid=" + uid
18889                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18890        Slog.w(TAG, msg);
18891        throw new SecurityException(msg);
18892    }
18893
18894    public void updateConfiguration(Configuration values) {
18895        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18896                "updateConfiguration()");
18897
18898        synchronized(this) {
18899            if (values == null && mWindowManager != null) {
18900                // sentinel: fetch the current configuration from the window manager
18901                values = mWindowManager.computeNewConfiguration();
18902            }
18903
18904            if (mWindowManager != null) {
18905                mProcessList.applyDisplaySize(mWindowManager);
18906            }
18907
18908            final long origId = Binder.clearCallingIdentity();
18909            if (values != null) {
18910                Settings.System.clearConfiguration(values);
18911            }
18912            updateConfigurationLocked(values, null, false);
18913            Binder.restoreCallingIdentity(origId);
18914        }
18915    }
18916
18917    void updateUserConfigurationLocked() {
18918        Configuration configuration = new Configuration(mConfiguration);
18919        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18920                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18921        updateConfigurationLocked(configuration, null, false);
18922    }
18923
18924    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18925            boolean initLocale) {
18926        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18927    }
18928
18929    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18930            boolean initLocale, boolean deferResume) {
18931        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18932        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18933                UserHandle.USER_NULL, deferResume);
18934    }
18935
18936    // To cache the list of supported system locales
18937    private String[] mSupportedSystemLocales = null;
18938
18939    /**
18940     * Do either or both things: (1) change the current configuration, and (2)
18941     * make sure the given activity is running with the (now) current
18942     * configuration.  Returns true if the activity has been left running, or
18943     * false if <var>starting</var> is being destroyed to match the new
18944     * configuration.
18945     *
18946     * @param userId is only used when persistent parameter is set to true to persist configuration
18947     *               for that particular user
18948     */
18949    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18950            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18951        int changes = 0;
18952
18953        if (mWindowManager != null) {
18954            mWindowManager.deferSurfaceLayout();
18955        }
18956        if (values != null) {
18957            Configuration newConfig = new Configuration(mConfiguration);
18958            changes = newConfig.updateFrom(values);
18959            if (changes != 0) {
18960                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18961                        "Updating configuration to: " + values);
18962
18963                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18964
18965                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18966                    final LocaleList locales = values.getLocales();
18967                    int bestLocaleIndex = 0;
18968                    if (locales.size() > 1) {
18969                        if (mSupportedSystemLocales == null) {
18970                            mSupportedSystemLocales =
18971                                    Resources.getSystem().getAssets().getLocales();
18972                        }
18973                        bestLocaleIndex = Math.max(0,
18974                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18975                    }
18976                    SystemProperties.set("persist.sys.locale",
18977                            locales.get(bestLocaleIndex).toLanguageTag());
18978                    LocaleList.setDefault(locales, bestLocaleIndex);
18979                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18980                            locales.get(bestLocaleIndex)));
18981                }
18982
18983                mConfigurationSeq++;
18984                if (mConfigurationSeq <= 0) {
18985                    mConfigurationSeq = 1;
18986                }
18987                newConfig.seq = mConfigurationSeq;
18988                mConfiguration = newConfig;
18989                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18990                mUsageStatsService.reportConfigurationChange(newConfig,
18991                        mUserController.getCurrentUserIdLocked());
18992                //mUsageStatsService.noteStartConfig(newConfig);
18993
18994                final Configuration configCopy = new Configuration(mConfiguration);
18995
18996                // TODO: If our config changes, should we auto dismiss any currently
18997                // showing dialogs?
18998                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18999
19000                AttributeCache ac = AttributeCache.instance();
19001                if (ac != null) {
19002                    ac.updateConfiguration(configCopy);
19003                }
19004
19005                // Make sure all resources in our process are updated
19006                // right now, so that anyone who is going to retrieve
19007                // resource values after we return will be sure to get
19008                // the new ones.  This is especially important during
19009                // boot, where the first config change needs to guarantee
19010                // all resources have that config before following boot
19011                // code is executed.
19012                mSystemThread.applyConfigurationToResources(configCopy);
19013
19014                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19015                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19016                    msg.obj = new Configuration(configCopy);
19017                    msg.arg1 = userId;
19018                    mHandler.sendMessage(msg);
19019                }
19020
19021                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19022                if (isDensityChange) {
19023                    // Reset the unsupported display size dialog.
19024                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19025
19026                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19027                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19028                }
19029
19030                for (int i=mLruProcesses.size()-1; i>=0; i--) {
19031                    ProcessRecord app = mLruProcesses.get(i);
19032                    try {
19033                        if (app.thread != null) {
19034                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19035                                    + app.processName + " new config " + mConfiguration);
19036                            app.thread.scheduleConfigurationChanged(configCopy);
19037                        }
19038                    } catch (Exception e) {
19039                    }
19040                }
19041                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19042                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19043                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
19044                        | Intent.FLAG_RECEIVER_FOREGROUND);
19045                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19046                        null, AppOpsManager.OP_NONE, null, false, false,
19047                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19048                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19049                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19050                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19051	            if (initLocale || !mProcessesReady) {
19052                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19053                    }
19054                    broadcastIntentLocked(null, null, intent,
19055                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19056                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19057                }
19058            }
19059            // Update the configuration with WM first and check if any of the stacks need to be
19060            // resized due to the configuration change. If so, resize the stacks now and do any
19061            // relaunches if necessary. This way we don't need to relaunch again below in
19062            // ensureActivityConfigurationLocked().
19063            if (mWindowManager != null) {
19064                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19065                if (resizedStacks != null) {
19066                    for (int stackId : resizedStacks) {
19067                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19068                        mStackSupervisor.resizeStackLocked(
19069                                stackId, newBounds, null, null, false, false, deferResume);
19070                    }
19071                }
19072            }
19073        }
19074
19075        boolean kept = true;
19076        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19077        // mainStack is null during startup.
19078        if (mainStack != null) {
19079            if (changes != 0 && starting == null) {
19080                // If the configuration changed, and the caller is not already
19081                // in the process of starting an activity, then find the top
19082                // activity to check if its configuration needs to change.
19083                starting = mainStack.topRunningActivityLocked();
19084            }
19085
19086            if (starting != null) {
19087                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19088                // And we need to make sure at this point that all other activities
19089                // are made visible with the correct configuration.
19090                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19091                        !PRESERVE_WINDOWS);
19092            }
19093        }
19094        if (mWindowManager != null) {
19095            mWindowManager.continueSurfaceLayout();
19096        }
19097        return kept;
19098    }
19099
19100    /**
19101     * Decide based on the configuration whether we should shouw the ANR,
19102     * crash, etc dialogs.  The idea is that if there is no affordence to
19103     * press the on-screen buttons, or the user experience would be more
19104     * greatly impacted than the crash itself, we shouldn't show the dialog.
19105     *
19106     * A thought: SystemUI might also want to get told about this, the Power
19107     * dialog / global actions also might want different behaviors.
19108     */
19109    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19110        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19111                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19112                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19113        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19114        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19115                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19116        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19117    }
19118
19119    @Override
19120    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19121        synchronized (this) {
19122            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19123            if (srec != null) {
19124                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19125            }
19126        }
19127        return false;
19128    }
19129
19130    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19131            Intent resultData) {
19132
19133        synchronized (this) {
19134            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19135            if (r != null) {
19136                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19137            }
19138            return false;
19139        }
19140    }
19141
19142    public int getLaunchedFromUid(IBinder activityToken) {
19143        ActivityRecord srec;
19144        synchronized (this) {
19145            srec = ActivityRecord.forTokenLocked(activityToken);
19146        }
19147        if (srec == null) {
19148            return -1;
19149        }
19150        return srec.launchedFromUid;
19151    }
19152
19153    public String getLaunchedFromPackage(IBinder activityToken) {
19154        ActivityRecord srec;
19155        synchronized (this) {
19156            srec = ActivityRecord.forTokenLocked(activityToken);
19157        }
19158        if (srec == null) {
19159            return null;
19160        }
19161        return srec.launchedFromPackage;
19162    }
19163
19164    // =========================================================
19165    // LIFETIME MANAGEMENT
19166    // =========================================================
19167
19168    // Returns whether the app is receiving broadcast.
19169    // If receiving, fetch all broadcast queues which the app is
19170    // the current [or imminent] receiver on.
19171    private boolean isReceivingBroadcastLocked(ProcessRecord app,
19172            ArraySet<BroadcastQueue> receivingQueues) {
19173        if (!app.curReceivers.isEmpty()) {
19174            for (BroadcastRecord r : app.curReceivers) {
19175                receivingQueues.add(r.queue);
19176            }
19177            return true;
19178        }
19179
19180        // It's not the current receiver, but it might be starting up to become one
19181        for (BroadcastQueue queue : mBroadcastQueues) {
19182            final BroadcastRecord r = queue.mPendingBroadcast;
19183            if (r != null && r.curApp == app) {
19184                // found it; report which queue it's in
19185                receivingQueues.add(queue);
19186            }
19187        }
19188
19189        return !receivingQueues.isEmpty();
19190    }
19191
19192    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19193            int targetUid, ComponentName targetComponent, String targetProcess) {
19194        if (!mTrackingAssociations) {
19195            return null;
19196        }
19197        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19198                = mAssociations.get(targetUid);
19199        if (components == null) {
19200            components = new ArrayMap<>();
19201            mAssociations.put(targetUid, components);
19202        }
19203        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19204        if (sourceUids == null) {
19205            sourceUids = new SparseArray<>();
19206            components.put(targetComponent, sourceUids);
19207        }
19208        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19209        if (sourceProcesses == null) {
19210            sourceProcesses = new ArrayMap<>();
19211            sourceUids.put(sourceUid, sourceProcesses);
19212        }
19213        Association ass = sourceProcesses.get(sourceProcess);
19214        if (ass == null) {
19215            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19216                    targetProcess);
19217            sourceProcesses.put(sourceProcess, ass);
19218        }
19219        ass.mCount++;
19220        ass.mNesting++;
19221        if (ass.mNesting == 1) {
19222            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19223            ass.mLastState = sourceState;
19224        }
19225        return ass;
19226    }
19227
19228    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19229            ComponentName targetComponent) {
19230        if (!mTrackingAssociations) {
19231            return;
19232        }
19233        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19234                = mAssociations.get(targetUid);
19235        if (components == null) {
19236            return;
19237        }
19238        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19239        if (sourceUids == null) {
19240            return;
19241        }
19242        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19243        if (sourceProcesses == null) {
19244            return;
19245        }
19246        Association ass = sourceProcesses.get(sourceProcess);
19247        if (ass == null || ass.mNesting <= 0) {
19248            return;
19249        }
19250        ass.mNesting--;
19251        if (ass.mNesting == 0) {
19252            long uptime = SystemClock.uptimeMillis();
19253            ass.mTime += uptime - ass.mStartTime;
19254            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19255                    += uptime - ass.mLastStateUptime;
19256            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19257        }
19258    }
19259
19260    private void noteUidProcessState(final int uid, final int state) {
19261        mBatteryStatsService.noteUidProcessState(uid, state);
19262        if (mTrackingAssociations) {
19263            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19264                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19265                        = mAssociations.valueAt(i1);
19266                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19267                    SparseArray<ArrayMap<String, Association>> sourceUids
19268                            = targetComponents.valueAt(i2);
19269                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19270                    if (sourceProcesses != null) {
19271                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19272                            Association ass = sourceProcesses.valueAt(i4);
19273                            if (ass.mNesting >= 1) {
19274                                // currently associated
19275                                long uptime = SystemClock.uptimeMillis();
19276                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19277                                        += uptime - ass.mLastStateUptime;
19278                                ass.mLastState = state;
19279                                ass.mLastStateUptime = uptime;
19280                            }
19281                        }
19282                    }
19283                }
19284            }
19285        }
19286    }
19287
19288    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19289            boolean doingAll, long now) {
19290        if (mAdjSeq == app.adjSeq) {
19291            // This adjustment has already been computed.
19292            return app.curRawAdj;
19293        }
19294
19295        if (app.thread == null) {
19296            app.adjSeq = mAdjSeq;
19297            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19298            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19299            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19300        }
19301
19302        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19303        app.adjSource = null;
19304        app.adjTarget = null;
19305        app.empty = false;
19306        app.cached = false;
19307
19308        final int activitiesSize = app.activities.size();
19309
19310        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19311            // The max adjustment doesn't allow this app to be anything
19312            // below foreground, so it is not worth doing work for it.
19313            app.adjType = "fixed";
19314            app.adjSeq = mAdjSeq;
19315            app.curRawAdj = app.maxAdj;
19316            app.foregroundActivities = false;
19317            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19318            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19319            // System processes can do UI, and when they do we want to have
19320            // them trim their memory after the user leaves the UI.  To
19321            // facilitate this, here we need to determine whether or not it
19322            // is currently showing UI.
19323            app.systemNoUi = true;
19324            if (app == TOP_APP) {
19325                app.systemNoUi = false;
19326                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19327                app.adjType = "pers-top-activity";
19328            } else if (app.hasTopUi) {
19329                app.systemNoUi = false;
19330                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19331                app.adjType = "pers-top-ui";
19332            } else if (activitiesSize > 0) {
19333                for (int j = 0; j < activitiesSize; j++) {
19334                    final ActivityRecord r = app.activities.get(j);
19335                    if (r.visible) {
19336                        app.systemNoUi = false;
19337                    }
19338                }
19339            }
19340            if (!app.systemNoUi) {
19341                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19342            }
19343            return (app.curAdj=app.maxAdj);
19344        }
19345
19346        app.systemNoUi = false;
19347
19348        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19349
19350        // Determine the importance of the process, starting with most
19351        // important to least, and assign an appropriate OOM adjustment.
19352        int adj;
19353        int schedGroup;
19354        int procState;
19355        boolean foregroundActivities = false;
19356        final ArraySet<BroadcastQueue> queues = new ArraySet<BroadcastQueue>();
19357        if (app == TOP_APP) {
19358            // The last app on the list is the foreground app.
19359            adj = ProcessList.FOREGROUND_APP_ADJ;
19360            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19361            app.adjType = "top-activity";
19362            foregroundActivities = true;
19363            procState = PROCESS_STATE_CUR_TOP;
19364        } else if (app.instrumentationClass != null) {
19365            // Don't want to kill running instrumentation.
19366            adj = ProcessList.FOREGROUND_APP_ADJ;
19367            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19368            app.adjType = "instrumentation";
19369            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19370        } else if (isReceivingBroadcastLocked(app, queues)) {
19371            // An app that is currently receiving a broadcast also
19372            // counts as being in the foreground for OOM killer purposes.
19373            // It's placed in a sched group based on the nature of the
19374            // broadcast as reflected by which queue it's active in.
19375            adj = ProcessList.FOREGROUND_APP_ADJ;
19376            schedGroup = (queues.contains(mFgBroadcastQueue))
19377                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19378            app.adjType = "broadcast";
19379            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19380        } else if (app.executingServices.size() > 0) {
19381            // An app that is currently executing a service callback also
19382            // counts as being in the foreground.
19383            adj = ProcessList.FOREGROUND_APP_ADJ;
19384            schedGroup = app.execServicesFg ?
19385                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19386            app.adjType = "exec-service";
19387            procState = ActivityManager.PROCESS_STATE_SERVICE;
19388            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19389        } else {
19390            // As far as we know the process is empty.  We may change our mind later.
19391            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19392            // At this point we don't actually know the adjustment.  Use the cached adj
19393            // value that the caller wants us to.
19394            adj = cachedAdj;
19395            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19396            app.cached = true;
19397            app.empty = true;
19398            app.adjType = "cch-empty";
19399        }
19400
19401        // Examine all activities if not already foreground.
19402        if (!foregroundActivities && activitiesSize > 0) {
19403            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19404            for (int j = 0; j < activitiesSize; j++) {
19405                final ActivityRecord r = app.activities.get(j);
19406                if (r.app != app) {
19407                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19408                            + " instead of expected " + app);
19409                    if (r.app == null || (r.app.uid == app.uid)) {
19410                        // Only fix things up when they look sane
19411                        r.app = app;
19412                    } else {
19413                        continue;
19414                    }
19415                }
19416                if (r.visible) {
19417                    // App has a visible activity; only upgrade adjustment.
19418                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19419                        adj = ProcessList.VISIBLE_APP_ADJ;
19420                        app.adjType = "visible";
19421                    }
19422                    if (procState > PROCESS_STATE_CUR_TOP) {
19423                        procState = PROCESS_STATE_CUR_TOP;
19424                    }
19425                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19426                    app.cached = false;
19427                    app.empty = false;
19428                    foregroundActivities = true;
19429                    if (r.task != null && minLayer > 0) {
19430                        final int layer = r.task.mLayerRank;
19431                        if (layer >= 0 && minLayer > layer) {
19432                            minLayer = layer;
19433                        }
19434                    }
19435                    break;
19436                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19437                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19438                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19439                        app.adjType = "pausing";
19440                    }
19441                    if (procState > PROCESS_STATE_CUR_TOP) {
19442                        procState = PROCESS_STATE_CUR_TOP;
19443                    }
19444                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19445                    app.cached = false;
19446                    app.empty = false;
19447                    foregroundActivities = true;
19448                } else if (r.state == ActivityState.STOPPING) {
19449                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19450                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19451                        app.adjType = "stopping";
19452                    }
19453                    // For the process state, we will at this point consider the
19454                    // process to be cached.  It will be cached either as an activity
19455                    // or empty depending on whether the activity is finishing.  We do
19456                    // this so that we can treat the process as cached for purposes of
19457                    // memory trimming (determing current memory level, trim command to
19458                    // send to process) since there can be an arbitrary number of stopping
19459                    // processes and they should soon all go into the cached state.
19460                    if (!r.finishing) {
19461                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19462                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19463                        }
19464                    }
19465                    app.cached = false;
19466                    app.empty = false;
19467                    foregroundActivities = true;
19468                } else {
19469                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19470                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19471                        app.adjType = "cch-act";
19472                    }
19473                }
19474            }
19475            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19476                adj += minLayer;
19477            }
19478        }
19479
19480        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19481                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19482            if (app.foregroundServices) {
19483                // The user is aware of this app, so make it visible.
19484                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19485                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19486                app.cached = false;
19487                app.adjType = "fg-service";
19488                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19489            } else if (app.forcingToForeground != null) {
19490                // The user is aware of this app, so make it visible.
19491                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19492                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19493                app.cached = false;
19494                app.adjType = "force-fg";
19495                app.adjSource = app.forcingToForeground;
19496                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19497            }
19498        }
19499
19500        if (app == mHeavyWeightProcess) {
19501            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19502                // We don't want to kill the current heavy-weight process.
19503                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19504                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19505                app.cached = false;
19506                app.adjType = "heavy";
19507            }
19508            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19509                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19510            }
19511        }
19512
19513        if (app == mHomeProcess) {
19514            if (adj > ProcessList.HOME_APP_ADJ) {
19515                // This process is hosting what we currently consider to be the
19516                // home app, so we don't want to let it go into the background.
19517                adj = ProcessList.HOME_APP_ADJ;
19518                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19519                app.cached = false;
19520                app.adjType = "home";
19521            }
19522            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19523                procState = ActivityManager.PROCESS_STATE_HOME;
19524            }
19525        }
19526
19527        if (app == mPreviousProcess && app.activities.size() > 0) {
19528            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19529                // This was the previous process that showed UI to the user.
19530                // We want to try to keep it around more aggressively, to give
19531                // a good experience around switching between two apps.
19532                adj = ProcessList.PREVIOUS_APP_ADJ;
19533                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19534                app.cached = false;
19535                app.adjType = "previous";
19536            }
19537            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19538                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19539            }
19540        }
19541
19542        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19543                + " reason=" + app.adjType);
19544
19545        // By default, we use the computed adjustment.  It may be changed if
19546        // there are applications dependent on our services or providers, but
19547        // this gives us a baseline and makes sure we don't get into an
19548        // infinite recursion.
19549        app.adjSeq = mAdjSeq;
19550        app.curRawAdj = adj;
19551        app.hasStartedServices = false;
19552
19553        if (mBackupTarget != null && app == mBackupTarget.app) {
19554            // If possible we want to avoid killing apps while they're being backed up
19555            if (adj > ProcessList.BACKUP_APP_ADJ) {
19556                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19557                adj = ProcessList.BACKUP_APP_ADJ;
19558                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19559                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19560                }
19561                app.adjType = "backup";
19562                app.cached = false;
19563            }
19564            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19565                procState = ActivityManager.PROCESS_STATE_BACKUP;
19566            }
19567        }
19568
19569        boolean mayBeTop = false;
19570
19571        for (int is = app.services.size()-1;
19572                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19573                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19574                        || procState > ActivityManager.PROCESS_STATE_TOP);
19575                is--) {
19576            ServiceRecord s = app.services.valueAt(is);
19577            if (s.startRequested) {
19578                app.hasStartedServices = true;
19579                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19580                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19581                }
19582                if (app.hasShownUi && app != mHomeProcess) {
19583                    // If this process has shown some UI, let it immediately
19584                    // go to the LRU list because it may be pretty heavy with
19585                    // UI stuff.  We'll tag it with a label just to help
19586                    // debug and understand what is going on.
19587                    if (adj > ProcessList.SERVICE_ADJ) {
19588                        app.adjType = "cch-started-ui-services";
19589                    }
19590                } else {
19591                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19592                        // This service has seen some activity within
19593                        // recent memory, so we will keep its process ahead
19594                        // of the background processes.
19595                        if (adj > ProcessList.SERVICE_ADJ) {
19596                            adj = ProcessList.SERVICE_ADJ;
19597                            app.adjType = "started-services";
19598                            app.cached = false;
19599                        }
19600                    }
19601                    // If we have let the service slide into the background
19602                    // state, still have some text describing what it is doing
19603                    // even though the service no longer has an impact.
19604                    if (adj > ProcessList.SERVICE_ADJ) {
19605                        app.adjType = "cch-started-services";
19606                    }
19607                }
19608            }
19609
19610            for (int conni = s.connections.size()-1;
19611                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19612                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19613                            || procState > ActivityManager.PROCESS_STATE_TOP);
19614                    conni--) {
19615                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19616                for (int i = 0;
19617                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19618                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19619                                || procState > ActivityManager.PROCESS_STATE_TOP);
19620                        i++) {
19621                    // XXX should compute this based on the max of
19622                    // all connected clients.
19623                    ConnectionRecord cr = clist.get(i);
19624                    if (cr.binding.client == app) {
19625                        // Binding to ourself is not interesting.
19626                        continue;
19627                    }
19628
19629                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19630                        ProcessRecord client = cr.binding.client;
19631                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19632                                TOP_APP, doingAll, now);
19633                        int clientProcState = client.curProcState;
19634                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19635                            // If the other app is cached for any reason, for purposes here
19636                            // we are going to consider it empty.  The specific cached state
19637                            // doesn't propagate except under certain conditions.
19638                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19639                        }
19640                        String adjType = null;
19641                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19642                            // Not doing bind OOM management, so treat
19643                            // this guy more like a started service.
19644                            if (app.hasShownUi && app != mHomeProcess) {
19645                                // If this process has shown some UI, let it immediately
19646                                // go to the LRU list because it may be pretty heavy with
19647                                // UI stuff.  We'll tag it with a label just to help
19648                                // debug and understand what is going on.
19649                                if (adj > clientAdj) {
19650                                    adjType = "cch-bound-ui-services";
19651                                }
19652                                app.cached = false;
19653                                clientAdj = adj;
19654                                clientProcState = procState;
19655                            } else {
19656                                if (now >= (s.lastActivity
19657                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19658                                    // This service has not seen activity within
19659                                    // recent memory, so allow it to drop to the
19660                                    // LRU list if there is no other reason to keep
19661                                    // it around.  We'll also tag it with a label just
19662                                    // to help debug and undertand what is going on.
19663                                    if (adj > clientAdj) {
19664                                        adjType = "cch-bound-services";
19665                                    }
19666                                    clientAdj = adj;
19667                                }
19668                            }
19669                        }
19670                        if (adj > clientAdj) {
19671                            // If this process has recently shown UI, and
19672                            // the process that is binding to it is less
19673                            // important than being visible, then we don't
19674                            // care about the binding as much as we care
19675                            // about letting this process get into the LRU
19676                            // list to be killed and restarted if needed for
19677                            // memory.
19678                            if (app.hasShownUi && app != mHomeProcess
19679                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19680                                adjType = "cch-bound-ui-services";
19681                            } else {
19682                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19683                                        |Context.BIND_IMPORTANT)) != 0) {
19684                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19685                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19686                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19687                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19688                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19689                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19690                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19691                                    adj = clientAdj;
19692                                } else {
19693                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19694                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19695                                    }
19696                                }
19697                                if (!client.cached) {
19698                                    app.cached = false;
19699                                }
19700                                adjType = "service";
19701                            }
19702                        }
19703                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19704                            // This will treat important bound services identically to
19705                            // the top app, which may behave differently than generic
19706                            // foreground work.
19707                            if (client.curSchedGroup > schedGroup) {
19708                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19709                                    schedGroup = client.curSchedGroup;
19710                                } else {
19711                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19712                                }
19713                            }
19714                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19715                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19716                                    // Special handling of clients who are in the top state.
19717                                    // We *may* want to consider this process to be in the
19718                                    // top state as well, but only if there is not another
19719                                    // reason for it to be running.  Being on the top is a
19720                                    // special state, meaning you are specifically running
19721                                    // for the current top app.  If the process is already
19722                                    // running in the background for some other reason, it
19723                                    // is more important to continue considering it to be
19724                                    // in the background state.
19725                                    mayBeTop = true;
19726                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19727                                } else {
19728                                    // Special handling for above-top states (persistent
19729                                    // processes).  These should not bring the current process
19730                                    // into the top state, since they are not on top.  Instead
19731                                    // give them the best state after that.
19732                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19733                                        clientProcState =
19734                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19735                                    } else if (mWakefulness
19736                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19737                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19738                                                    != 0) {
19739                                        clientProcState =
19740                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19741                                    } else {
19742                                        clientProcState =
19743                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19744                                    }
19745                                }
19746                            }
19747                        } else {
19748                            if (clientProcState <
19749                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19750                                clientProcState =
19751                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19752                            }
19753                        }
19754                        if (procState > clientProcState) {
19755                            procState = clientProcState;
19756                        }
19757                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19758                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19759                            app.pendingUiClean = true;
19760                        }
19761                        if (adjType != null) {
19762                            app.adjType = adjType;
19763                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19764                                    .REASON_SERVICE_IN_USE;
19765                            app.adjSource = cr.binding.client;
19766                            app.adjSourceProcState = clientProcState;
19767                            app.adjTarget = s.name;
19768                        }
19769                    }
19770                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19771                        app.treatLikeActivity = true;
19772                    }
19773                    final ActivityRecord a = cr.activity;
19774                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19775                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19776                            (a.visible || a.state == ActivityState.RESUMED ||
19777                             a.state == ActivityState.PAUSING)) {
19778                            adj = ProcessList.FOREGROUND_APP_ADJ;
19779                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19780                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19781                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19782                                } else {
19783                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19784                                }
19785                            }
19786                            app.cached = false;
19787                            app.adjType = "service";
19788                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19789                                    .REASON_SERVICE_IN_USE;
19790                            app.adjSource = a;
19791                            app.adjSourceProcState = procState;
19792                            app.adjTarget = s.name;
19793                        }
19794                    }
19795                }
19796            }
19797        }
19798
19799        for (int provi = app.pubProviders.size()-1;
19800                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19801                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19802                        || procState > ActivityManager.PROCESS_STATE_TOP);
19803                provi--) {
19804            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19805            for (int i = cpr.connections.size()-1;
19806                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19807                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19808                            || procState > ActivityManager.PROCESS_STATE_TOP);
19809                    i--) {
19810                ContentProviderConnection conn = cpr.connections.get(i);
19811                ProcessRecord client = conn.client;
19812                if (client == app) {
19813                    // Being our own client is not interesting.
19814                    continue;
19815                }
19816                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19817                int clientProcState = client.curProcState;
19818                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19819                    // If the other app is cached for any reason, for purposes here
19820                    // we are going to consider it empty.
19821                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19822                }
19823                if (adj > clientAdj) {
19824                    if (app.hasShownUi && app != mHomeProcess
19825                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19826                        app.adjType = "cch-ui-provider";
19827                    } else {
19828                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19829                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19830                        app.adjType = "provider";
19831                    }
19832                    app.cached &= client.cached;
19833                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19834                            .REASON_PROVIDER_IN_USE;
19835                    app.adjSource = client;
19836                    app.adjSourceProcState = clientProcState;
19837                    app.adjTarget = cpr.name;
19838                }
19839                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19840                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19841                        // Special handling of clients who are in the top state.
19842                        // We *may* want to consider this process to be in the
19843                        // top state as well, but only if there is not another
19844                        // reason for it to be running.  Being on the top is a
19845                        // special state, meaning you are specifically running
19846                        // for the current top app.  If the process is already
19847                        // running in the background for some other reason, it
19848                        // is more important to continue considering it to be
19849                        // in the background state.
19850                        mayBeTop = true;
19851                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19852                    } else {
19853                        // Special handling for above-top states (persistent
19854                        // processes).  These should not bring the current process
19855                        // into the top state, since they are not on top.  Instead
19856                        // give them the best state after that.
19857                        clientProcState =
19858                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19859                    }
19860                }
19861                if (procState > clientProcState) {
19862                    procState = clientProcState;
19863                }
19864                if (client.curSchedGroup > schedGroup) {
19865                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19866                }
19867            }
19868            // If the provider has external (non-framework) process
19869            // dependencies, ensure that its adjustment is at least
19870            // FOREGROUND_APP_ADJ.
19871            if (cpr.hasExternalProcessHandles()) {
19872                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19873                    adj = ProcessList.FOREGROUND_APP_ADJ;
19874                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19875                    app.cached = false;
19876                    app.adjType = "provider";
19877                    app.adjTarget = cpr.name;
19878                }
19879                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19880                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19881                }
19882            }
19883        }
19884
19885        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19886            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19887                adj = ProcessList.PREVIOUS_APP_ADJ;
19888                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19889                app.cached = false;
19890                app.adjType = "provider";
19891            }
19892            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19893                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19894            }
19895        }
19896
19897        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19898            // A client of one of our services or providers is in the top state.  We
19899            // *may* want to be in the top state, but not if we are already running in
19900            // the background for some other reason.  For the decision here, we are going
19901            // to pick out a few specific states that we want to remain in when a client
19902            // is top (states that tend to be longer-term) and otherwise allow it to go
19903            // to the top state.
19904            switch (procState) {
19905                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19906                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19907                case ActivityManager.PROCESS_STATE_SERVICE:
19908                    // These all are longer-term states, so pull them up to the top
19909                    // of the background states, but not all the way to the top state.
19910                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19911                    break;
19912                default:
19913                    // Otherwise, top is a better choice, so take it.
19914                    procState = ActivityManager.PROCESS_STATE_TOP;
19915                    break;
19916            }
19917        }
19918
19919        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19920            if (app.hasClientActivities) {
19921                // This is a cached process, but with client activities.  Mark it so.
19922                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19923                app.adjType = "cch-client-act";
19924            } else if (app.treatLikeActivity) {
19925                // This is a cached process, but somebody wants us to treat it like it has
19926                // an activity, okay!
19927                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19928                app.adjType = "cch-as-act";
19929            }
19930        }
19931
19932        if (adj == ProcessList.SERVICE_ADJ) {
19933            if (doingAll) {
19934                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19935                mNewNumServiceProcs++;
19936                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19937                if (!app.serviceb) {
19938                    // This service isn't far enough down on the LRU list to
19939                    // normally be a B service, but if we are low on RAM and it
19940                    // is large we want to force it down since we would prefer to
19941                    // keep launcher over it.
19942                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19943                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19944                        app.serviceHighRam = true;
19945                        app.serviceb = true;
19946                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19947                    } else {
19948                        mNewNumAServiceProcs++;
19949                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19950                    }
19951                } else {
19952                    app.serviceHighRam = false;
19953                }
19954            }
19955            if (app.serviceb) {
19956                adj = ProcessList.SERVICE_B_ADJ;
19957            }
19958        }
19959
19960        app.curRawAdj = adj;
19961
19962        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19963        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19964        if (adj > app.maxAdj) {
19965            adj = app.maxAdj;
19966            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19967                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19968            }
19969        }
19970
19971        // Do final modification to adj.  Everything we do between here and applying
19972        // the final setAdj must be done in this function, because we will also use
19973        // it when computing the final cached adj later.  Note that we don't need to
19974        // worry about this for max adj above, since max adj will always be used to
19975        // keep it out of the cached vaues.
19976        app.curAdj = app.modifyRawOomAdj(adj);
19977        app.curSchedGroup = schedGroup;
19978        app.curProcState = procState;
19979        app.foregroundActivities = foregroundActivities;
19980
19981        return app.curRawAdj;
19982    }
19983
19984    /**
19985     * Record new PSS sample for a process.
19986     */
19987    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19988            long now) {
19989        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19990                swapPss * 1024);
19991        proc.lastPssTime = now;
19992        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19993        if (DEBUG_PSS) Slog.d(TAG_PSS,
19994                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19995                + " state=" + ProcessList.makeProcStateString(procState));
19996        if (proc.initialIdlePss == 0) {
19997            proc.initialIdlePss = pss;
19998        }
19999        proc.lastPss = pss;
20000        proc.lastSwapPss = swapPss;
20001        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20002            proc.lastCachedPss = pss;
20003            proc.lastCachedSwapPss = swapPss;
20004        }
20005
20006        final SparseArray<Pair<Long, String>> watchUids
20007                = mMemWatchProcesses.getMap().get(proc.processName);
20008        Long check = null;
20009        if (watchUids != null) {
20010            Pair<Long, String> val = watchUids.get(proc.uid);
20011            if (val == null) {
20012                val = watchUids.get(0);
20013            }
20014            if (val != null) {
20015                check = val.first;
20016            }
20017        }
20018        if (check != null) {
20019            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20020                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20021                if (!isDebuggable) {
20022                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20023                        isDebuggable = true;
20024                    }
20025                }
20026                if (isDebuggable) {
20027                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20028                    final ProcessRecord myProc = proc;
20029                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20030                    mMemWatchDumpProcName = proc.processName;
20031                    mMemWatchDumpFile = heapdumpFile.toString();
20032                    mMemWatchDumpPid = proc.pid;
20033                    mMemWatchDumpUid = proc.uid;
20034                    BackgroundThread.getHandler().post(new Runnable() {
20035                        @Override
20036                        public void run() {
20037                            revokeUriPermission(ActivityThread.currentActivityThread()
20038                                            .getApplicationThread(),
20039                                    DumpHeapActivity.JAVA_URI,
20040                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20041                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20042                                    UserHandle.myUserId());
20043                            ParcelFileDescriptor fd = null;
20044                            try {
20045                                heapdumpFile.delete();
20046                                fd = ParcelFileDescriptor.open(heapdumpFile,
20047                                        ParcelFileDescriptor.MODE_CREATE |
20048                                                ParcelFileDescriptor.MODE_TRUNCATE |
20049                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20050                                                ParcelFileDescriptor.MODE_APPEND);
20051                                IApplicationThread thread = myProc.thread;
20052                                if (thread != null) {
20053                                    try {
20054                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20055                                                "Requesting dump heap from "
20056                                                + myProc + " to " + heapdumpFile);
20057                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20058                                    } catch (RemoteException e) {
20059                                    }
20060                                }
20061                            } catch (FileNotFoundException e) {
20062                                e.printStackTrace();
20063                            } finally {
20064                                if (fd != null) {
20065                                    try {
20066                                        fd.close();
20067                                    } catch (IOException e) {
20068                                    }
20069                                }
20070                            }
20071                        }
20072                    });
20073                } else {
20074                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20075                            + ", but debugging not enabled");
20076                }
20077            }
20078        }
20079    }
20080
20081    /**
20082     * Schedule PSS collection of a process.
20083     */
20084    void requestPssLocked(ProcessRecord proc, int procState) {
20085        if (mPendingPssProcesses.contains(proc)) {
20086            return;
20087        }
20088        if (mPendingPssProcesses.size() == 0) {
20089            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20090        }
20091        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20092        proc.pssProcState = procState;
20093        mPendingPssProcesses.add(proc);
20094    }
20095
20096    /**
20097     * Schedule PSS collection of all processes.
20098     */
20099    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20100        if (!always) {
20101            if (now < (mLastFullPssTime +
20102                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20103                return;
20104            }
20105        }
20106        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20107        mLastFullPssTime = now;
20108        mFullPssPending = true;
20109        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20110        mPendingPssProcesses.clear();
20111        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20112            ProcessRecord app = mLruProcesses.get(i);
20113            if (app.thread == null
20114                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20115                continue;
20116            }
20117            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20118                app.pssProcState = app.setProcState;
20119                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20120                        mTestPssMode, isSleepingLocked(), now);
20121                mPendingPssProcesses.add(app);
20122            }
20123        }
20124        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20125    }
20126
20127    public void setTestPssMode(boolean enabled) {
20128        synchronized (this) {
20129            mTestPssMode = enabled;
20130            if (enabled) {
20131                // Whenever we enable the mode, we want to take a snapshot all of current
20132                // process mem use.
20133                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20134            }
20135        }
20136    }
20137
20138    /**
20139     * Ask a given process to GC right now.
20140     */
20141    final void performAppGcLocked(ProcessRecord app) {
20142        try {
20143            app.lastRequestedGc = SystemClock.uptimeMillis();
20144            if (app.thread != null) {
20145                if (app.reportLowMemory) {
20146                    app.reportLowMemory = false;
20147                    app.thread.scheduleLowMemory();
20148                } else {
20149                    app.thread.processInBackground();
20150                }
20151            }
20152        } catch (Exception e) {
20153            // whatever.
20154        }
20155    }
20156
20157    /**
20158     * Returns true if things are idle enough to perform GCs.
20159     */
20160    private final boolean canGcNowLocked() {
20161        boolean processingBroadcasts = false;
20162        for (BroadcastQueue q : mBroadcastQueues) {
20163            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20164                processingBroadcasts = true;
20165            }
20166        }
20167        return !processingBroadcasts
20168                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20169    }
20170
20171    /**
20172     * Perform GCs on all processes that are waiting for it, but only
20173     * if things are idle.
20174     */
20175    final void performAppGcsLocked() {
20176        final int N = mProcessesToGc.size();
20177        if (N <= 0) {
20178            return;
20179        }
20180        if (canGcNowLocked()) {
20181            while (mProcessesToGc.size() > 0) {
20182                ProcessRecord proc = mProcessesToGc.remove(0);
20183                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20184                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20185                            <= SystemClock.uptimeMillis()) {
20186                        // To avoid spamming the system, we will GC processes one
20187                        // at a time, waiting a few seconds between each.
20188                        performAppGcLocked(proc);
20189                        scheduleAppGcsLocked();
20190                        return;
20191                    } else {
20192                        // It hasn't been long enough since we last GCed this
20193                        // process...  put it in the list to wait for its time.
20194                        addProcessToGcListLocked(proc);
20195                        break;
20196                    }
20197                }
20198            }
20199
20200            scheduleAppGcsLocked();
20201        }
20202    }
20203
20204    /**
20205     * If all looks good, perform GCs on all processes waiting for them.
20206     */
20207    final void performAppGcsIfAppropriateLocked() {
20208        if (canGcNowLocked()) {
20209            performAppGcsLocked();
20210            return;
20211        }
20212        // Still not idle, wait some more.
20213        scheduleAppGcsLocked();
20214    }
20215
20216    /**
20217     * Schedule the execution of all pending app GCs.
20218     */
20219    final void scheduleAppGcsLocked() {
20220        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20221
20222        if (mProcessesToGc.size() > 0) {
20223            // Schedule a GC for the time to the next process.
20224            ProcessRecord proc = mProcessesToGc.get(0);
20225            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20226
20227            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20228            long now = SystemClock.uptimeMillis();
20229            if (when < (now+GC_TIMEOUT)) {
20230                when = now + GC_TIMEOUT;
20231            }
20232            mHandler.sendMessageAtTime(msg, when);
20233        }
20234    }
20235
20236    /**
20237     * Add a process to the array of processes waiting to be GCed.  Keeps the
20238     * list in sorted order by the last GC time.  The process can't already be
20239     * on the list.
20240     */
20241    final void addProcessToGcListLocked(ProcessRecord proc) {
20242        boolean added = false;
20243        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20244            if (mProcessesToGc.get(i).lastRequestedGc <
20245                    proc.lastRequestedGc) {
20246                added = true;
20247                mProcessesToGc.add(i+1, proc);
20248                break;
20249            }
20250        }
20251        if (!added) {
20252            mProcessesToGc.add(0, proc);
20253        }
20254    }
20255
20256    /**
20257     * Set up to ask a process to GC itself.  This will either do it
20258     * immediately, or put it on the list of processes to gc the next
20259     * time things are idle.
20260     */
20261    final void scheduleAppGcLocked(ProcessRecord app) {
20262        long now = SystemClock.uptimeMillis();
20263        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20264            return;
20265        }
20266        if (!mProcessesToGc.contains(app)) {
20267            addProcessToGcListLocked(app);
20268            scheduleAppGcsLocked();
20269        }
20270    }
20271
20272    final void checkExcessivePowerUsageLocked(boolean doKills) {
20273        updateCpuStatsNow();
20274
20275        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20276        boolean doWakeKills = doKills;
20277        boolean doCpuKills = doKills;
20278        if (mLastPowerCheckRealtime == 0) {
20279            doWakeKills = false;
20280        }
20281        if (mLastPowerCheckUptime == 0) {
20282            doCpuKills = false;
20283        }
20284        if (stats.isScreenOn()) {
20285            doWakeKills = false;
20286        }
20287        final long curRealtime = SystemClock.elapsedRealtime();
20288        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20289        final long curUptime = SystemClock.uptimeMillis();
20290        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20291        mLastPowerCheckRealtime = curRealtime;
20292        mLastPowerCheckUptime = curUptime;
20293        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20294            doWakeKills = false;
20295        }
20296        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20297            doCpuKills = false;
20298        }
20299        int i = mLruProcesses.size();
20300        while (i > 0) {
20301            i--;
20302            ProcessRecord app = mLruProcesses.get(i);
20303            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20304                long wtime;
20305                synchronized (stats) {
20306                    wtime = stats.getProcessWakeTime(app.info.uid,
20307                            app.pid, curRealtime);
20308                }
20309                long wtimeUsed = wtime - app.lastWakeTime;
20310                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20311                if (DEBUG_POWER) {
20312                    StringBuilder sb = new StringBuilder(128);
20313                    sb.append("Wake for ");
20314                    app.toShortString(sb);
20315                    sb.append(": over ");
20316                    TimeUtils.formatDuration(realtimeSince, sb);
20317                    sb.append(" used ");
20318                    TimeUtils.formatDuration(wtimeUsed, sb);
20319                    sb.append(" (");
20320                    sb.append((wtimeUsed*100)/realtimeSince);
20321                    sb.append("%)");
20322                    Slog.i(TAG_POWER, sb.toString());
20323                    sb.setLength(0);
20324                    sb.append("CPU for ");
20325                    app.toShortString(sb);
20326                    sb.append(": over ");
20327                    TimeUtils.formatDuration(uptimeSince, sb);
20328                    sb.append(" used ");
20329                    TimeUtils.formatDuration(cputimeUsed, sb);
20330                    sb.append(" (");
20331                    sb.append((cputimeUsed*100)/uptimeSince);
20332                    sb.append("%)");
20333                    Slog.i(TAG_POWER, sb.toString());
20334                }
20335                // If a process has held a wake lock for more
20336                // than 50% of the time during this period,
20337                // that sounds bad.  Kill!
20338                if (doWakeKills && realtimeSince > 0
20339                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20340                    synchronized (stats) {
20341                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20342                                realtimeSince, wtimeUsed);
20343                    }
20344                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20345                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20346                } else if (doCpuKills && uptimeSince > 0
20347                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20348                    synchronized (stats) {
20349                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20350                                uptimeSince, cputimeUsed);
20351                    }
20352                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20353                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20354                } else {
20355                    app.lastWakeTime = wtime;
20356                    app.lastCpuTime = app.curCpuTime;
20357                }
20358            }
20359        }
20360    }
20361
20362    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20363            long nowElapsed) {
20364        boolean success = true;
20365
20366        if (app.curRawAdj != app.setRawAdj) {
20367            app.setRawAdj = app.curRawAdj;
20368        }
20369
20370        int changes = 0;
20371
20372        if (app.curAdj != app.setAdj) {
20373            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20374            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20375                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20376                    + app.adjType);
20377            app.setAdj = app.curAdj;
20378            app.verifiedAdj = ProcessList.INVALID_ADJ;
20379        }
20380
20381        if (app.setSchedGroup != app.curSchedGroup) {
20382            int oldSchedGroup = app.setSchedGroup;
20383            app.setSchedGroup = app.curSchedGroup;
20384            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20385                    "Setting sched group of " + app.processName
20386                    + " to " + app.curSchedGroup);
20387            if (app.waitingToKill != null && app.curReceivers.isEmpty()
20388                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20389                app.kill(app.waitingToKill, true);
20390                success = false;
20391            } else {
20392                int processGroup;
20393                switch (app.curSchedGroup) {
20394                    case ProcessList.SCHED_GROUP_BACKGROUND:
20395                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20396                        break;
20397                    case ProcessList.SCHED_GROUP_TOP_APP:
20398                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20399                        processGroup = Process.THREAD_GROUP_TOP_APP;
20400                        break;
20401                    default:
20402                        processGroup = Process.THREAD_GROUP_DEFAULT;
20403                        break;
20404                }
20405                long oldId = Binder.clearCallingIdentity();
20406                try {
20407                    Process.setProcessGroup(app.pid, processGroup);
20408                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20409                        // do nothing if we already switched to RT
20410                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20411                            // Switch VR thread for app to SCHED_FIFO
20412                            if (mInVrMode && app.vrThreadTid != 0) {
20413                                try {
20414                                    Process.setThreadScheduler(app.vrThreadTid,
20415                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20416                                } catch (IllegalArgumentException e) {
20417                                    // thread died, ignore
20418                                }
20419                            }
20420                            if (mUseFifoUiScheduling) {
20421                                // Switch UI pipeline for app to SCHED_FIFO
20422                                app.savedPriority = Process.getThreadPriority(app.pid);
20423                                try {
20424                                    Process.setThreadScheduler(app.pid,
20425                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20426                                } catch (IllegalArgumentException e) {
20427                                    // thread died, ignore
20428                                }
20429                                if (app.renderThreadTid != 0) {
20430                                    try {
20431                                        Process.setThreadScheduler(app.renderThreadTid,
20432                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20433                                    } catch (IllegalArgumentException e) {
20434                                        // thread died, ignore
20435                                    }
20436                                    if (DEBUG_OOM_ADJ) {
20437                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20438                                            app.renderThreadTid + ") to FIFO");
20439                                    }
20440                                } else {
20441                                    if (DEBUG_OOM_ADJ) {
20442                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20443                                    }
20444                                }
20445                            } else {
20446                                // Boost priority for top app UI and render threads
20447                                Process.setThreadPriority(app.pid, -10);
20448                                if (app.renderThreadTid != 0) {
20449                                    try {
20450                                        Process.setThreadPriority(app.renderThreadTid, -10);
20451                                    } catch (IllegalArgumentException e) {
20452                                        // thread died, ignore
20453                                    }
20454                                }
20455                            }
20456                        }
20457                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20458                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20459                        // Reset VR thread to SCHED_OTHER
20460                        // Safe to do even if we're not in VR mode
20461                        if (app.vrThreadTid != 0) {
20462                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20463                        }
20464                        if (mUseFifoUiScheduling) {
20465                            // Reset UI pipeline to SCHED_OTHER
20466                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20467                            Process.setThreadPriority(app.pid, app.savedPriority);
20468                            if (app.renderThreadTid != 0) {
20469                                Process.setThreadScheduler(app.renderThreadTid,
20470                                    Process.SCHED_OTHER, 0);
20471                                Process.setThreadPriority(app.renderThreadTid, -4);
20472                            }
20473                        } else {
20474                            // Reset priority for top app UI and render threads
20475                            Process.setThreadPriority(app.pid, 0);
20476                            if (app.renderThreadTid != 0) {
20477                                Process.setThreadPriority(app.renderThreadTid, 0);
20478                            }
20479                        }
20480                    }
20481                } catch (Exception e) {
20482                    Slog.w(TAG, "Failed setting process group of " + app.pid
20483                            + " to " + app.curSchedGroup);
20484                    e.printStackTrace();
20485                } finally {
20486                    Binder.restoreCallingIdentity(oldId);
20487                }
20488            }
20489        }
20490        if (app.repForegroundActivities != app.foregroundActivities) {
20491            app.repForegroundActivities = app.foregroundActivities;
20492            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20493        }
20494        if (app.repProcState != app.curProcState) {
20495            app.repProcState = app.curProcState;
20496            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20497            if (app.thread != null) {
20498                try {
20499                    if (false) {
20500                        //RuntimeException h = new RuntimeException("here");
20501                        Slog.i(TAG, "Sending new process state " + app.repProcState
20502                                + " to " + app /*, h*/);
20503                    }
20504                    app.thread.setProcessState(app.repProcState);
20505                } catch (RemoteException e) {
20506                }
20507            }
20508        }
20509        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20510                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20511            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20512                // Experimental code to more aggressively collect pss while
20513                // running test...  the problem is that this tends to collect
20514                // the data right when a process is transitioning between process
20515                // states, which well tend to give noisy data.
20516                long start = SystemClock.uptimeMillis();
20517                long pss = Debug.getPss(app.pid, mTmpLong, null);
20518                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20519                mPendingPssProcesses.remove(app);
20520                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20521                        + " to " + app.curProcState + ": "
20522                        + (SystemClock.uptimeMillis()-start) + "ms");
20523            }
20524            app.lastStateTime = now;
20525            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20526                    mTestPssMode, isSleepingLocked(), now);
20527            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20528                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20529                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20530                    + (app.nextPssTime-now) + ": " + app);
20531        } else {
20532            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20533                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20534                    mTestPssMode)))) {
20535                requestPssLocked(app, app.setProcState);
20536                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20537                        mTestPssMode, isSleepingLocked(), now);
20538            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20539                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20540        }
20541        if (app.setProcState != app.curProcState) {
20542            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20543                    "Proc state change of " + app.processName
20544                            + " to " + app.curProcState);
20545            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20546            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20547            if (setImportant && !curImportant) {
20548                // This app is no longer something we consider important enough to allow to
20549                // use arbitrary amounts of battery power.  Note
20550                // its current wake lock time to later know to kill it if
20551                // it is not behaving well.
20552                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20553                synchronized (stats) {
20554                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20555                            app.pid, nowElapsed);
20556                }
20557                app.lastCpuTime = app.curCpuTime;
20558
20559            }
20560            // Inform UsageStats of important process state change
20561            // Must be called before updating setProcState
20562            maybeUpdateUsageStatsLocked(app, nowElapsed);
20563
20564            app.setProcState = app.curProcState;
20565            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20566                app.notCachedSinceIdle = false;
20567            }
20568            if (!doingAll) {
20569                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20570            } else {
20571                app.procStateChanged = true;
20572            }
20573        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20574                > USAGE_STATS_INTERACTION_INTERVAL) {
20575            // For apps that sit around for a long time in the interactive state, we need
20576            // to report this at least once a day so they don't go idle.
20577            maybeUpdateUsageStatsLocked(app, nowElapsed);
20578        }
20579
20580        if (changes != 0) {
20581            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20582                    "Changes in " + app + ": " + changes);
20583            int i = mPendingProcessChanges.size()-1;
20584            ProcessChangeItem item = null;
20585            while (i >= 0) {
20586                item = mPendingProcessChanges.get(i);
20587                if (item.pid == app.pid) {
20588                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20589                            "Re-using existing item: " + item);
20590                    break;
20591                }
20592                i--;
20593            }
20594            if (i < 0) {
20595                // No existing item in pending changes; need a new one.
20596                final int NA = mAvailProcessChanges.size();
20597                if (NA > 0) {
20598                    item = mAvailProcessChanges.remove(NA-1);
20599                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20600                            "Retrieving available item: " + item);
20601                } else {
20602                    item = new ProcessChangeItem();
20603                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20604                            "Allocating new item: " + item);
20605                }
20606                item.changes = 0;
20607                item.pid = app.pid;
20608                item.uid = app.info.uid;
20609                if (mPendingProcessChanges.size() == 0) {
20610                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20611                            "*** Enqueueing dispatch processes changed!");
20612                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20613                }
20614                mPendingProcessChanges.add(item);
20615            }
20616            item.changes |= changes;
20617            item.processState = app.repProcState;
20618            item.foregroundActivities = app.repForegroundActivities;
20619            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20620                    "Item " + Integer.toHexString(System.identityHashCode(item))
20621                    + " " + app.toShortString() + ": changes=" + item.changes
20622                    + " procState=" + item.processState
20623                    + " foreground=" + item.foregroundActivities
20624                    + " type=" + app.adjType + " source=" + app.adjSource
20625                    + " target=" + app.adjTarget);
20626        }
20627
20628        return success;
20629    }
20630
20631    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20632        final UidRecord.ChangeItem pendingChange;
20633        if (uidRec == null || uidRec.pendingChange == null) {
20634            if (mPendingUidChanges.size() == 0) {
20635                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20636                        "*** Enqueueing dispatch uid changed!");
20637                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20638            }
20639            final int NA = mAvailUidChanges.size();
20640            if (NA > 0) {
20641                pendingChange = mAvailUidChanges.remove(NA-1);
20642                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20643                        "Retrieving available item: " + pendingChange);
20644            } else {
20645                pendingChange = new UidRecord.ChangeItem();
20646                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20647                        "Allocating new item: " + pendingChange);
20648            }
20649            if (uidRec != null) {
20650                uidRec.pendingChange = pendingChange;
20651                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20652                    // If this uid is going away, and we haven't yet reported it is gone,
20653                    // then do so now.
20654                    change = UidRecord.CHANGE_GONE_IDLE;
20655                }
20656            } else if (uid < 0) {
20657                throw new IllegalArgumentException("No UidRecord or uid");
20658            }
20659            pendingChange.uidRecord = uidRec;
20660            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20661            mPendingUidChanges.add(pendingChange);
20662        } else {
20663            pendingChange = uidRec.pendingChange;
20664            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20665                change = UidRecord.CHANGE_GONE_IDLE;
20666            }
20667        }
20668        pendingChange.change = change;
20669        pendingChange.processState = uidRec != null
20670                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20671    }
20672
20673    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20674            String authority) {
20675        if (app == null) return;
20676        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20677            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20678            if (userState == null) return;
20679            final long now = SystemClock.elapsedRealtime();
20680            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20681            if (lastReported == null || lastReported < now - 60 * 1000L) {
20682                if (mSystemReady) {
20683                    // Cannot touch the user stats if not system ready
20684                    mUsageStatsService.reportContentProviderUsage(
20685                            authority, providerPkgName, app.userId);
20686                }
20687                userState.mProviderLastReportedFg.put(authority, now);
20688            }
20689        }
20690    }
20691
20692    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20693        if (DEBUG_USAGE_STATS) {
20694            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20695                    + "] state changes: old = " + app.setProcState + ", new = "
20696                    + app.curProcState);
20697        }
20698        if (mUsageStatsService == null) {
20699            return;
20700        }
20701        boolean isInteraction;
20702        // To avoid some abuse patterns, we are going to be careful about what we consider
20703        // to be an app interaction.  Being the top activity doesn't count while the display
20704        // is sleeping, nor do short foreground services.
20705        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20706            isInteraction = true;
20707            app.fgInteractionTime = 0;
20708        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20709            if (app.fgInteractionTime == 0) {
20710                app.fgInteractionTime = nowElapsed;
20711                isInteraction = false;
20712            } else {
20713                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20714            }
20715        } else {
20716            // If the app was being forced to the foreground, by say a Toast, then
20717            // no need to treat it as an interaction
20718            isInteraction = app.forcingToForeground == null
20719                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20720            app.fgInteractionTime = 0;
20721        }
20722        if (isInteraction && (!app.reportedInteraction
20723                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20724            app.interactionEventTime = nowElapsed;
20725            String[] packages = app.getPackageList();
20726            if (packages != null) {
20727                for (int i = 0; i < packages.length; i++) {
20728                    mUsageStatsService.reportEvent(packages[i], app.userId,
20729                            UsageEvents.Event.SYSTEM_INTERACTION);
20730                }
20731            }
20732        }
20733        app.reportedInteraction = isInteraction;
20734        if (!isInteraction) {
20735            app.interactionEventTime = 0;
20736        }
20737    }
20738
20739    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20740        if (proc.thread != null) {
20741            if (proc.baseProcessTracker != null) {
20742                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20743            }
20744        }
20745    }
20746
20747    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20748            ProcessRecord TOP_APP, boolean doingAll, long now) {
20749        if (app.thread == null) {
20750            return false;
20751        }
20752
20753        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20754
20755        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20756    }
20757
20758    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20759            boolean oomAdj) {
20760        if (isForeground != proc.foregroundServices) {
20761            proc.foregroundServices = isForeground;
20762            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20763                    proc.info.uid);
20764            if (isForeground) {
20765                if (curProcs == null) {
20766                    curProcs = new ArrayList<ProcessRecord>();
20767                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20768                }
20769                if (!curProcs.contains(proc)) {
20770                    curProcs.add(proc);
20771                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20772                            proc.info.packageName, proc.info.uid);
20773                }
20774            } else {
20775                if (curProcs != null) {
20776                    if (curProcs.remove(proc)) {
20777                        mBatteryStatsService.noteEvent(
20778                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20779                                proc.info.packageName, proc.info.uid);
20780                        if (curProcs.size() <= 0) {
20781                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20782                        }
20783                    }
20784                }
20785            }
20786            if (oomAdj) {
20787                updateOomAdjLocked();
20788            }
20789        }
20790    }
20791
20792    private final ActivityRecord resumedAppLocked() {
20793        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20794        String pkg;
20795        int uid;
20796        if (act != null) {
20797            pkg = act.packageName;
20798            uid = act.info.applicationInfo.uid;
20799        } else {
20800            pkg = null;
20801            uid = -1;
20802        }
20803        // Has the UID or resumed package name changed?
20804        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20805                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20806            if (mCurResumedPackage != null) {
20807                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20808                        mCurResumedPackage, mCurResumedUid);
20809            }
20810            mCurResumedPackage = pkg;
20811            mCurResumedUid = uid;
20812            if (mCurResumedPackage != null) {
20813                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20814                        mCurResumedPackage, mCurResumedUid);
20815            }
20816        }
20817        return act;
20818    }
20819
20820    final boolean updateOomAdjLocked(ProcessRecord app) {
20821        final ActivityRecord TOP_ACT = resumedAppLocked();
20822        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20823        final boolean wasCached = app.cached;
20824
20825        mAdjSeq++;
20826
20827        // This is the desired cached adjusment we want to tell it to use.
20828        // If our app is currently cached, we know it, and that is it.  Otherwise,
20829        // we don't know it yet, and it needs to now be cached we will then
20830        // need to do a complete oom adj.
20831        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20832                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20833        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20834                SystemClock.uptimeMillis());
20835        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20836            // Changed to/from cached state, so apps after it in the LRU
20837            // list may also be changed.
20838            updateOomAdjLocked();
20839        }
20840        return success;
20841    }
20842
20843    final void updateOomAdjLocked() {
20844        final ActivityRecord TOP_ACT = resumedAppLocked();
20845        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20846        final long now = SystemClock.uptimeMillis();
20847        final long nowElapsed = SystemClock.elapsedRealtime();
20848        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20849        final int N = mLruProcesses.size();
20850
20851        if (false) {
20852            RuntimeException e = new RuntimeException();
20853            e.fillInStackTrace();
20854            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20855        }
20856
20857        // Reset state in all uid records.
20858        for (int i=mActiveUids.size()-1; i>=0; i--) {
20859            final UidRecord uidRec = mActiveUids.valueAt(i);
20860            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20861                    "Starting update of " + uidRec);
20862            uidRec.reset();
20863        }
20864
20865        mStackSupervisor.rankTaskLayersIfNeeded();
20866
20867        mAdjSeq++;
20868        mNewNumServiceProcs = 0;
20869        mNewNumAServiceProcs = 0;
20870
20871        final int emptyProcessLimit;
20872        final int cachedProcessLimit;
20873        if (mProcessLimit <= 0) {
20874            emptyProcessLimit = cachedProcessLimit = 0;
20875        } else if (mProcessLimit == 1) {
20876            emptyProcessLimit = 1;
20877            cachedProcessLimit = 0;
20878        } else {
20879            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20880            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20881        }
20882
20883        // Let's determine how many processes we have running vs.
20884        // how many slots we have for background processes; we may want
20885        // to put multiple processes in a slot of there are enough of
20886        // them.
20887        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20888                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20889        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20890        if (numEmptyProcs > cachedProcessLimit) {
20891            // If there are more empty processes than our limit on cached
20892            // processes, then use the cached process limit for the factor.
20893            // This ensures that the really old empty processes get pushed
20894            // down to the bottom, so if we are running low on memory we will
20895            // have a better chance at keeping around more cached processes
20896            // instead of a gazillion empty processes.
20897            numEmptyProcs = cachedProcessLimit;
20898        }
20899        int emptyFactor = numEmptyProcs/numSlots;
20900        if (emptyFactor < 1) emptyFactor = 1;
20901        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20902        if (cachedFactor < 1) cachedFactor = 1;
20903        int stepCached = 0;
20904        int stepEmpty = 0;
20905        int numCached = 0;
20906        int numEmpty = 0;
20907        int numTrimming = 0;
20908
20909        mNumNonCachedProcs = 0;
20910        mNumCachedHiddenProcs = 0;
20911
20912        // First update the OOM adjustment for each of the
20913        // application processes based on their current state.
20914        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20915        int nextCachedAdj = curCachedAdj+1;
20916        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20917        int nextEmptyAdj = curEmptyAdj+2;
20918        for (int i=N-1; i>=0; i--) {
20919            ProcessRecord app = mLruProcesses.get(i);
20920            if (!app.killedByAm && app.thread != null) {
20921                app.procStateChanged = false;
20922                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20923
20924                // If we haven't yet assigned the final cached adj
20925                // to the process, do that now.
20926                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20927                    switch (app.curProcState) {
20928                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20929                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20930                            // This process is a cached process holding activities...
20931                            // assign it the next cached value for that type, and then
20932                            // step that cached level.
20933                            app.curRawAdj = curCachedAdj;
20934                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20935                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20936                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20937                                    + ")");
20938                            if (curCachedAdj != nextCachedAdj) {
20939                                stepCached++;
20940                                if (stepCached >= cachedFactor) {
20941                                    stepCached = 0;
20942                                    curCachedAdj = nextCachedAdj;
20943                                    nextCachedAdj += 2;
20944                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20945                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20946                                    }
20947                                }
20948                            }
20949                            break;
20950                        default:
20951                            // For everything else, assign next empty cached process
20952                            // level and bump that up.  Note that this means that
20953                            // long-running services that have dropped down to the
20954                            // cached level will be treated as empty (since their process
20955                            // state is still as a service), which is what we want.
20956                            app.curRawAdj = curEmptyAdj;
20957                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20958                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20959                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20960                                    + ")");
20961                            if (curEmptyAdj != nextEmptyAdj) {
20962                                stepEmpty++;
20963                                if (stepEmpty >= emptyFactor) {
20964                                    stepEmpty = 0;
20965                                    curEmptyAdj = nextEmptyAdj;
20966                                    nextEmptyAdj += 2;
20967                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20968                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20969                                    }
20970                                }
20971                            }
20972                            break;
20973                    }
20974                }
20975
20976                applyOomAdjLocked(app, true, now, nowElapsed);
20977
20978                // Count the number of process types.
20979                switch (app.curProcState) {
20980                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20981                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20982                        mNumCachedHiddenProcs++;
20983                        numCached++;
20984                        if (numCached > cachedProcessLimit) {
20985                            app.kill("cached #" + numCached, true);
20986                        }
20987                        break;
20988                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20989                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20990                                && app.lastActivityTime < oldTime) {
20991                            app.kill("empty for "
20992                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20993                                    / 1000) + "s", true);
20994                        } else {
20995                            numEmpty++;
20996                            if (numEmpty > emptyProcessLimit) {
20997                                app.kill("empty #" + numEmpty, true);
20998                            }
20999                        }
21000                        break;
21001                    default:
21002                        mNumNonCachedProcs++;
21003                        break;
21004                }
21005
21006                if (app.isolated && app.services.size() <= 0) {
21007                    // If this is an isolated process, and there are no
21008                    // services running in it, then the process is no longer
21009                    // needed.  We agressively kill these because we can by
21010                    // definition not re-use the same process again, and it is
21011                    // good to avoid having whatever code was running in them
21012                    // left sitting around after no longer needed.
21013                    app.kill("isolated not needed", true);
21014                } else {
21015                    // Keeping this process, update its uid.
21016                    final UidRecord uidRec = app.uidRecord;
21017                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
21018                        uidRec.curProcState = app.curProcState;
21019                    }
21020                }
21021
21022                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21023                        && !app.killedByAm) {
21024                    numTrimming++;
21025                }
21026            }
21027        }
21028
21029        mNumServiceProcs = mNewNumServiceProcs;
21030
21031        // Now determine the memory trimming level of background processes.
21032        // Unfortunately we need to start at the back of the list to do this
21033        // properly.  We only do this if the number of background apps we
21034        // are managing to keep around is less than half the maximum we desire;
21035        // if we are keeping a good number around, we'll let them use whatever
21036        // memory they want.
21037        final int numCachedAndEmpty = numCached + numEmpty;
21038        int memFactor;
21039        if (numCached <= ProcessList.TRIM_CACHED_APPS
21040                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21041            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21042                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21043            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21044                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21045            } else {
21046                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21047            }
21048        } else {
21049            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21050        }
21051        // We always allow the memory level to go up (better).  We only allow it to go
21052        // down if we are in a state where that is allowed, *and* the total number of processes
21053        // has gone down since last time.
21054        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21055                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21056                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21057        if (memFactor > mLastMemoryLevel) {
21058            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21059                memFactor = mLastMemoryLevel;
21060                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21061            }
21062        }
21063        if (memFactor != mLastMemoryLevel) {
21064            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21065        }
21066        mLastMemoryLevel = memFactor;
21067        mLastNumProcesses = mLruProcesses.size();
21068        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21069        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21070        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21071            if (mLowRamStartTime == 0) {
21072                mLowRamStartTime = now;
21073            }
21074            int step = 0;
21075            int fgTrimLevel;
21076            switch (memFactor) {
21077                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21078                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21079                    break;
21080                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21081                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21082                    break;
21083                default:
21084                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21085                    break;
21086            }
21087            int factor = numTrimming/3;
21088            int minFactor = 2;
21089            if (mHomeProcess != null) minFactor++;
21090            if (mPreviousProcess != null) minFactor++;
21091            if (factor < minFactor) factor = minFactor;
21092            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21093            for (int i=N-1; i>=0; i--) {
21094                ProcessRecord app = mLruProcesses.get(i);
21095                if (allChanged || app.procStateChanged) {
21096                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21097                    app.procStateChanged = false;
21098                }
21099                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21100                        && !app.killedByAm) {
21101                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21102                        try {
21103                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21104                                    "Trimming memory of " + app.processName + " to " + curLevel);
21105                            app.thread.scheduleTrimMemory(curLevel);
21106                        } catch (RemoteException e) {
21107                        }
21108                        if (false) {
21109                            // For now we won't do this; our memory trimming seems
21110                            // to be good enough at this point that destroying
21111                            // activities causes more harm than good.
21112                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21113                                    && app != mHomeProcess && app != mPreviousProcess) {
21114                                // Need to do this on its own message because the stack may not
21115                                // be in a consistent state at this point.
21116                                // For these apps we will also finish their activities
21117                                // to help them free memory.
21118                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21119                            }
21120                        }
21121                    }
21122                    app.trimMemoryLevel = curLevel;
21123                    step++;
21124                    if (step >= factor) {
21125                        step = 0;
21126                        switch (curLevel) {
21127                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21128                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21129                                break;
21130                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21131                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21132                                break;
21133                        }
21134                    }
21135                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21136                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21137                            && app.thread != null) {
21138                        try {
21139                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21140                                    "Trimming memory of heavy-weight " + app.processName
21141                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21142                            app.thread.scheduleTrimMemory(
21143                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21144                        } catch (RemoteException e) {
21145                        }
21146                    }
21147                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21148                } else {
21149                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21150                            || app.systemNoUi) && app.pendingUiClean) {
21151                        // If this application is now in the background and it
21152                        // had done UI, then give it the special trim level to
21153                        // have it free UI resources.
21154                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21155                        if (app.trimMemoryLevel < level && app.thread != null) {
21156                            try {
21157                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21158                                        "Trimming memory of bg-ui " + app.processName
21159                                        + " to " + level);
21160                                app.thread.scheduleTrimMemory(level);
21161                            } catch (RemoteException e) {
21162                            }
21163                        }
21164                        app.pendingUiClean = false;
21165                    }
21166                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21167                        try {
21168                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21169                                    "Trimming memory of fg " + app.processName
21170                                    + " to " + fgTrimLevel);
21171                            app.thread.scheduleTrimMemory(fgTrimLevel);
21172                        } catch (RemoteException e) {
21173                        }
21174                    }
21175                    app.trimMemoryLevel = fgTrimLevel;
21176                }
21177            }
21178        } else {
21179            if (mLowRamStartTime != 0) {
21180                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21181                mLowRamStartTime = 0;
21182            }
21183            for (int i=N-1; i>=0; i--) {
21184                ProcessRecord app = mLruProcesses.get(i);
21185                if (allChanged || app.procStateChanged) {
21186                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21187                    app.procStateChanged = false;
21188                }
21189                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21190                        || app.systemNoUi) && app.pendingUiClean) {
21191                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21192                            && app.thread != null) {
21193                        try {
21194                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21195                                    "Trimming memory of ui hidden " + app.processName
21196                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21197                            app.thread.scheduleTrimMemory(
21198                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21199                        } catch (RemoteException e) {
21200                        }
21201                    }
21202                    app.pendingUiClean = false;
21203                }
21204                app.trimMemoryLevel = 0;
21205            }
21206        }
21207
21208        if (mAlwaysFinishActivities) {
21209            // Need to do this on its own message because the stack may not
21210            // be in a consistent state at this point.
21211            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21212        }
21213
21214        if (allChanged) {
21215            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21216        }
21217
21218        // Update from any uid changes.
21219        for (int i=mActiveUids.size()-1; i>=0; i--) {
21220            final UidRecord uidRec = mActiveUids.valueAt(i);
21221            int uidChange = UidRecord.CHANGE_PROCSTATE;
21222            if (uidRec.setProcState != uidRec.curProcState) {
21223                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21224                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21225                        + " to " + uidRec.curProcState);
21226                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21227                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21228                        uidRec.lastBackgroundTime = nowElapsed;
21229                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21230                            // Note: the background settle time is in elapsed realtime, while
21231                            // the handler time base is uptime.  All this means is that we may
21232                            // stop background uids later than we had intended, but that only
21233                            // happens because the device was sleeping so we are okay anyway.
21234                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21235                        }
21236                    }
21237                } else {
21238                    if (uidRec.idle) {
21239                        uidChange = UidRecord.CHANGE_ACTIVE;
21240                        uidRec.idle = false;
21241                    }
21242                    uidRec.lastBackgroundTime = 0;
21243                }
21244                uidRec.setProcState = uidRec.curProcState;
21245                enqueueUidChangeLocked(uidRec, -1, uidChange);
21246                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21247            }
21248        }
21249
21250        if (mProcessStats.shouldWriteNowLocked(now)) {
21251            mHandler.post(new Runnable() {
21252                @Override public void run() {
21253                    synchronized (ActivityManagerService.this) {
21254                        mProcessStats.writeStateAsyncLocked();
21255                    }
21256                }
21257            });
21258        }
21259
21260        if (DEBUG_OOM_ADJ) {
21261            final long duration = SystemClock.uptimeMillis() - now;
21262            if (false) {
21263                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21264                        new RuntimeException("here").fillInStackTrace());
21265            } else {
21266                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21267            }
21268        }
21269    }
21270
21271    final void idleUids() {
21272        synchronized (this) {
21273            final long nowElapsed = SystemClock.elapsedRealtime();
21274            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21275            long nextTime = 0;
21276            for (int i=mActiveUids.size()-1; i>=0; i--) {
21277                final UidRecord uidRec = mActiveUids.valueAt(i);
21278                final long bgTime = uidRec.lastBackgroundTime;
21279                if (bgTime > 0 && !uidRec.idle) {
21280                    if (bgTime <= maxBgTime) {
21281                        uidRec.idle = true;
21282                        doStopUidLocked(uidRec.uid, uidRec);
21283                    } else {
21284                        if (nextTime == 0 || nextTime > bgTime) {
21285                            nextTime = bgTime;
21286                        }
21287                    }
21288                }
21289            }
21290            if (nextTime > 0) {
21291                mHandler.removeMessages(IDLE_UIDS_MSG);
21292                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21293                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21294            }
21295        }
21296    }
21297
21298    final void runInBackgroundDisabled(int uid) {
21299        synchronized (this) {
21300            UidRecord uidRec = mActiveUids.get(uid);
21301            if (uidRec != null) {
21302                // This uid is actually running...  should it be considered background now?
21303                if (uidRec.idle) {
21304                    doStopUidLocked(uidRec.uid, uidRec);
21305                }
21306            } else {
21307                // This uid isn't actually running...  still send a report about it being "stopped".
21308                doStopUidLocked(uid, null);
21309            }
21310        }
21311    }
21312
21313    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21314        mServices.stopInBackgroundLocked(uid);
21315        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21316    }
21317
21318    final void trimApplications() {
21319        synchronized (this) {
21320            int i;
21321
21322            // First remove any unused application processes whose package
21323            // has been removed.
21324            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21325                final ProcessRecord app = mRemovedProcesses.get(i);
21326                if (app.activities.size() == 0
21327                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
21328                    Slog.i(
21329                        TAG, "Exiting empty application process "
21330                        + app.toShortString() + " ("
21331                        + (app.thread != null ? app.thread.asBinder() : null)
21332                        + ")\n");
21333                    if (app.pid > 0 && app.pid != MY_PID) {
21334                        app.kill("empty", false);
21335                    } else {
21336                        try {
21337                            app.thread.scheduleExit();
21338                        } catch (Exception e) {
21339                            // Ignore exceptions.
21340                        }
21341                    }
21342                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21343                    mRemovedProcesses.remove(i);
21344
21345                    if (app.persistent) {
21346                        addAppLocked(app.info, false, null /* ABI override */);
21347                    }
21348                }
21349            }
21350
21351            // Now update the oom adj for all processes.
21352            updateOomAdjLocked();
21353        }
21354    }
21355
21356    /** This method sends the specified signal to each of the persistent apps */
21357    public void signalPersistentProcesses(int sig) throws RemoteException {
21358        if (sig != Process.SIGNAL_USR1) {
21359            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21360        }
21361
21362        synchronized (this) {
21363            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21364                    != PackageManager.PERMISSION_GRANTED) {
21365                throw new SecurityException("Requires permission "
21366                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21367            }
21368
21369            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21370                ProcessRecord r = mLruProcesses.get(i);
21371                if (r.thread != null && r.persistent) {
21372                    Process.sendSignal(r.pid, sig);
21373                }
21374            }
21375        }
21376    }
21377
21378    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21379        if (proc == null || proc == mProfileProc) {
21380            proc = mProfileProc;
21381            profileType = mProfileType;
21382            clearProfilerLocked();
21383        }
21384        if (proc == null) {
21385            return;
21386        }
21387        try {
21388            proc.thread.profilerControl(false, null, profileType);
21389        } catch (RemoteException e) {
21390            throw new IllegalStateException("Process disappeared");
21391        }
21392    }
21393
21394    private void clearProfilerLocked() {
21395        if (mProfileFd != null) {
21396            try {
21397                mProfileFd.close();
21398            } catch (IOException e) {
21399            }
21400        }
21401        mProfileApp = null;
21402        mProfileProc = null;
21403        mProfileFile = null;
21404        mProfileType = 0;
21405        mAutoStopProfiler = false;
21406        mSamplingInterval = 0;
21407    }
21408
21409    public boolean profileControl(String process, int userId, boolean start,
21410            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21411
21412        try {
21413            synchronized (this) {
21414                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21415                // its own permission.
21416                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21417                        != PackageManager.PERMISSION_GRANTED) {
21418                    throw new SecurityException("Requires permission "
21419                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21420                }
21421
21422                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21423                    throw new IllegalArgumentException("null profile info or fd");
21424                }
21425
21426                ProcessRecord proc = null;
21427                if (process != null) {
21428                    proc = findProcessLocked(process, userId, "profileControl");
21429                }
21430
21431                if (start && (proc == null || proc.thread == null)) {
21432                    throw new IllegalArgumentException("Unknown process: " + process);
21433                }
21434
21435                if (start) {
21436                    stopProfilerLocked(null, 0);
21437                    setProfileApp(proc.info, proc.processName, profilerInfo);
21438                    mProfileProc = proc;
21439                    mProfileType = profileType;
21440                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21441                    try {
21442                        fd = fd.dup();
21443                    } catch (IOException e) {
21444                        fd = null;
21445                    }
21446                    profilerInfo.profileFd = fd;
21447                    proc.thread.profilerControl(start, profilerInfo, profileType);
21448                    fd = null;
21449                    mProfileFd = null;
21450                } else {
21451                    stopProfilerLocked(proc, profileType);
21452                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21453                        try {
21454                            profilerInfo.profileFd.close();
21455                        } catch (IOException e) {
21456                        }
21457                    }
21458                }
21459
21460                return true;
21461            }
21462        } catch (RemoteException e) {
21463            throw new IllegalStateException("Process disappeared");
21464        } finally {
21465            if (profilerInfo != null && profilerInfo.profileFd != null) {
21466                try {
21467                    profilerInfo.profileFd.close();
21468                } catch (IOException e) {
21469                }
21470            }
21471        }
21472    }
21473
21474    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21475        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21476                userId, true, ALLOW_FULL_ONLY, callName, null);
21477        ProcessRecord proc = null;
21478        try {
21479            int pid = Integer.parseInt(process);
21480            synchronized (mPidsSelfLocked) {
21481                proc = mPidsSelfLocked.get(pid);
21482            }
21483        } catch (NumberFormatException e) {
21484        }
21485
21486        if (proc == null) {
21487            ArrayMap<String, SparseArray<ProcessRecord>> all
21488                    = mProcessNames.getMap();
21489            SparseArray<ProcessRecord> procs = all.get(process);
21490            if (procs != null && procs.size() > 0) {
21491                proc = procs.valueAt(0);
21492                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21493                    for (int i=1; i<procs.size(); i++) {
21494                        ProcessRecord thisProc = procs.valueAt(i);
21495                        if (thisProc.userId == userId) {
21496                            proc = thisProc;
21497                            break;
21498                        }
21499                    }
21500                }
21501            }
21502        }
21503
21504        return proc;
21505    }
21506
21507    public boolean dumpHeap(String process, int userId, boolean managed,
21508            String path, ParcelFileDescriptor fd) throws RemoteException {
21509
21510        try {
21511            synchronized (this) {
21512                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21513                // its own permission (same as profileControl).
21514                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21515                        != PackageManager.PERMISSION_GRANTED) {
21516                    throw new SecurityException("Requires permission "
21517                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21518                }
21519
21520                if (fd == null) {
21521                    throw new IllegalArgumentException("null fd");
21522                }
21523
21524                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21525                if (proc == null || proc.thread == null) {
21526                    throw new IllegalArgumentException("Unknown process: " + process);
21527                }
21528
21529                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21530                if (!isDebuggable) {
21531                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21532                        throw new SecurityException("Process not debuggable: " + proc);
21533                    }
21534                }
21535
21536                proc.thread.dumpHeap(managed, path, fd);
21537                fd = null;
21538                return true;
21539            }
21540        } catch (RemoteException e) {
21541            throw new IllegalStateException("Process disappeared");
21542        } finally {
21543            if (fd != null) {
21544                try {
21545                    fd.close();
21546                } catch (IOException e) {
21547                }
21548            }
21549        }
21550    }
21551
21552    @Override
21553    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21554            String reportPackage) {
21555        if (processName != null) {
21556            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21557                    "setDumpHeapDebugLimit()");
21558        } else {
21559            synchronized (mPidsSelfLocked) {
21560                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21561                if (proc == null) {
21562                    throw new SecurityException("No process found for calling pid "
21563                            + Binder.getCallingPid());
21564                }
21565                if (!Build.IS_DEBUGGABLE
21566                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21567                    throw new SecurityException("Not running a debuggable build");
21568                }
21569                processName = proc.processName;
21570                uid = proc.uid;
21571                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21572                    throw new SecurityException("Package " + reportPackage + " is not running in "
21573                            + proc);
21574                }
21575            }
21576        }
21577        synchronized (this) {
21578            if (maxMemSize > 0) {
21579                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21580            } else {
21581                if (uid != 0) {
21582                    mMemWatchProcesses.remove(processName, uid);
21583                } else {
21584                    mMemWatchProcesses.getMap().remove(processName);
21585                }
21586            }
21587        }
21588    }
21589
21590    @Override
21591    public void dumpHeapFinished(String path) {
21592        synchronized (this) {
21593            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21594                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21595                        + " does not match last pid " + mMemWatchDumpPid);
21596                return;
21597            }
21598            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21599                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21600                        + " does not match last path " + mMemWatchDumpFile);
21601                return;
21602            }
21603            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21604            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21605        }
21606    }
21607
21608    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21609    public void monitor() {
21610        synchronized (this) { }
21611    }
21612
21613    void onCoreSettingsChange(Bundle settings) {
21614        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21615            ProcessRecord processRecord = mLruProcesses.get(i);
21616            try {
21617                if (processRecord.thread != null) {
21618                    processRecord.thread.setCoreSettings(settings);
21619                }
21620            } catch (RemoteException re) {
21621                /* ignore */
21622            }
21623        }
21624    }
21625
21626    // Multi-user methods
21627
21628    /**
21629     * Start user, if its not already running, but don't bring it to foreground.
21630     */
21631    @Override
21632    public boolean startUserInBackground(final int userId) {
21633        return mUserController.startUser(userId, /* foreground */ false);
21634    }
21635
21636    @Override
21637    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21638        return mUserController.unlockUser(userId, token, secret, listener);
21639    }
21640
21641    @Override
21642    public boolean switchUser(final int targetUserId) {
21643        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21644        UserInfo currentUserInfo;
21645        UserInfo targetUserInfo;
21646        synchronized (this) {
21647            int currentUserId = mUserController.getCurrentUserIdLocked();
21648            currentUserInfo = mUserController.getUserInfo(currentUserId);
21649            targetUserInfo = mUserController.getUserInfo(targetUserId);
21650            if (targetUserInfo == null) {
21651                Slog.w(TAG, "No user info for user #" + targetUserId);
21652                return false;
21653            }
21654            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21655                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21656                        + " when device is in demo mode");
21657                return false;
21658            }
21659            if (!targetUserInfo.supportsSwitchTo()) {
21660                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21661                return false;
21662            }
21663            if (targetUserInfo.isManagedProfile()) {
21664                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21665                return false;
21666            }
21667            mUserController.setTargetUserIdLocked(targetUserId);
21668        }
21669        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21670        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21671        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21672        return true;
21673    }
21674
21675    void scheduleStartProfilesLocked() {
21676        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21677            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21678                    DateUtils.SECOND_IN_MILLIS);
21679        }
21680    }
21681
21682    @Override
21683    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21684        return mUserController.stopUser(userId, force, callback);
21685    }
21686
21687    @Override
21688    public UserInfo getCurrentUser() {
21689        return mUserController.getCurrentUser();
21690    }
21691
21692    @Override
21693    public boolean isUserRunning(int userId, int flags) {
21694        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21695                && checkCallingPermission(INTERACT_ACROSS_USERS)
21696                    != PackageManager.PERMISSION_GRANTED) {
21697            String msg = "Permission Denial: isUserRunning() from pid="
21698                    + Binder.getCallingPid()
21699                    + ", uid=" + Binder.getCallingUid()
21700                    + " requires " + INTERACT_ACROSS_USERS;
21701            Slog.w(TAG, msg);
21702            throw new SecurityException(msg);
21703        }
21704        synchronized (this) {
21705            return mUserController.isUserRunningLocked(userId, flags);
21706        }
21707    }
21708
21709    @Override
21710    public int[] getRunningUserIds() {
21711        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21712                != PackageManager.PERMISSION_GRANTED) {
21713            String msg = "Permission Denial: isUserRunning() from pid="
21714                    + Binder.getCallingPid()
21715                    + ", uid=" + Binder.getCallingUid()
21716                    + " requires " + INTERACT_ACROSS_USERS;
21717            Slog.w(TAG, msg);
21718            throw new SecurityException(msg);
21719        }
21720        synchronized (this) {
21721            return mUserController.getStartedUserArrayLocked();
21722        }
21723    }
21724
21725    @Override
21726    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21727        mUserController.registerUserSwitchObserver(observer, name);
21728    }
21729
21730    @Override
21731    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21732        mUserController.unregisterUserSwitchObserver(observer);
21733    }
21734
21735    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21736        if (info == null) return null;
21737        ApplicationInfo newInfo = new ApplicationInfo(info);
21738        newInfo.initForUser(userId);
21739        return newInfo;
21740    }
21741
21742    public boolean isUserStopped(int userId) {
21743        synchronized (this) {
21744            return mUserController.getStartedUserStateLocked(userId) == null;
21745        }
21746    }
21747
21748    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21749        if (aInfo == null
21750                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21751            return aInfo;
21752        }
21753
21754        ActivityInfo info = new ActivityInfo(aInfo);
21755        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21756        return info;
21757    }
21758
21759    private boolean processSanityChecksLocked(ProcessRecord process) {
21760        if (process == null || process.thread == null) {
21761            return false;
21762        }
21763
21764        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21765        if (!isDebuggable) {
21766            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21767                return false;
21768            }
21769        }
21770
21771        return true;
21772    }
21773
21774    public boolean startBinderTracking() throws RemoteException {
21775        synchronized (this) {
21776            mBinderTransactionTrackingEnabled = true;
21777            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21778            // permission (same as profileControl).
21779            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21780                    != PackageManager.PERMISSION_GRANTED) {
21781                throw new SecurityException("Requires permission "
21782                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21783            }
21784
21785            for (int i = 0; i < mLruProcesses.size(); i++) {
21786                ProcessRecord process = mLruProcesses.get(i);
21787                if (!processSanityChecksLocked(process)) {
21788                    continue;
21789                }
21790                try {
21791                    process.thread.startBinderTracking();
21792                } catch (RemoteException e) {
21793                    Log.v(TAG, "Process disappared");
21794                }
21795            }
21796            return true;
21797        }
21798    }
21799
21800    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21801        try {
21802            synchronized (this) {
21803                mBinderTransactionTrackingEnabled = false;
21804                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21805                // permission (same as profileControl).
21806                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21807                        != PackageManager.PERMISSION_GRANTED) {
21808                    throw new SecurityException("Requires permission "
21809                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21810                }
21811
21812                if (fd == null) {
21813                    throw new IllegalArgumentException("null fd");
21814                }
21815
21816                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21817                pw.println("Binder transaction traces for all processes.\n");
21818                for (ProcessRecord process : mLruProcesses) {
21819                    if (!processSanityChecksLocked(process)) {
21820                        continue;
21821                    }
21822
21823                    pw.println("Traces for process: " + process.processName);
21824                    pw.flush();
21825                    try {
21826                        TransferPipe tp = new TransferPipe();
21827                        try {
21828                            process.thread.stopBinderTrackingAndDump(
21829                                    tp.getWriteFd().getFileDescriptor());
21830                            tp.go(fd.getFileDescriptor());
21831                        } finally {
21832                            tp.kill();
21833                        }
21834                    } catch (IOException e) {
21835                        pw.println("Failure while dumping IPC traces from " + process +
21836                                ".  Exception: " + e);
21837                        pw.flush();
21838                    } catch (RemoteException e) {
21839                        pw.println("Got a RemoteException while dumping IPC traces from " +
21840                                process + ".  Exception: " + e);
21841                        pw.flush();
21842                    }
21843                }
21844                fd = null;
21845                return true;
21846            }
21847        } finally {
21848            if (fd != null) {
21849                try {
21850                    fd.close();
21851                } catch (IOException e) {
21852                }
21853            }
21854        }
21855    }
21856
21857    private final class LocalService extends ActivityManagerInternal {
21858        @Override
21859        public void onWakefulnessChanged(int wakefulness) {
21860            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21861        }
21862
21863        @Override
21864        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21865                String processName, String abiOverride, int uid, Runnable crashHandler) {
21866            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21867                    processName, abiOverride, uid, crashHandler);
21868        }
21869
21870        @Override
21871        public SleepToken acquireSleepToken(String tag) {
21872            Preconditions.checkNotNull(tag);
21873
21874            ComponentName requestedVrService = null;
21875            ComponentName callingVrActivity = null;
21876            int userId = -1;
21877            synchronized (ActivityManagerService.this) {
21878                if (mFocusedActivity != null) {
21879                    requestedVrService = mFocusedActivity.requestedVrComponent;
21880                    callingVrActivity = mFocusedActivity.info.getComponentName();
21881                    userId = mFocusedActivity.userId;
21882                }
21883            }
21884
21885            if (requestedVrService != null) {
21886                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21887            }
21888
21889            synchronized (ActivityManagerService.this) {
21890                SleepTokenImpl token = new SleepTokenImpl(tag);
21891                mSleepTokens.add(token);
21892                updateSleepIfNeededLocked();
21893                return token;
21894            }
21895        }
21896
21897        @Override
21898        public ComponentName getHomeActivityForUser(int userId) {
21899            synchronized (ActivityManagerService.this) {
21900                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21901                return homeActivity == null ? null : homeActivity.realActivity;
21902            }
21903        }
21904
21905        @Override
21906        public void onUserRemoved(int userId) {
21907            synchronized (ActivityManagerService.this) {
21908                ActivityManagerService.this.onUserStoppedLocked(userId);
21909            }
21910        }
21911
21912        @Override
21913        public void onLocalVoiceInteractionStarted(IBinder activity,
21914                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21915            synchronized (ActivityManagerService.this) {
21916                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21917                        voiceSession, voiceInteractor);
21918            }
21919        }
21920
21921        @Override
21922        public void notifyStartingWindowDrawn() {
21923            synchronized (ActivityManagerService.this) {
21924                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21925            }
21926        }
21927
21928        @Override
21929        public void notifyAppTransitionStarting(int reason) {
21930            synchronized (ActivityManagerService.this) {
21931                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21932            }
21933        }
21934
21935        @Override
21936        public void notifyAppTransitionFinished() {
21937            synchronized (ActivityManagerService.this) {
21938                mStackSupervisor.notifyAppTransitionDone();
21939            }
21940        }
21941
21942        @Override
21943        public void notifyAppTransitionCancelled() {
21944            synchronized (ActivityManagerService.this) {
21945                mStackSupervisor.notifyAppTransitionDone();
21946            }
21947        }
21948
21949        @Override
21950        public List<IBinder> getTopVisibleActivities() {
21951            synchronized (ActivityManagerService.this) {
21952                return mStackSupervisor.getTopVisibleActivities();
21953            }
21954        }
21955
21956        @Override
21957        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21958            synchronized (ActivityManagerService.this) {
21959                mStackSupervisor.setDockedStackMinimized(minimized);
21960            }
21961        }
21962
21963        @Override
21964        public void killForegroundAppsForUser(int userHandle) {
21965            synchronized (ActivityManagerService.this) {
21966                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21967                final int NP = mProcessNames.getMap().size();
21968                for (int ip = 0; ip < NP; ip++) {
21969                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21970                    final int NA = apps.size();
21971                    for (int ia = 0; ia < NA; ia++) {
21972                        final ProcessRecord app = apps.valueAt(ia);
21973                        if (app.persistent) {
21974                            // We don't kill persistent processes.
21975                            continue;
21976                        }
21977                        if (app.removed) {
21978                            procs.add(app);
21979                        } else if (app.userId == userHandle && app.foregroundActivities) {
21980                            app.removed = true;
21981                            procs.add(app);
21982                        }
21983                    }
21984                }
21985
21986                final int N = procs.size();
21987                for (int i = 0; i < N; i++) {
21988                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21989                }
21990            }
21991        }
21992
21993        @Override
21994        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21995            if (!(target instanceof PendingIntentRecord)) {
21996                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21997                return;
21998            }
21999            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22000        }
22001
22002        @Override
22003        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22004                int userId) {
22005            Preconditions.checkNotNull(values, "Configuration must not be null");
22006            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22007            synchronized (ActivityManagerService.this) {
22008                updateConfigurationLocked(values, null, false, true, userId,
22009                        false /* deferResume */);
22010            }
22011        }
22012
22013        @Override
22014        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22015                Bundle bOptions) {
22016            Preconditions.checkNotNull(intents, "intents");
22017            final String[] resolvedTypes = new String[intents.length];
22018            for (int i = 0; i < intents.length; i++) {
22019                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22020            }
22021
22022            // UID of the package on user userId.
22023            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22024            // packageUid may not be initialized.
22025            int packageUid = 0;
22026            try {
22027                packageUid = AppGlobals.getPackageManager().getPackageUid(
22028                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22029            } catch (RemoteException e) {
22030                // Shouldn't happen.
22031            }
22032
22033            synchronized (ActivityManagerService.this) {
22034                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22035                        /*resultTo*/ null, bOptions, userId);
22036            }
22037        }
22038
22039        @Override
22040        public int getUidProcessState(int uid) {
22041            return getUidState(uid);
22042        }
22043    }
22044
22045    private final class SleepTokenImpl extends SleepToken {
22046        private final String mTag;
22047        private final long mAcquireTime;
22048
22049        public SleepTokenImpl(String tag) {
22050            mTag = tag;
22051            mAcquireTime = SystemClock.uptimeMillis();
22052        }
22053
22054        @Override
22055        public void release() {
22056            synchronized (ActivityManagerService.this) {
22057                if (mSleepTokens.remove(this)) {
22058                    updateSleepIfNeededLocked();
22059                }
22060            }
22061        }
22062
22063        @Override
22064        public String toString() {
22065            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22066        }
22067    }
22068
22069    /**
22070     * An implementation of IAppTask, that allows an app to manage its own tasks via
22071     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22072     * only the process that calls getAppTasks() can call the AppTask methods.
22073     */
22074    class AppTaskImpl extends IAppTask.Stub {
22075        private int mTaskId;
22076        private int mCallingUid;
22077
22078        public AppTaskImpl(int taskId, int callingUid) {
22079            mTaskId = taskId;
22080            mCallingUid = callingUid;
22081        }
22082
22083        private void checkCaller() {
22084            if (mCallingUid != Binder.getCallingUid()) {
22085                throw new SecurityException("Caller " + mCallingUid
22086                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22087            }
22088        }
22089
22090        @Override
22091        public void finishAndRemoveTask() {
22092            checkCaller();
22093
22094            synchronized (ActivityManagerService.this) {
22095                long origId = Binder.clearCallingIdentity();
22096                try {
22097                    // We remove the task from recents to preserve backwards
22098                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22099                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22100                    }
22101                } finally {
22102                    Binder.restoreCallingIdentity(origId);
22103                }
22104            }
22105        }
22106
22107        @Override
22108        public ActivityManager.RecentTaskInfo getTaskInfo() {
22109            checkCaller();
22110
22111            synchronized (ActivityManagerService.this) {
22112                long origId = Binder.clearCallingIdentity();
22113                try {
22114                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22115                    if (tr == null) {
22116                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22117                    }
22118                    return createRecentTaskInfoFromTaskRecord(tr);
22119                } finally {
22120                    Binder.restoreCallingIdentity(origId);
22121                }
22122            }
22123        }
22124
22125        @Override
22126        public void moveToFront() {
22127            checkCaller();
22128            // Will bring task to front if it already has a root activity.
22129            final long origId = Binder.clearCallingIdentity();
22130            try {
22131                synchronized (this) {
22132                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22133                }
22134            } finally {
22135                Binder.restoreCallingIdentity(origId);
22136            }
22137        }
22138
22139        @Override
22140        public int startActivity(IBinder whoThread, String callingPackage,
22141                Intent intent, String resolvedType, Bundle bOptions) {
22142            checkCaller();
22143
22144            int callingUser = UserHandle.getCallingUserId();
22145            TaskRecord tr;
22146            IApplicationThread appThread;
22147            synchronized (ActivityManagerService.this) {
22148                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22149                if (tr == null) {
22150                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22151                }
22152                appThread = ApplicationThreadNative.asInterface(whoThread);
22153                if (appThread == null) {
22154                    throw new IllegalArgumentException("Bad app thread " + appThread);
22155                }
22156            }
22157            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22158                    resolvedType, null, null, null, null, 0, 0, null, null,
22159                    null, bOptions, false, callingUser, null, tr);
22160        }
22161
22162        @Override
22163        public void setExcludeFromRecents(boolean exclude) {
22164            checkCaller();
22165
22166            synchronized (ActivityManagerService.this) {
22167                long origId = Binder.clearCallingIdentity();
22168                try {
22169                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22170                    if (tr == null) {
22171                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22172                    }
22173                    Intent intent = tr.getBaseIntent();
22174                    if (exclude) {
22175                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22176                    } else {
22177                        intent.setFlags(intent.getFlags()
22178                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22179                    }
22180                } finally {
22181                    Binder.restoreCallingIdentity(origId);
22182                }
22183            }
22184        }
22185    }
22186
22187    /**
22188     * Kill processes for the user with id userId and that depend on the package named packageName
22189     */
22190    @Override
22191    public void killPackageDependents(String packageName, int userId) {
22192        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22193        if (packageName == null) {
22194            throw new NullPointerException(
22195                    "Cannot kill the dependents of a package without its name.");
22196        }
22197
22198        long callingId = Binder.clearCallingIdentity();
22199        IPackageManager pm = AppGlobals.getPackageManager();
22200        int pkgUid = -1;
22201        try {
22202            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22203        } catch (RemoteException e) {
22204        }
22205        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22206            throw new IllegalArgumentException(
22207                    "Cannot kill dependents of non-existing package " + packageName);
22208        }
22209        try {
22210            synchronized(this) {
22211                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22212                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22213                        "dep: " + packageName);
22214            }
22215        } finally {
22216            Binder.restoreCallingIdentity(callingId);
22217        }
22218    }
22219
22220    @Override
22221    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22222        final int userId = intent.getCreatorUserHandle().getIdentifier();
22223        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22224            return false;
22225        }
22226        IIntentSender target = intent.getTarget();
22227        if (!(target instanceof PendingIntentRecord)) {
22228            return false;
22229        }
22230        final PendingIntentRecord record = (PendingIntentRecord) target;
22231        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22232                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22233        // For direct boot aware activities, they can be shown without triggering a work challenge
22234        // before the profile user is unlocked.
22235        return rInfo != null && rInfo.activityInfo != null;
22236    }
22237}
22238