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                final ActivityRecord r = (ActivityRecord) msg.obj;
2317                boolean vrMode;
2318                ComponentName requestedPackage;
2319                ComponentName callingPackage;
2320                int userId;
2321                synchronized (ActivityManagerService.this) {
2322                    vrMode = r.requestedVrComponent != null;
2323                    requestedPackage = r.requestedVrComponent;
2324                    userId = r.userId;
2325                    callingPackage = r.info.getComponentName();
2326                    if (mInVrMode != vrMode) {
2327                        mInVrMode = vrMode;
2328                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2329                        if (r.app != null) {
2330                            ProcessRecord proc = r.app;
2331                            if (proc.vrThreadTid > 0) {
2332                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2333                                    try {
2334                                        if (mInVrMode == true) {
2335                                            Process.setThreadScheduler(proc.vrThreadTid,
2336                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2337                                        } else {
2338                                            Process.setThreadScheduler(proc.vrThreadTid,
2339                                                Process.SCHED_OTHER, 0);
2340                                        }
2341                                    } catch (IllegalArgumentException e) {
2342                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2343                                                + " not exist:\n" + e);
2344                                    }
2345                                }
2346                            }
2347                        }
2348                    }
2349                }
2350                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2351            } break;
2352            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2353                final ActivityRecord r = (ActivityRecord) msg.obj;
2354                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2355                if (needsVrMode) {
2356                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2357                            r.info.getComponentName(), false);
2358                }
2359            } break;
2360            }
2361        }
2362    };
2363
2364    static final int COLLECT_PSS_BG_MSG = 1;
2365
2366    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2367        @Override
2368        public void handleMessage(Message msg) {
2369            switch (msg.what) {
2370            case COLLECT_PSS_BG_MSG: {
2371                long start = SystemClock.uptimeMillis();
2372                MemInfoReader memInfo = null;
2373                synchronized (ActivityManagerService.this) {
2374                    if (mFullPssPending) {
2375                        mFullPssPending = false;
2376                        memInfo = new MemInfoReader();
2377                    }
2378                }
2379                if (memInfo != null) {
2380                    updateCpuStatsNow();
2381                    long nativeTotalPss = 0;
2382                    final List<ProcessCpuTracker.Stats> stats;
2383                    synchronized (mProcessCpuTracker) {
2384                        stats = mProcessCpuTracker.getStats( (st)-> {
2385                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2386                        });
2387                    }
2388                    final int N = stats.size();
2389                    for (int j = 0; j < N; j++) {
2390                        synchronized (mPidsSelfLocked) {
2391                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2392                                // This is one of our own processes; skip it.
2393                                continue;
2394                            }
2395                        }
2396                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2397                    }
2398                    memInfo.readMemInfo();
2399                    synchronized (ActivityManagerService.this) {
2400                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2401                                + (SystemClock.uptimeMillis()-start) + "ms");
2402                        final long cachedKb = memInfo.getCachedSizeKb();
2403                        final long freeKb = memInfo.getFreeSizeKb();
2404                        final long zramKb = memInfo.getZramTotalSizeKb();
2405                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2406                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2407                                kernelKb*1024, nativeTotalPss*1024);
2408                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2409                                nativeTotalPss);
2410                    }
2411                }
2412
2413                int num = 0;
2414                long[] tmp = new long[2];
2415                do {
2416                    ProcessRecord proc;
2417                    int procState;
2418                    int pid;
2419                    long lastPssTime;
2420                    synchronized (ActivityManagerService.this) {
2421                        if (mPendingPssProcesses.size() <= 0) {
2422                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2423                                    "Collected PSS of " + num + " processes in "
2424                                    + (SystemClock.uptimeMillis() - start) + "ms");
2425                            mPendingPssProcesses.clear();
2426                            return;
2427                        }
2428                        proc = mPendingPssProcesses.remove(0);
2429                        procState = proc.pssProcState;
2430                        lastPssTime = proc.lastPssTime;
2431                        if (proc.thread != null && procState == proc.setProcState
2432                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2433                                        < SystemClock.uptimeMillis()) {
2434                            pid = proc.pid;
2435                        } else {
2436                            proc = null;
2437                            pid = 0;
2438                        }
2439                    }
2440                    if (proc != null) {
2441                        long pss = Debug.getPss(pid, tmp, null);
2442                        synchronized (ActivityManagerService.this) {
2443                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2444                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2445                                num++;
2446                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2447                                        SystemClock.uptimeMillis());
2448                            }
2449                        }
2450                    }
2451                } while (true);
2452            }
2453            }
2454        }
2455    };
2456
2457    public void setSystemProcess() {
2458        try {
2459            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2460            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2461            ServiceManager.addService("meminfo", new MemBinder(this));
2462            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2463            ServiceManager.addService("dbinfo", new DbBinder(this));
2464            if (MONITOR_CPU_USAGE) {
2465                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2466            }
2467            ServiceManager.addService("permission", new PermissionController(this));
2468            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2469
2470            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2471                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2472            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2473
2474            synchronized (this) {
2475                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2476                app.persistent = true;
2477                app.pid = MY_PID;
2478                app.maxAdj = ProcessList.SYSTEM_ADJ;
2479                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2480                synchronized (mPidsSelfLocked) {
2481                    mPidsSelfLocked.put(app.pid, app);
2482                }
2483                updateLruProcessLocked(app, false, null);
2484                updateOomAdjLocked();
2485            }
2486        } catch (PackageManager.NameNotFoundException e) {
2487            throw new RuntimeException(
2488                    "Unable to find android system package", e);
2489        }
2490    }
2491
2492    public void setWindowManager(WindowManagerService wm) {
2493        mWindowManager = wm;
2494        mStackSupervisor.setWindowManager(wm);
2495        mActivityStarter.setWindowManager(wm);
2496    }
2497
2498    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2499        mUsageStatsService = usageStatsManager;
2500    }
2501
2502    public void startObservingNativeCrashes() {
2503        final NativeCrashListener ncl = new NativeCrashListener(this);
2504        ncl.start();
2505    }
2506
2507    public IAppOpsService getAppOpsService() {
2508        return mAppOpsService;
2509    }
2510
2511    static class MemBinder extends Binder {
2512        ActivityManagerService mActivityManagerService;
2513        MemBinder(ActivityManagerService activityManagerService) {
2514            mActivityManagerService = activityManagerService;
2515        }
2516
2517        @Override
2518        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2519            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2520                    != PackageManager.PERMISSION_GRANTED) {
2521                pw.println("Permission Denial: can't dump meminfo from from pid="
2522                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2523                        + " without permission " + android.Manifest.permission.DUMP);
2524                return;
2525            }
2526
2527            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2528        }
2529    }
2530
2531    static class GraphicsBinder extends Binder {
2532        ActivityManagerService mActivityManagerService;
2533        GraphicsBinder(ActivityManagerService activityManagerService) {
2534            mActivityManagerService = activityManagerService;
2535        }
2536
2537        @Override
2538        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2539            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2540                    != PackageManager.PERMISSION_GRANTED) {
2541                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2542                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2543                        + " without permission " + android.Manifest.permission.DUMP);
2544                return;
2545            }
2546
2547            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2548        }
2549    }
2550
2551    static class DbBinder extends Binder {
2552        ActivityManagerService mActivityManagerService;
2553        DbBinder(ActivityManagerService activityManagerService) {
2554            mActivityManagerService = activityManagerService;
2555        }
2556
2557        @Override
2558        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2559            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2560                    != PackageManager.PERMISSION_GRANTED) {
2561                pw.println("Permission Denial: can't dump dbinfo from from pid="
2562                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2563                        + " without permission " + android.Manifest.permission.DUMP);
2564                return;
2565            }
2566
2567            mActivityManagerService.dumpDbInfo(fd, pw, args);
2568        }
2569    }
2570
2571    static class CpuBinder extends Binder {
2572        ActivityManagerService mActivityManagerService;
2573        CpuBinder(ActivityManagerService activityManagerService) {
2574            mActivityManagerService = activityManagerService;
2575        }
2576
2577        @Override
2578        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2579            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2580                    != PackageManager.PERMISSION_GRANTED) {
2581                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2582                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2583                        + " without permission " + android.Manifest.permission.DUMP);
2584                return;
2585            }
2586
2587            synchronized (mActivityManagerService.mProcessCpuTracker) {
2588                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2589                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2590                        SystemClock.uptimeMillis()));
2591            }
2592        }
2593    }
2594
2595    public static final class Lifecycle extends SystemService {
2596        private final ActivityManagerService mService;
2597
2598        public Lifecycle(Context context) {
2599            super(context);
2600            mService = new ActivityManagerService(context);
2601        }
2602
2603        @Override
2604        public void onStart() {
2605            mService.start();
2606        }
2607
2608        public ActivityManagerService getService() {
2609            return mService;
2610        }
2611    }
2612
2613    // Note: This method is invoked on the main thread but may need to attach various
2614    // handlers to other threads.  So take care to be explicit about the looper.
2615    public ActivityManagerService(Context systemContext) {
2616        mContext = systemContext;
2617        mFactoryTest = FactoryTest.getMode();
2618        mSystemThread = ActivityThread.currentActivityThread();
2619
2620        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2621
2622        mHandlerThread = new ServiceThread(TAG,
2623                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2624        mHandlerThread.start();
2625        mHandler = new MainHandler(mHandlerThread.getLooper());
2626        mUiHandler = new UiHandler();
2627
2628        /* static; one-time init here */
2629        if (sKillHandler == null) {
2630            sKillThread = new ServiceThread(TAG + ":kill",
2631                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2632            sKillThread.start();
2633            sKillHandler = new KillHandler(sKillThread.getLooper());
2634        }
2635
2636        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2637                "foreground", BROADCAST_FG_TIMEOUT, false);
2638        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2639                "background", BROADCAST_BG_TIMEOUT, true);
2640        mBroadcastQueues[0] = mFgBroadcastQueue;
2641        mBroadcastQueues[1] = mBgBroadcastQueue;
2642
2643        mServices = new ActiveServices(this);
2644        mProviderMap = new ProviderMap(this);
2645        mAppErrors = new AppErrors(mContext, this);
2646
2647        // TODO: Move creation of battery stats service outside of activity manager service.
2648        File dataDir = Environment.getDataDirectory();
2649        File systemDir = new File(dataDir, "system");
2650        systemDir.mkdirs();
2651        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2652        mBatteryStatsService.getActiveStatistics().readLocked();
2653        mBatteryStatsService.scheduleWriteToDisk();
2654        mOnBattery = DEBUG_POWER ? true
2655                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2656        mBatteryStatsService.getActiveStatistics().setCallback(this);
2657
2658        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2659
2660        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2661        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2662                new IAppOpsCallback.Stub() {
2663                    @Override public void opChanged(int op, int uid, String packageName) {
2664                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2665                            if (mAppOpsService.checkOperation(op, uid, packageName)
2666                                    != AppOpsManager.MODE_ALLOWED) {
2667                                runInBackgroundDisabled(uid);
2668                            }
2669                        }
2670                    }
2671                });
2672
2673        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2674
2675        mUserController = new UserController(this);
2676
2677        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2678            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2679
2680        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2681            mUseFifoUiScheduling = true;
2682        }
2683
2684        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2685
2686        mConfiguration.setToDefaults();
2687        mConfiguration.setLocales(LocaleList.getDefault());
2688
2689        mConfigurationSeq = mConfiguration.seq = 1;
2690        mProcessCpuTracker.init();
2691
2692        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2693        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2694        mStackSupervisor = new ActivityStackSupervisor(this);
2695        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2696        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2697
2698        mProcessCpuThread = new Thread("CpuTracker") {
2699            @Override
2700            public void run() {
2701                while (true) {
2702                    try {
2703                        try {
2704                            synchronized(this) {
2705                                final long now = SystemClock.uptimeMillis();
2706                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2707                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2708                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2709                                //        + ", write delay=" + nextWriteDelay);
2710                                if (nextWriteDelay < nextCpuDelay) {
2711                                    nextCpuDelay = nextWriteDelay;
2712                                }
2713                                if (nextCpuDelay > 0) {
2714                                    mProcessCpuMutexFree.set(true);
2715                                    this.wait(nextCpuDelay);
2716                                }
2717                            }
2718                        } catch (InterruptedException e) {
2719                        }
2720                        updateCpuStatsNow();
2721                    } catch (Exception e) {
2722                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2723                    }
2724                }
2725            }
2726        };
2727
2728        Watchdog.getInstance().addMonitor(this);
2729        Watchdog.getInstance().addThread(mHandler);
2730    }
2731
2732    public void setSystemServiceManager(SystemServiceManager mgr) {
2733        mSystemServiceManager = mgr;
2734    }
2735
2736    public void setInstaller(Installer installer) {
2737        mInstaller = installer;
2738    }
2739
2740    private void start() {
2741        Process.removeAllProcessGroups();
2742        mProcessCpuThread.start();
2743
2744        mBatteryStatsService.publish(mContext);
2745        mAppOpsService.publish(mContext);
2746        Slog.d("AppOps", "AppOpsService published");
2747        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2748    }
2749
2750    void onUserStoppedLocked(int userId) {
2751        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2752    }
2753
2754    public void initPowerManagement() {
2755        mStackSupervisor.initPowerManagement();
2756        mBatteryStatsService.initPowerManagement();
2757        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2758        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2759        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2760        mVoiceWakeLock.setReferenceCounted(false);
2761    }
2762
2763    @Override
2764    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2765            throws RemoteException {
2766        if (code == SYSPROPS_TRANSACTION) {
2767            // We need to tell all apps about the system property change.
2768            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2769            synchronized(this) {
2770                final int NP = mProcessNames.getMap().size();
2771                for (int ip=0; ip<NP; ip++) {
2772                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2773                    final int NA = apps.size();
2774                    for (int ia=0; ia<NA; ia++) {
2775                        ProcessRecord app = apps.valueAt(ia);
2776                        if (app.thread != null) {
2777                            procs.add(app.thread.asBinder());
2778                        }
2779                    }
2780                }
2781            }
2782
2783            int N = procs.size();
2784            for (int i=0; i<N; i++) {
2785                Parcel data2 = Parcel.obtain();
2786                try {
2787                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2788                } catch (RemoteException e) {
2789                }
2790                data2.recycle();
2791            }
2792        }
2793        try {
2794            return super.onTransact(code, data, reply, flags);
2795        } catch (RuntimeException e) {
2796            // The activity manager only throws security exceptions, so let's
2797            // log all others.
2798            if (!(e instanceof SecurityException)) {
2799                Slog.wtf(TAG, "Activity Manager Crash", e);
2800            }
2801            throw e;
2802        }
2803    }
2804
2805    void updateCpuStats() {
2806        final long now = SystemClock.uptimeMillis();
2807        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2808            return;
2809        }
2810        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2811            synchronized (mProcessCpuThread) {
2812                mProcessCpuThread.notify();
2813            }
2814        }
2815    }
2816
2817    void updateCpuStatsNow() {
2818        synchronized (mProcessCpuTracker) {
2819            mProcessCpuMutexFree.set(false);
2820            final long now = SystemClock.uptimeMillis();
2821            boolean haveNewCpuStats = false;
2822
2823            if (MONITOR_CPU_USAGE &&
2824                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2825                mLastCpuTime.set(now);
2826                mProcessCpuTracker.update();
2827                if (mProcessCpuTracker.hasGoodLastStats()) {
2828                    haveNewCpuStats = true;
2829                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2830                    //Slog.i(TAG, "Total CPU usage: "
2831                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2832
2833                    // Slog the cpu usage if the property is set.
2834                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2835                        int user = mProcessCpuTracker.getLastUserTime();
2836                        int system = mProcessCpuTracker.getLastSystemTime();
2837                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2838                        int irq = mProcessCpuTracker.getLastIrqTime();
2839                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2840                        int idle = mProcessCpuTracker.getLastIdleTime();
2841
2842                        int total = user + system + iowait + irq + softIrq + idle;
2843                        if (total == 0) total = 1;
2844
2845                        EventLog.writeEvent(EventLogTags.CPU,
2846                                ((user+system+iowait+irq+softIrq) * 100) / total,
2847                                (user * 100) / total,
2848                                (system * 100) / total,
2849                                (iowait * 100) / total,
2850                                (irq * 100) / total,
2851                                (softIrq * 100) / total);
2852                    }
2853                }
2854            }
2855
2856            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2857            synchronized(bstats) {
2858                synchronized(mPidsSelfLocked) {
2859                    if (haveNewCpuStats) {
2860                        if (bstats.startAddingCpuLocked()) {
2861                            int totalUTime = 0;
2862                            int totalSTime = 0;
2863                            final int N = mProcessCpuTracker.countStats();
2864                            for (int i=0; i<N; i++) {
2865                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2866                                if (!st.working) {
2867                                    continue;
2868                                }
2869                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2870                                totalUTime += st.rel_utime;
2871                                totalSTime += st.rel_stime;
2872                                if (pr != null) {
2873                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2874                                    if (ps == null || !ps.isActive()) {
2875                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2876                                                pr.info.uid, pr.processName);
2877                                    }
2878                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2879                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2880                                } else {
2881                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2882                                    if (ps == null || !ps.isActive()) {
2883                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2884                                                bstats.mapUid(st.uid), st.name);
2885                                    }
2886                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2887                                }
2888                            }
2889                            final int userTime = mProcessCpuTracker.getLastUserTime();
2890                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2891                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2892                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2893                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2894                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2895                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2896                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2897                        }
2898                    }
2899                }
2900
2901                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2902                    mLastWriteTime = now;
2903                    mBatteryStatsService.scheduleWriteToDisk();
2904                }
2905            }
2906        }
2907    }
2908
2909    @Override
2910    public void batteryNeedsCpuUpdate() {
2911        updateCpuStatsNow();
2912    }
2913
2914    @Override
2915    public void batteryPowerChanged(boolean onBattery) {
2916        // When plugging in, update the CPU stats first before changing
2917        // the plug state.
2918        updateCpuStatsNow();
2919        synchronized (this) {
2920            synchronized(mPidsSelfLocked) {
2921                mOnBattery = DEBUG_POWER ? true : onBattery;
2922            }
2923        }
2924    }
2925
2926    @Override
2927    public void batterySendBroadcast(Intent intent) {
2928        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2929                AppOpsManager.OP_NONE, null, false, false,
2930                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2931    }
2932
2933    /**
2934     * Initialize the application bind args. These are passed to each
2935     * process when the bindApplication() IPC is sent to the process. They're
2936     * lazily setup to make sure the services are running when they're asked for.
2937     */
2938    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2939        // Isolated processes won't get this optimization, so that we don't
2940        // violate the rules about which services they have access to.
2941        if (isolated) {
2942            if (mIsolatedAppBindArgs == null) {
2943                mIsolatedAppBindArgs = new HashMap<>();
2944                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2945            }
2946            return mIsolatedAppBindArgs;
2947        }
2948
2949        if (mAppBindArgs == null) {
2950            mAppBindArgs = new HashMap<>();
2951
2952            // Setup the application init args
2953            mAppBindArgs.put("package", ServiceManager.getService("package"));
2954            mAppBindArgs.put("window", ServiceManager.getService("window"));
2955            mAppBindArgs.put(Context.ALARM_SERVICE,
2956                    ServiceManager.getService(Context.ALARM_SERVICE));
2957        }
2958        return mAppBindArgs;
2959    }
2960
2961    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2962        if (r == null || mFocusedActivity == r) {
2963            return false;
2964        }
2965
2966        if (!r.isFocusable()) {
2967            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2968            return false;
2969        }
2970
2971        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2972
2973        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2974        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2975                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2976        mDoingSetFocusedActivity = true;
2977
2978        final ActivityRecord last = mFocusedActivity;
2979        mFocusedActivity = r;
2980        if (r.task.isApplicationTask()) {
2981            if (mCurAppTimeTracker != r.appTimeTracker) {
2982                // We are switching app tracking.  Complete the current one.
2983                if (mCurAppTimeTracker != null) {
2984                    mCurAppTimeTracker.stop();
2985                    mHandler.obtainMessage(
2986                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2987                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2988                    mCurAppTimeTracker = null;
2989                }
2990                if (r.appTimeTracker != null) {
2991                    mCurAppTimeTracker = r.appTimeTracker;
2992                    startTimeTrackingFocusedActivityLocked();
2993                }
2994            } else {
2995                startTimeTrackingFocusedActivityLocked();
2996            }
2997        } else {
2998            r.appTimeTracker = null;
2999        }
3000        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3001        // TODO: Probably not, because we don't want to resume voice on switching
3002        // back to this activity
3003        if (r.task.voiceInteractor != null) {
3004            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3005        } else {
3006            finishRunningVoiceLocked();
3007            IVoiceInteractionSession session;
3008            if (last != null && ((session = last.task.voiceSession) != null
3009                    || (session = last.voiceSession) != null)) {
3010                // We had been in a voice interaction session, but now focused has
3011                // move to something different.  Just finish the session, we can't
3012                // return to it and retain the proper state and synchronization with
3013                // the voice interaction service.
3014                finishVoiceTask(session);
3015            }
3016        }
3017        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3018            mWindowManager.setFocusedApp(r.appToken, true);
3019        }
3020        applyUpdateLockStateLocked(r);
3021        applyUpdateVrModeLocked(r);
3022        if (mFocusedActivity.userId != mLastFocusedUserId) {
3023            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3024            mHandler.obtainMessage(
3025                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3026            mLastFocusedUserId = mFocusedActivity.userId;
3027        }
3028
3029        // Log a warning if the focused app is changed during the process. This could
3030        // indicate a problem of the focus setting logic!
3031        if (mFocusedActivity != r) Slog.w(TAG,
3032                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3033        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3034
3035        EventLogTags.writeAmFocusedActivity(
3036                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3037                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3038                reason);
3039        return true;
3040    }
3041
3042    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3043        if (mFocusedActivity != goingAway) {
3044            return;
3045        }
3046
3047        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3048        if (focusedStack != null) {
3049            final ActivityRecord top = focusedStack.topActivity();
3050            if (top != null && top.userId != mLastFocusedUserId) {
3051                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3052                mHandler.sendMessage(
3053                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3054                mLastFocusedUserId = top.userId;
3055            }
3056        }
3057
3058        // Try to move focus to another activity if possible.
3059        if (setFocusedActivityLocked(
3060                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3061            return;
3062        }
3063
3064        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3065                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3066        mFocusedActivity = null;
3067        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3068    }
3069
3070    @Override
3071    public void setFocusedStack(int stackId) {
3072        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3073        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3074        final long callingId = Binder.clearCallingIdentity();
3075        try {
3076            synchronized (this) {
3077                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3078                if (stack == null) {
3079                    return;
3080                }
3081                final ActivityRecord r = stack.topRunningActivityLocked();
3082                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3083                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3084                }
3085            }
3086        } finally {
3087            Binder.restoreCallingIdentity(callingId);
3088        }
3089    }
3090
3091    @Override
3092    public void setFocusedTask(int taskId) {
3093        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3094        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3095        final long callingId = Binder.clearCallingIdentity();
3096        try {
3097            synchronized (this) {
3098                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3099                if (task == null) {
3100                    return;
3101                }
3102                if (mUserController.shouldConfirmCredentials(task.userId)) {
3103                    mActivityStarter.showConfirmDeviceCredential(task.userId);
3104                    if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3105                        mStackSupervisor.moveTaskToStackLocked(task.taskId,
3106                                FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3107                                "setFocusedTask", ANIMATE);
3108                    }
3109                    return;
3110                }
3111                final ActivityRecord r = task.topRunningActivityLocked();
3112                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3113                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3114                }
3115            }
3116        } finally {
3117            Binder.restoreCallingIdentity(callingId);
3118        }
3119    }
3120
3121    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3122    @Override
3123    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3124        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3125        synchronized (this) {
3126            if (listener != null) {
3127                mTaskStackListeners.register(listener);
3128            }
3129        }
3130    }
3131
3132    @Override
3133    public void notifyActivityDrawn(IBinder token) {
3134        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3135        synchronized (this) {
3136            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3137            if (r != null) {
3138                r.task.stack.notifyActivityDrawnLocked(r);
3139            }
3140        }
3141    }
3142
3143    final void applyUpdateLockStateLocked(ActivityRecord r) {
3144        // Modifications to the UpdateLock state are done on our handler, outside
3145        // the activity manager's locks.  The new state is determined based on the
3146        // state *now* of the relevant activity record.  The object is passed to
3147        // the handler solely for logging detail, not to be consulted/modified.
3148        final boolean nextState = r != null && r.immersive;
3149        mHandler.sendMessage(
3150                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3151    }
3152
3153    final void applyUpdateVrModeLocked(ActivityRecord r) {
3154        mHandler.sendMessage(
3155                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3156    }
3157
3158    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3159        mHandler.sendMessage(
3160                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3161    }
3162
3163    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3164            ComponentName callingPackage, boolean immediate) {
3165        VrManagerInternal vrService =
3166                LocalServices.getService(VrManagerInternal.class);
3167        if (immediate) {
3168            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3169        } else {
3170            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3171        }
3172    }
3173
3174    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3175        Message msg = Message.obtain();
3176        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3177        msg.obj = r.task.askedCompatMode ? null : r;
3178        mUiHandler.sendMessage(msg);
3179    }
3180
3181    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3182        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3183                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3184            final Message msg = Message.obtain();
3185            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3186            msg.obj = r;
3187            mUiHandler.sendMessage(msg);
3188        }
3189    }
3190
3191    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3192            String what, Object obj, ProcessRecord srcApp) {
3193        app.lastActivityTime = now;
3194
3195        if (app.activities.size() > 0) {
3196            // Don't want to touch dependent processes that are hosting activities.
3197            return index;
3198        }
3199
3200        int lrui = mLruProcesses.lastIndexOf(app);
3201        if (lrui < 0) {
3202            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3203                    + what + " " + obj + " from " + srcApp);
3204            return index;
3205        }
3206
3207        if (lrui >= index) {
3208            // Don't want to cause this to move dependent processes *back* in the
3209            // list as if they were less frequently used.
3210            return index;
3211        }
3212
3213        if (lrui >= mLruProcessActivityStart) {
3214            // Don't want to touch dependent processes that are hosting activities.
3215            return index;
3216        }
3217
3218        mLruProcesses.remove(lrui);
3219        if (index > 0) {
3220            index--;
3221        }
3222        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3223                + " in LRU list: " + app);
3224        mLruProcesses.add(index, app);
3225        return index;
3226    }
3227
3228    static void killProcessGroup(int uid, int pid) {
3229        if (sKillHandler != null) {
3230            sKillHandler.sendMessage(
3231                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3232        } else {
3233            Slog.w(TAG, "Asked to kill process group before system bringup!");
3234            Process.killProcessGroup(uid, pid);
3235        }
3236    }
3237
3238    final void removeLruProcessLocked(ProcessRecord app) {
3239        int lrui = mLruProcesses.lastIndexOf(app);
3240        if (lrui >= 0) {
3241            if (!app.killed) {
3242                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3243                Process.killProcessQuiet(app.pid);
3244                killProcessGroup(app.uid, app.pid);
3245            }
3246            if (lrui <= mLruProcessActivityStart) {
3247                mLruProcessActivityStart--;
3248            }
3249            if (lrui <= mLruProcessServiceStart) {
3250                mLruProcessServiceStart--;
3251            }
3252            mLruProcesses.remove(lrui);
3253        }
3254    }
3255
3256    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3257            ProcessRecord client) {
3258        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3259                || app.treatLikeActivity;
3260        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3261        if (!activityChange && hasActivity) {
3262            // The process has activities, so we are only allowing activity-based adjustments
3263            // to move it.  It should be kept in the front of the list with other
3264            // processes that have activities, and we don't want those to change their
3265            // order except due to activity operations.
3266            return;
3267        }
3268
3269        mLruSeq++;
3270        final long now = SystemClock.uptimeMillis();
3271        app.lastActivityTime = now;
3272
3273        // First a quick reject: if the app is already at the position we will
3274        // put it, then there is nothing to do.
3275        if (hasActivity) {
3276            final int N = mLruProcesses.size();
3277            if (N > 0 && mLruProcesses.get(N-1) == app) {
3278                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3279                return;
3280            }
3281        } else {
3282            if (mLruProcessServiceStart > 0
3283                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3284                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3285                return;
3286            }
3287        }
3288
3289        int lrui = mLruProcesses.lastIndexOf(app);
3290
3291        if (app.persistent && lrui >= 0) {
3292            // We don't care about the position of persistent processes, as long as
3293            // they are in the list.
3294            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3295            return;
3296        }
3297
3298        /* In progress: compute new position first, so we can avoid doing work
3299           if the process is not actually going to move.  Not yet working.
3300        int addIndex;
3301        int nextIndex;
3302        boolean inActivity = false, inService = false;
3303        if (hasActivity) {
3304            // Process has activities, put it at the very tipsy-top.
3305            addIndex = mLruProcesses.size();
3306            nextIndex = mLruProcessServiceStart;
3307            inActivity = true;
3308        } else if (hasService) {
3309            // Process has services, put it at the top of the service list.
3310            addIndex = mLruProcessActivityStart;
3311            nextIndex = mLruProcessServiceStart;
3312            inActivity = true;
3313            inService = true;
3314        } else  {
3315            // Process not otherwise of interest, it goes to the top of the non-service area.
3316            addIndex = mLruProcessServiceStart;
3317            if (client != null) {
3318                int clientIndex = mLruProcesses.lastIndexOf(client);
3319                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3320                        + app);
3321                if (clientIndex >= 0 && addIndex > clientIndex) {
3322                    addIndex = clientIndex;
3323                }
3324            }
3325            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3326        }
3327
3328        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3329                + mLruProcessActivityStart + "): " + app);
3330        */
3331
3332        if (lrui >= 0) {
3333            if (lrui < mLruProcessActivityStart) {
3334                mLruProcessActivityStart--;
3335            }
3336            if (lrui < mLruProcessServiceStart) {
3337                mLruProcessServiceStart--;
3338            }
3339            /*
3340            if (addIndex > lrui) {
3341                addIndex--;
3342            }
3343            if (nextIndex > lrui) {
3344                nextIndex--;
3345            }
3346            */
3347            mLruProcesses.remove(lrui);
3348        }
3349
3350        /*
3351        mLruProcesses.add(addIndex, app);
3352        if (inActivity) {
3353            mLruProcessActivityStart++;
3354        }
3355        if (inService) {
3356            mLruProcessActivityStart++;
3357        }
3358        */
3359
3360        int nextIndex;
3361        if (hasActivity) {
3362            final int N = mLruProcesses.size();
3363            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3364                // Process doesn't have activities, but has clients with
3365                // activities...  move it up, but one below the top (the top
3366                // should always have a real activity).
3367                if (DEBUG_LRU) Slog.d(TAG_LRU,
3368                        "Adding to second-top of LRU activity list: " + app);
3369                mLruProcesses.add(N - 1, app);
3370                // To keep it from spamming the LRU list (by making a bunch of clients),
3371                // we will push down any other entries owned by the app.
3372                final int uid = app.info.uid;
3373                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3374                    ProcessRecord subProc = mLruProcesses.get(i);
3375                    if (subProc.info.uid == uid) {
3376                        // We want to push this one down the list.  If the process after
3377                        // it is for the same uid, however, don't do so, because we don't
3378                        // want them internally to be re-ordered.
3379                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3380                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3381                                    "Pushing uid " + uid + " swapping at " + i + ": "
3382                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3383                            ProcessRecord tmp = mLruProcesses.get(i);
3384                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3385                            mLruProcesses.set(i - 1, tmp);
3386                            i--;
3387                        }
3388                    } else {
3389                        // A gap, we can stop here.
3390                        break;
3391                    }
3392                }
3393            } else {
3394                // Process has activities, put it at the very tipsy-top.
3395                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3396                mLruProcesses.add(app);
3397            }
3398            nextIndex = mLruProcessServiceStart;
3399        } else if (hasService) {
3400            // Process has services, put it at the top of the service list.
3401            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3402            mLruProcesses.add(mLruProcessActivityStart, app);
3403            nextIndex = mLruProcessServiceStart;
3404            mLruProcessActivityStart++;
3405        } else  {
3406            // Process not otherwise of interest, it goes to the top of the non-service area.
3407            int index = mLruProcessServiceStart;
3408            if (client != null) {
3409                // If there is a client, don't allow the process to be moved up higher
3410                // in the list than that client.
3411                int clientIndex = mLruProcesses.lastIndexOf(client);
3412                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3413                        + " when updating " + app);
3414                if (clientIndex <= lrui) {
3415                    // Don't allow the client index restriction to push it down farther in the
3416                    // list than it already is.
3417                    clientIndex = lrui;
3418                }
3419                if (clientIndex >= 0 && index > clientIndex) {
3420                    index = clientIndex;
3421                }
3422            }
3423            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3424            mLruProcesses.add(index, app);
3425            nextIndex = index-1;
3426            mLruProcessActivityStart++;
3427            mLruProcessServiceStart++;
3428        }
3429
3430        // If the app is currently using a content provider or service,
3431        // bump those processes as well.
3432        for (int j=app.connections.size()-1; j>=0; j--) {
3433            ConnectionRecord cr = app.connections.valueAt(j);
3434            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3435                    && cr.binding.service.app != null
3436                    && cr.binding.service.app.lruSeq != mLruSeq
3437                    && !cr.binding.service.app.persistent) {
3438                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3439                        "service connection", cr, app);
3440            }
3441        }
3442        for (int j=app.conProviders.size()-1; j>=0; j--) {
3443            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3444            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3445                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3446                        "provider reference", cpr, app);
3447            }
3448        }
3449    }
3450
3451    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3452        if (uid == Process.SYSTEM_UID) {
3453            // The system gets to run in any process.  If there are multiple
3454            // processes with the same uid, just pick the first (this
3455            // should never happen).
3456            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3457            if (procs == null) return null;
3458            final int procCount = procs.size();
3459            for (int i = 0; i < procCount; i++) {
3460                final int procUid = procs.keyAt(i);
3461                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3462                    // Don't use an app process or different user process for system component.
3463                    continue;
3464                }
3465                return procs.valueAt(i);
3466            }
3467        }
3468        ProcessRecord proc = mProcessNames.get(processName, uid);
3469        if (false && proc != null && !keepIfLarge
3470                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3471                && proc.lastCachedPss >= 4000) {
3472            // Turn this condition on to cause killing to happen regularly, for testing.
3473            if (proc.baseProcessTracker != null) {
3474                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3475            }
3476            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3477        } else if (proc != null && !keepIfLarge
3478                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3479                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3480            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3481            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3482                if (proc.baseProcessTracker != null) {
3483                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3484                }
3485                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3486            }
3487        }
3488        return proc;
3489    }
3490
3491    void notifyPackageUse(String packageName, int reason) {
3492        IPackageManager pm = AppGlobals.getPackageManager();
3493        try {
3494            pm.notifyPackageUse(packageName, reason);
3495        } catch (RemoteException e) {
3496        }
3497    }
3498
3499    boolean isNextTransitionForward() {
3500        int transit = mWindowManager.getPendingAppTransition();
3501        return transit == TRANSIT_ACTIVITY_OPEN
3502                || transit == TRANSIT_TASK_OPEN
3503                || transit == TRANSIT_TASK_TO_FRONT;
3504    }
3505
3506    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3507            String processName, String abiOverride, int uid, Runnable crashHandler) {
3508        synchronized(this) {
3509            ApplicationInfo info = new ApplicationInfo();
3510            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3511            // For isolated processes, the former contains the parent's uid and the latter the
3512            // actual uid of the isolated process.
3513            // In the special case introduced by this method (which is, starting an isolated
3514            // process directly from the SystemServer without an actual parent app process) the
3515            // closest thing to a parent's uid is SYSTEM_UID.
3516            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3517            // the |isolated| logic in the ProcessRecord constructor.
3518            info.uid = Process.SYSTEM_UID;
3519            info.processName = processName;
3520            info.className = entryPoint;
3521            info.packageName = "android";
3522            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3523                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3524                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3525                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3526                    crashHandler);
3527            return proc != null ? proc.pid : 0;
3528        }
3529    }
3530
3531    final ProcessRecord startProcessLocked(String processName,
3532            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3533            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3534            boolean isolated, boolean keepIfLarge) {
3535        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3536                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3537                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3538                null /* crashHandler */);
3539    }
3540
3541    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3542            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3543            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3544            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3545        long startTime = SystemClock.elapsedRealtime();
3546        ProcessRecord app;
3547        if (!isolated) {
3548            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3549            checkTime(startTime, "startProcess: after getProcessRecord");
3550
3551            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3552                // If we are in the background, then check to see if this process
3553                // is bad.  If so, we will just silently fail.
3554                if (mAppErrors.isBadProcessLocked(info)) {
3555                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3556                            + "/" + info.processName);
3557                    return null;
3558                }
3559            } else {
3560                // When the user is explicitly starting a process, then clear its
3561                // crash count so that we won't make it bad until they see at
3562                // least one crash dialog again, and make the process good again
3563                // if it had been bad.
3564                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3565                        + "/" + info.processName);
3566                mAppErrors.resetProcessCrashTimeLocked(info);
3567                if (mAppErrors.isBadProcessLocked(info)) {
3568                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3569                            UserHandle.getUserId(info.uid), info.uid,
3570                            info.processName);
3571                    mAppErrors.clearBadProcessLocked(info);
3572                    if (app != null) {
3573                        app.bad = false;
3574                    }
3575                }
3576            }
3577        } else {
3578            // If this is an isolated process, it can't re-use an existing process.
3579            app = null;
3580        }
3581
3582        // app launch boost for big.little configurations
3583        // use cpusets to migrate freshly launched tasks to big cores
3584        nativeMigrateToBoost();
3585        mIsBoosted = true;
3586        mBoostStartTime = SystemClock.uptimeMillis();
3587        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3588        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3589
3590        // We don't have to do anything more if:
3591        // (1) There is an existing application record; and
3592        // (2) The caller doesn't think it is dead, OR there is no thread
3593        //     object attached to it so we know it couldn't have crashed; and
3594        // (3) There is a pid assigned to it, so it is either starting or
3595        //     already running.
3596        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3597                + " app=" + app + " knownToBeDead=" + knownToBeDead
3598                + " thread=" + (app != null ? app.thread : null)
3599                + " pid=" + (app != null ? app.pid : -1));
3600        if (app != null && app.pid > 0) {
3601            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3602                // We already have the app running, or are waiting for it to
3603                // come up (we have a pid but not yet its thread), so keep it.
3604                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3605                // If this is a new package in the process, add the package to the list
3606                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3607                checkTime(startTime, "startProcess: done, added package to proc");
3608                return app;
3609            }
3610
3611            // An application record is attached to a previous process,
3612            // clean it up now.
3613            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3614            checkTime(startTime, "startProcess: bad proc running, killing");
3615            killProcessGroup(app.uid, app.pid);
3616            handleAppDiedLocked(app, true, true);
3617            checkTime(startTime, "startProcess: done killing old proc");
3618        }
3619
3620        String hostingNameStr = hostingName != null
3621                ? hostingName.flattenToShortString() : null;
3622
3623        if (app == null) {
3624            checkTime(startTime, "startProcess: creating new process record");
3625            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3626            if (app == null) {
3627                Slog.w(TAG, "Failed making new process record for "
3628                        + processName + "/" + info.uid + " isolated=" + isolated);
3629                return null;
3630            }
3631            app.crashHandler = crashHandler;
3632            checkTime(startTime, "startProcess: done creating new process record");
3633        } else {
3634            // If this is a new package in the process, add the package to the list
3635            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3636            checkTime(startTime, "startProcess: added package to existing proc");
3637        }
3638
3639        // If the system is not ready yet, then hold off on starting this
3640        // process until it is.
3641        if (!mProcessesReady
3642                && !isAllowedWhileBooting(info)
3643                && !allowWhileBooting) {
3644            if (!mProcessesOnHold.contains(app)) {
3645                mProcessesOnHold.add(app);
3646            }
3647            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3648                    "System not ready, putting on hold: " + app);
3649            checkTime(startTime, "startProcess: returning with proc on hold");
3650            return app;
3651        }
3652
3653        checkTime(startTime, "startProcess: stepping in to startProcess");
3654        startProcessLocked(
3655                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3656        checkTime(startTime, "startProcess: done starting proc!");
3657        return (app.pid != 0) ? app : null;
3658    }
3659
3660    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3661        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3662    }
3663
3664    private final void startProcessLocked(ProcessRecord app,
3665            String hostingType, String hostingNameStr) {
3666        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3667                null /* entryPoint */, null /* entryPointArgs */);
3668    }
3669
3670    private final void startProcessLocked(ProcessRecord app, String hostingType,
3671            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3672        long startTime = SystemClock.elapsedRealtime();
3673        if (app.pid > 0 && app.pid != MY_PID) {
3674            checkTime(startTime, "startProcess: removing from pids map");
3675            synchronized (mPidsSelfLocked) {
3676                mPidsSelfLocked.remove(app.pid);
3677                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3678            }
3679            checkTime(startTime, "startProcess: done removing from pids map");
3680            app.setPid(0);
3681        }
3682
3683        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3684                "startProcessLocked removing on hold: " + app);
3685        mProcessesOnHold.remove(app);
3686
3687        checkTime(startTime, "startProcess: starting to update cpu stats");
3688        updateCpuStats();
3689        checkTime(startTime, "startProcess: done updating cpu stats");
3690
3691        try {
3692            try {
3693                final int userId = UserHandle.getUserId(app.uid);
3694                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3695            } catch (RemoteException e) {
3696                throw e.rethrowAsRuntimeException();
3697            }
3698
3699            int uid = app.uid;
3700            int[] gids = null;
3701            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3702            if (!app.isolated) {
3703                int[] permGids = null;
3704                try {
3705                    checkTime(startTime, "startProcess: getting gids from package manager");
3706                    final IPackageManager pm = AppGlobals.getPackageManager();
3707                    permGids = pm.getPackageGids(app.info.packageName,
3708                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3709                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3710                            MountServiceInternal.class);
3711                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3712                            app.info.packageName);
3713                } catch (RemoteException e) {
3714                    throw e.rethrowAsRuntimeException();
3715                }
3716
3717                /*
3718                 * Add shared application and profile GIDs so applications can share some
3719                 * resources like shared libraries and access user-wide resources
3720                 */
3721                if (ArrayUtils.isEmpty(permGids)) {
3722                    gids = new int[2];
3723                } else {
3724                    gids = new int[permGids.length + 2];
3725                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3726                }
3727                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3728                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3729            }
3730            checkTime(startTime, "startProcess: building args");
3731            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3732                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3733                        && mTopComponent != null
3734                        && app.processName.equals(mTopComponent.getPackageName())) {
3735                    uid = 0;
3736                }
3737                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3738                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3739                    uid = 0;
3740                }
3741            }
3742            int debugFlags = 0;
3743            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3744                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3745                // Also turn on CheckJNI for debuggable apps. It's quite
3746                // awkward to turn on otherwise.
3747                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3748            }
3749            // Run the app in safe mode if its manifest requests so or the
3750            // system is booted in safe mode.
3751            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3752                mSafeMode == true) {
3753                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3754            }
3755            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3756                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3757            }
3758            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3759            if ("true".equals(genDebugInfoProperty)) {
3760                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3761            }
3762            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3763                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3764            }
3765            if ("1".equals(SystemProperties.get("debug.assert"))) {
3766                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3767            }
3768            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3769                // Enable all debug flags required by the native debugger.
3770                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3771                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3772                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3773                mNativeDebuggingApp = null;
3774            }
3775
3776            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3777            if (requiredAbi == null) {
3778                requiredAbi = Build.SUPPORTED_ABIS[0];
3779            }
3780
3781            String instructionSet = null;
3782            if (app.info.primaryCpuAbi != null) {
3783                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3784            }
3785
3786            app.gids = gids;
3787            app.requiredAbi = requiredAbi;
3788            app.instructionSet = instructionSet;
3789
3790            // Start the process.  It will either succeed and return a result containing
3791            // the PID of the new process, or else throw a RuntimeException.
3792            boolean isActivityProcess = (entryPoint == null);
3793            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3794            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3795                    app.processName);
3796            checkTime(startTime, "startProcess: asking zygote to start proc");
3797            Process.ProcessStartResult startResult = Process.start(entryPoint,
3798                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3799                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3800                    app.info.dataDir, entryPointArgs);
3801            checkTime(startTime, "startProcess: returned from zygote!");
3802            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3803
3804            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3805            checkTime(startTime, "startProcess: done updating battery stats");
3806
3807            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3808                    UserHandle.getUserId(uid), startResult.pid, uid,
3809                    app.processName, hostingType,
3810                    hostingNameStr != null ? hostingNameStr : "");
3811
3812            try {
3813                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3814                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3815            } catch (RemoteException ex) {
3816                // Ignore
3817            }
3818
3819            if (app.persistent) {
3820                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3821            }
3822
3823            checkTime(startTime, "startProcess: building log message");
3824            StringBuilder buf = mStringBuilder;
3825            buf.setLength(0);
3826            buf.append("Start proc ");
3827            buf.append(startResult.pid);
3828            buf.append(':');
3829            buf.append(app.processName);
3830            buf.append('/');
3831            UserHandle.formatUid(buf, uid);
3832            if (!isActivityProcess) {
3833                buf.append(" [");
3834                buf.append(entryPoint);
3835                buf.append("]");
3836            }
3837            buf.append(" for ");
3838            buf.append(hostingType);
3839            if (hostingNameStr != null) {
3840                buf.append(" ");
3841                buf.append(hostingNameStr);
3842            }
3843            Slog.i(TAG, buf.toString());
3844            app.setPid(startResult.pid);
3845            app.usingWrapper = startResult.usingWrapper;
3846            app.removed = false;
3847            app.killed = false;
3848            app.killedByAm = false;
3849            checkTime(startTime, "startProcess: starting to update pids map");
3850            ProcessRecord oldApp;
3851            synchronized (mPidsSelfLocked) {
3852                oldApp = mPidsSelfLocked.get(startResult.pid);
3853            }
3854            // If there is already an app occupying that pid that hasn't been cleaned up
3855            if (oldApp != null && !app.isolated) {
3856                // Clean up anything relating to this pid first
3857                Slog.w(TAG, "Reusing pid " + startResult.pid
3858                        + " while app is still mapped to it");
3859                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3860                        true /*replacingPid*/);
3861            }
3862            synchronized (mPidsSelfLocked) {
3863                this.mPidsSelfLocked.put(startResult.pid, app);
3864                if (isActivityProcess) {
3865                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3866                    msg.obj = app;
3867                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3868                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3869                }
3870            }
3871            checkTime(startTime, "startProcess: done updating pids map");
3872        } catch (RuntimeException e) {
3873            Slog.e(TAG, "Failure starting process " + app.processName, e);
3874
3875            // Something went very wrong while trying to start this process; one
3876            // common case is when the package is frozen due to an active
3877            // upgrade. To recover, clean up any active bookkeeping related to
3878            // starting this process. (We already invoked this method once when
3879            // the package was initially frozen through KILL_APPLICATION_MSG, so
3880            // it doesn't hurt to use it again.)
3881            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3882                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3883        }
3884    }
3885
3886    void updateUsageStats(ActivityRecord component, boolean resumed) {
3887        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3888                "updateUsageStats: comp=" + component + "res=" + resumed);
3889        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3890        if (resumed) {
3891            if (mUsageStatsService != null) {
3892                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3893                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3894            }
3895            synchronized (stats) {
3896                stats.noteActivityResumedLocked(component.app.uid);
3897            }
3898        } else {
3899            if (mUsageStatsService != null) {
3900                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3901                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3902            }
3903            synchronized (stats) {
3904                stats.noteActivityPausedLocked(component.app.uid);
3905            }
3906        }
3907    }
3908
3909    Intent getHomeIntent() {
3910        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3911        intent.setComponent(mTopComponent);
3912        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3913        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3914            intent.addCategory(Intent.CATEGORY_HOME);
3915        }
3916        return intent;
3917    }
3918
3919    boolean startHomeActivityLocked(int userId, String reason) {
3920        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3921                && mTopAction == null) {
3922            // We are running in factory test mode, but unable to find
3923            // the factory test app, so just sit around displaying the
3924            // error message and don't try to start anything.
3925            return false;
3926        }
3927        Intent intent = getHomeIntent();
3928        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3929        if (aInfo != null) {
3930            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3931            // Don't do this if the home app is currently being
3932            // instrumented.
3933            aInfo = new ActivityInfo(aInfo);
3934            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3935            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3936                    aInfo.applicationInfo.uid, true);
3937            if (app == null || app.instrumentationClass == null) {
3938                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3939                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3940            }
3941        } else {
3942            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3943        }
3944
3945        return true;
3946    }
3947
3948    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3949        ActivityInfo ai = null;
3950        ComponentName comp = intent.getComponent();
3951        try {
3952            if (comp != null) {
3953                // Factory test.
3954                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3955            } else {
3956                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3957                        intent,
3958                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3959                        flags, userId);
3960
3961                if (info != null) {
3962                    ai = info.activityInfo;
3963                }
3964            }
3965        } catch (RemoteException e) {
3966            // ignore
3967        }
3968
3969        return ai;
3970    }
3971
3972    /**
3973     * Starts the "new version setup screen" if appropriate.
3974     */
3975    void startSetupActivityLocked() {
3976        // Only do this once per boot.
3977        if (mCheckedForSetup) {
3978            return;
3979        }
3980
3981        // We will show this screen if the current one is a different
3982        // version than the last one shown, and we are not running in
3983        // low-level factory test mode.
3984        final ContentResolver resolver = mContext.getContentResolver();
3985        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3986                Settings.Global.getInt(resolver,
3987                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3988            mCheckedForSetup = true;
3989
3990            // See if we should be showing the platform update setup UI.
3991            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3992            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3993                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3994            if (!ris.isEmpty()) {
3995                final ResolveInfo ri = ris.get(0);
3996                String vers = ri.activityInfo.metaData != null
3997                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3998                        : null;
3999                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4000                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4001                            Intent.METADATA_SETUP_VERSION);
4002                }
4003                String lastVers = Settings.Secure.getString(
4004                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4005                if (vers != null && !vers.equals(lastVers)) {
4006                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4007                    intent.setComponent(new ComponentName(
4008                            ri.activityInfo.packageName, ri.activityInfo.name));
4009                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4010                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4011                            null, 0, 0, 0, null, false, false, null, null, null);
4012                }
4013            }
4014        }
4015    }
4016
4017    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4018        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4019    }
4020
4021    void enforceNotIsolatedCaller(String caller) {
4022        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4023            throw new SecurityException("Isolated process not allowed to call " + caller);
4024        }
4025    }
4026
4027    void enforceShellRestriction(String restriction, int userHandle) {
4028        if (Binder.getCallingUid() == Process.SHELL_UID) {
4029            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4030                throw new SecurityException("Shell does not have permission to access user "
4031                        + userHandle);
4032            }
4033        }
4034    }
4035
4036    @Override
4037    public int getFrontActivityScreenCompatMode() {
4038        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4039        synchronized (this) {
4040            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4041        }
4042    }
4043
4044    @Override
4045    public void setFrontActivityScreenCompatMode(int mode) {
4046        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4047                "setFrontActivityScreenCompatMode");
4048        synchronized (this) {
4049            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4050        }
4051    }
4052
4053    @Override
4054    public int getPackageScreenCompatMode(String packageName) {
4055        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4056        synchronized (this) {
4057            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4058        }
4059    }
4060
4061    @Override
4062    public void setPackageScreenCompatMode(String packageName, int mode) {
4063        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4064                "setPackageScreenCompatMode");
4065        synchronized (this) {
4066            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4067        }
4068    }
4069
4070    @Override
4071    public boolean getPackageAskScreenCompat(String packageName) {
4072        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4073        synchronized (this) {
4074            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4075        }
4076    }
4077
4078    @Override
4079    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4080        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4081                "setPackageAskScreenCompat");
4082        synchronized (this) {
4083            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4084        }
4085    }
4086
4087    private boolean hasUsageStatsPermission(String callingPackage) {
4088        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4089                Binder.getCallingUid(), callingPackage);
4090        if (mode == AppOpsManager.MODE_DEFAULT) {
4091            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4092                    == PackageManager.PERMISSION_GRANTED;
4093        }
4094        return mode == AppOpsManager.MODE_ALLOWED;
4095    }
4096
4097    @Override
4098    public int getPackageProcessState(String packageName, String callingPackage) {
4099        if (!hasUsageStatsPermission(callingPackage)) {
4100            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4101                    "getPackageProcessState");
4102        }
4103
4104        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4105        synchronized (this) {
4106            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4107                final ProcessRecord proc = mLruProcesses.get(i);
4108                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4109                        || procState > proc.setProcState) {
4110                    boolean found = false;
4111                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4112                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4113                            procState = proc.setProcState;
4114                            found = true;
4115                        }
4116                    }
4117                    if (proc.pkgDeps != null && !found) {
4118                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4119                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4120                                procState = proc.setProcState;
4121                                break;
4122                            }
4123                        }
4124                    }
4125                }
4126            }
4127        }
4128        return procState;
4129    }
4130
4131    @Override
4132    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4133        synchronized (this) {
4134            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4135            if (app == null) {
4136                return false;
4137            }
4138            if (app.trimMemoryLevel < level && app.thread != null &&
4139                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4140                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4141                try {
4142                    app.thread.scheduleTrimMemory(level);
4143                    app.trimMemoryLevel = level;
4144                    return true;
4145                } catch (RemoteException e) {
4146                    // Fallthrough to failure case.
4147                }
4148            }
4149        }
4150        return false;
4151    }
4152
4153    private void dispatchProcessesChanged() {
4154        int N;
4155        synchronized (this) {
4156            N = mPendingProcessChanges.size();
4157            if (mActiveProcessChanges.length < N) {
4158                mActiveProcessChanges = new ProcessChangeItem[N];
4159            }
4160            mPendingProcessChanges.toArray(mActiveProcessChanges);
4161            mPendingProcessChanges.clear();
4162            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4163                    "*** Delivering " + N + " process changes");
4164        }
4165
4166        int i = mProcessObservers.beginBroadcast();
4167        while (i > 0) {
4168            i--;
4169            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4170            if (observer != null) {
4171                try {
4172                    for (int j=0; j<N; j++) {
4173                        ProcessChangeItem item = mActiveProcessChanges[j];
4174                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4175                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4176                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4177                                    + item.uid + ": " + item.foregroundActivities);
4178                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4179                                    item.foregroundActivities);
4180                        }
4181                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4182                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4183                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4184                                    + ": " + item.processState);
4185                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4186                        }
4187                    }
4188                } catch (RemoteException e) {
4189                }
4190            }
4191        }
4192        mProcessObservers.finishBroadcast();
4193
4194        synchronized (this) {
4195            for (int j=0; j<N; j++) {
4196                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4197            }
4198        }
4199    }
4200
4201    private void dispatchProcessDied(int pid, int uid) {
4202        int i = mProcessObservers.beginBroadcast();
4203        while (i > 0) {
4204            i--;
4205            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4206            if (observer != null) {
4207                try {
4208                    observer.onProcessDied(pid, uid);
4209                } catch (RemoteException e) {
4210                }
4211            }
4212        }
4213        mProcessObservers.finishBroadcast();
4214    }
4215
4216    private void dispatchUidsChanged() {
4217        int N;
4218        synchronized (this) {
4219            N = mPendingUidChanges.size();
4220            if (mActiveUidChanges.length < N) {
4221                mActiveUidChanges = new UidRecord.ChangeItem[N];
4222            }
4223            for (int i=0; i<N; i++) {
4224                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4225                mActiveUidChanges[i] = change;
4226                if (change.uidRecord != null) {
4227                    change.uidRecord.pendingChange = null;
4228                    change.uidRecord = null;
4229                }
4230            }
4231            mPendingUidChanges.clear();
4232            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4233                    "*** Delivering " + N + " uid changes");
4234        }
4235
4236        if (mLocalPowerManager != null) {
4237            for (int j=0; j<N; j++) {
4238                UidRecord.ChangeItem item = mActiveUidChanges[j];
4239                if (item.change == UidRecord.CHANGE_GONE
4240                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4241                    mLocalPowerManager.uidGone(item.uid);
4242                } else {
4243                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4244                }
4245            }
4246        }
4247
4248        int i = mUidObservers.beginBroadcast();
4249        while (i > 0) {
4250            i--;
4251            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4252            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4253            if (observer != null) {
4254                try {
4255                    for (int j=0; j<N; j++) {
4256                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4257                        final int change = item.change;
4258                        UidRecord validateUid = null;
4259                        if (VALIDATE_UID_STATES && i == 0) {
4260                            validateUid = mValidateUids.get(item.uid);
4261                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4262                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4263                                validateUid = new UidRecord(item.uid);
4264                                mValidateUids.put(item.uid, validateUid);
4265                            }
4266                        }
4267                        if (change == UidRecord.CHANGE_IDLE
4268                                || change == UidRecord.CHANGE_GONE_IDLE) {
4269                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4270                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4271                                        "UID idle uid=" + item.uid);
4272                                observer.onUidIdle(item.uid);
4273                            }
4274                            if (VALIDATE_UID_STATES && i == 0) {
4275                                if (validateUid != null) {
4276                                    validateUid.idle = true;
4277                                }
4278                            }
4279                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4280                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4281                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4282                                        "UID active uid=" + item.uid);
4283                                observer.onUidActive(item.uid);
4284                            }
4285                            if (VALIDATE_UID_STATES && i == 0) {
4286                                validateUid.idle = false;
4287                            }
4288                        }
4289                        if (change == UidRecord.CHANGE_GONE
4290                                || change == UidRecord.CHANGE_GONE_IDLE) {
4291                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4292                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4293                                        "UID gone uid=" + item.uid);
4294                                observer.onUidGone(item.uid);
4295                            }
4296                            if (VALIDATE_UID_STATES && i == 0) {
4297                                if (validateUid != null) {
4298                                    mValidateUids.remove(item.uid);
4299                                }
4300                            }
4301                        } else {
4302                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4303                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4304                                        "UID CHANGED uid=" + item.uid
4305                                                + ": " + item.processState);
4306                                observer.onUidStateChanged(item.uid, item.processState);
4307                            }
4308                            if (VALIDATE_UID_STATES && i == 0) {
4309                                validateUid.curProcState = validateUid.setProcState
4310                                        = item.processState;
4311                            }
4312                        }
4313                    }
4314                } catch (RemoteException e) {
4315                }
4316            }
4317        }
4318        mUidObservers.finishBroadcast();
4319
4320        synchronized (this) {
4321            for (int j=0; j<N; j++) {
4322                mAvailUidChanges.add(mActiveUidChanges[j]);
4323            }
4324        }
4325    }
4326
4327    @Override
4328    public final int startActivity(IApplicationThread caller, String callingPackage,
4329            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4330            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4331        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4332                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4333                UserHandle.getCallingUserId());
4334    }
4335
4336    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4337        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4338        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4339                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4340                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4341
4342        // TODO: Switch to user app stacks here.
4343        String mimeType = intent.getType();
4344        final Uri data = intent.getData();
4345        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4346            mimeType = getProviderMimeType(data, userId);
4347        }
4348        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4349
4350        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4351        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4352                null, 0, 0, null, null, null, null, false, userId, container, null);
4353    }
4354
4355    @Override
4356    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4357            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4358            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4359        enforceNotIsolatedCaller("startActivity");
4360        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4361                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4362        // TODO: Switch to user app stacks here.
4363        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4364                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4365                profilerInfo, null, null, bOptions, false, userId, null, null);
4366    }
4367
4368    @Override
4369    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4370            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4371            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4372            int userId) {
4373
4374        // This is very dangerous -- it allows you to perform a start activity (including
4375        // permission grants) as any app that may launch one of your own activities.  So
4376        // we will only allow this to be done from activities that are part of the core framework,
4377        // and then only when they are running as the system.
4378        final ActivityRecord sourceRecord;
4379        final int targetUid;
4380        final String targetPackage;
4381        synchronized (this) {
4382            if (resultTo == null) {
4383                throw new SecurityException("Must be called from an activity");
4384            }
4385            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4386            if (sourceRecord == null) {
4387                throw new SecurityException("Called with bad activity token: " + resultTo);
4388            }
4389            if (!sourceRecord.info.packageName.equals("android")) {
4390                throw new SecurityException(
4391                        "Must be called from an activity that is declared in the android package");
4392            }
4393            if (sourceRecord.app == null) {
4394                throw new SecurityException("Called without a process attached to activity");
4395            }
4396            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4397                // This is still okay, as long as this activity is running under the
4398                // uid of the original calling activity.
4399                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4400                    throw new SecurityException(
4401                            "Calling activity in uid " + sourceRecord.app.uid
4402                                    + " must be system uid or original calling uid "
4403                                    + sourceRecord.launchedFromUid);
4404                }
4405            }
4406            if (ignoreTargetSecurity) {
4407                if (intent.getComponent() == null) {
4408                    throw new SecurityException(
4409                            "Component must be specified with ignoreTargetSecurity");
4410                }
4411                if (intent.getSelector() != null) {
4412                    throw new SecurityException(
4413                            "Selector not allowed with ignoreTargetSecurity");
4414                }
4415            }
4416            targetUid = sourceRecord.launchedFromUid;
4417            targetPackage = sourceRecord.launchedFromPackage;
4418        }
4419
4420        if (userId == UserHandle.USER_NULL) {
4421            userId = UserHandle.getUserId(sourceRecord.app.uid);
4422        }
4423
4424        // TODO: Switch to user app stacks here.
4425        try {
4426            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4427                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4428                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4429            return ret;
4430        } catch (SecurityException e) {
4431            // XXX need to figure out how to propagate to original app.
4432            // A SecurityException here is generally actually a fault of the original
4433            // calling activity (such as a fairly granting permissions), so propagate it
4434            // back to them.
4435            /*
4436            StringBuilder msg = new StringBuilder();
4437            msg.append("While launching");
4438            msg.append(intent.toString());
4439            msg.append(": ");
4440            msg.append(e.getMessage());
4441            */
4442            throw e;
4443        }
4444    }
4445
4446    @Override
4447    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4448            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4449            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4450        enforceNotIsolatedCaller("startActivityAndWait");
4451        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4452                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4453        WaitResult res = new WaitResult();
4454        // TODO: Switch to user app stacks here.
4455        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4456                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4457                bOptions, false, userId, null, null);
4458        return res;
4459    }
4460
4461    @Override
4462    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4463            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4464            int startFlags, Configuration config, Bundle bOptions, int userId) {
4465        enforceNotIsolatedCaller("startActivityWithConfig");
4466        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4467                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4468        // TODO: Switch to user app stacks here.
4469        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4470                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4471                null, null, config, bOptions, false, userId, null, null);
4472        return ret;
4473    }
4474
4475    @Override
4476    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4477            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4478            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4479            throws TransactionTooLargeException {
4480        enforceNotIsolatedCaller("startActivityIntentSender");
4481        // Refuse possible leaked file descriptors
4482        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4483            throw new IllegalArgumentException("File descriptors passed in Intent");
4484        }
4485
4486        IIntentSender sender = intent.getTarget();
4487        if (!(sender instanceof PendingIntentRecord)) {
4488            throw new IllegalArgumentException("Bad PendingIntent object");
4489        }
4490
4491        PendingIntentRecord pir = (PendingIntentRecord)sender;
4492
4493        synchronized (this) {
4494            // If this is coming from the currently resumed activity, it is
4495            // effectively saying that app switches are allowed at this point.
4496            final ActivityStack stack = getFocusedStack();
4497            if (stack.mResumedActivity != null &&
4498                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4499                mAppSwitchesAllowedTime = 0;
4500            }
4501        }
4502        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4503                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4504        return ret;
4505    }
4506
4507    @Override
4508    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4509            Intent intent, String resolvedType, IVoiceInteractionSession session,
4510            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4511            Bundle bOptions, int userId) {
4512        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4513                != PackageManager.PERMISSION_GRANTED) {
4514            String msg = "Permission Denial: startVoiceActivity() from pid="
4515                    + Binder.getCallingPid()
4516                    + ", uid=" + Binder.getCallingUid()
4517                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4518            Slog.w(TAG, msg);
4519            throw new SecurityException(msg);
4520        }
4521        if (session == null || interactor == null) {
4522            throw new NullPointerException("null session or interactor");
4523        }
4524        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4525                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4526        // TODO: Switch to user app stacks here.
4527        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4528                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4529                null, bOptions, false, userId, null, null);
4530    }
4531
4532    @Override
4533    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4534            throws RemoteException {
4535        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4536        synchronized (this) {
4537            ActivityRecord activity = getFocusedStack().topActivity();
4538            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4539                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4540            }
4541            if (mRunningVoice != null || activity.task.voiceSession != null
4542                    || activity.voiceSession != null) {
4543                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4544                return;
4545            }
4546            if (activity.pendingVoiceInteractionStart) {
4547                Slog.w(TAG, "Pending start of voice interaction already.");
4548                return;
4549            }
4550            activity.pendingVoiceInteractionStart = true;
4551        }
4552        LocalServices.getService(VoiceInteractionManagerInternal.class)
4553                .startLocalVoiceInteraction(callingActivity, options);
4554    }
4555
4556    @Override
4557    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4558        LocalServices.getService(VoiceInteractionManagerInternal.class)
4559                .stopLocalVoiceInteraction(callingActivity);
4560    }
4561
4562    @Override
4563    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4564        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4565                .supportsLocalVoiceInteraction();
4566    }
4567
4568    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4569            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4570        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4571        if (activityToCallback == null) return;
4572        activityToCallback.setVoiceSessionLocked(voiceSession);
4573
4574        // Inform the activity
4575        try {
4576            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4577                    voiceInteractor);
4578            long token = Binder.clearCallingIdentity();
4579            try {
4580                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4581            } finally {
4582                Binder.restoreCallingIdentity(token);
4583            }
4584            // TODO: VI Should we cache the activity so that it's easier to find later
4585            // rather than scan through all the stacks and activities?
4586        } catch (RemoteException re) {
4587            activityToCallback.clearVoiceSessionLocked();
4588            // TODO: VI Should this terminate the voice session?
4589        }
4590    }
4591
4592    @Override
4593    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4594        synchronized (this) {
4595            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4596                if (keepAwake) {
4597                    mVoiceWakeLock.acquire();
4598                } else {
4599                    mVoiceWakeLock.release();
4600                }
4601            }
4602        }
4603    }
4604
4605    @Override
4606    public boolean startNextMatchingActivity(IBinder callingActivity,
4607            Intent intent, Bundle bOptions) {
4608        // Refuse possible leaked file descriptors
4609        if (intent != null && intent.hasFileDescriptors() == true) {
4610            throw new IllegalArgumentException("File descriptors passed in Intent");
4611        }
4612        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4613
4614        synchronized (this) {
4615            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4616            if (r == null) {
4617                ActivityOptions.abort(options);
4618                return false;
4619            }
4620            if (r.app == null || r.app.thread == null) {
4621                // The caller is not running...  d'oh!
4622                ActivityOptions.abort(options);
4623                return false;
4624            }
4625            intent = new Intent(intent);
4626            // The caller is not allowed to change the data.
4627            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4628            // And we are resetting to find the next component...
4629            intent.setComponent(null);
4630
4631            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4632
4633            ActivityInfo aInfo = null;
4634            try {
4635                List<ResolveInfo> resolves =
4636                    AppGlobals.getPackageManager().queryIntentActivities(
4637                            intent, r.resolvedType,
4638                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4639                            UserHandle.getCallingUserId()).getList();
4640
4641                // Look for the original activity in the list...
4642                final int N = resolves != null ? resolves.size() : 0;
4643                for (int i=0; i<N; i++) {
4644                    ResolveInfo rInfo = resolves.get(i);
4645                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4646                            && rInfo.activityInfo.name.equals(r.info.name)) {
4647                        // We found the current one...  the next matching is
4648                        // after it.
4649                        i++;
4650                        if (i<N) {
4651                            aInfo = resolves.get(i).activityInfo;
4652                        }
4653                        if (debug) {
4654                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4655                                    + "/" + r.info.name);
4656                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4657                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4658                        }
4659                        break;
4660                    }
4661                }
4662            } catch (RemoteException e) {
4663            }
4664
4665            if (aInfo == null) {
4666                // Nobody who is next!
4667                ActivityOptions.abort(options);
4668                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4669                return false;
4670            }
4671
4672            intent.setComponent(new ComponentName(
4673                    aInfo.applicationInfo.packageName, aInfo.name));
4674            intent.setFlags(intent.getFlags()&~(
4675                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4676                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4677                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4678                    Intent.FLAG_ACTIVITY_NEW_TASK));
4679
4680            // Okay now we need to start the new activity, replacing the
4681            // currently running activity.  This is a little tricky because
4682            // we want to start the new one as if the current one is finished,
4683            // but not finish the current one first so that there is no flicker.
4684            // And thus...
4685            final boolean wasFinishing = r.finishing;
4686            r.finishing = true;
4687
4688            // Propagate reply information over to the new activity.
4689            final ActivityRecord resultTo = r.resultTo;
4690            final String resultWho = r.resultWho;
4691            final int requestCode = r.requestCode;
4692            r.resultTo = null;
4693            if (resultTo != null) {
4694                resultTo.removeResultsLocked(r, resultWho, requestCode);
4695            }
4696
4697            final long origId = Binder.clearCallingIdentity();
4698            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4699                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4700                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4701                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4702                    false, false, null, null, null);
4703            Binder.restoreCallingIdentity(origId);
4704
4705            r.finishing = wasFinishing;
4706            if (res != ActivityManager.START_SUCCESS) {
4707                return false;
4708            }
4709            return true;
4710        }
4711    }
4712
4713    @Override
4714    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4715        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4716            String msg = "Permission Denial: startActivityFromRecents called without " +
4717                    START_TASKS_FROM_RECENTS;
4718            Slog.w(TAG, msg);
4719            throw new SecurityException(msg);
4720        }
4721        final long origId = Binder.clearCallingIdentity();
4722        try {
4723            synchronized (this) {
4724                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4725            }
4726        } finally {
4727            Binder.restoreCallingIdentity(origId);
4728        }
4729    }
4730
4731    final int startActivityInPackage(int uid, String callingPackage,
4732            Intent intent, String resolvedType, IBinder resultTo,
4733            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4734            IActivityContainer container, TaskRecord inTask) {
4735
4736        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4737                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4738
4739        // TODO: Switch to user app stacks here.
4740        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4741                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4742                null, null, null, bOptions, false, userId, container, inTask);
4743        return ret;
4744    }
4745
4746    @Override
4747    public final int startActivities(IApplicationThread caller, String callingPackage,
4748            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4749            int userId) {
4750        enforceNotIsolatedCaller("startActivities");
4751        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4752                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4753        // TODO: Switch to user app stacks here.
4754        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4755                resolvedTypes, resultTo, bOptions, userId);
4756        return ret;
4757    }
4758
4759    final int startActivitiesInPackage(int uid, String callingPackage,
4760            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4761            Bundle bOptions, int userId) {
4762
4763        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4764                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4765        // TODO: Switch to user app stacks here.
4766        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4767                resultTo, bOptions, userId);
4768        return ret;
4769    }
4770
4771    @Override
4772    public void reportActivityFullyDrawn(IBinder token) {
4773        synchronized (this) {
4774            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4775            if (r == null) {
4776                return;
4777            }
4778            r.reportFullyDrawnLocked();
4779        }
4780    }
4781
4782    @Override
4783    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4784        synchronized (this) {
4785            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4786            if (r == null) {
4787                return;
4788            }
4789            TaskRecord task = r.task;
4790            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4791                // Fixed screen orientation isn't supported when activities aren't in full screen
4792                // mode.
4793                return;
4794            }
4795            final long origId = Binder.clearCallingIdentity();
4796            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4797            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4798                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4799            if (config != null) {
4800                r.frozenBeforeDestroy = true;
4801                if (!updateConfigurationLocked(config, r, false)) {
4802                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4803                }
4804            }
4805            Binder.restoreCallingIdentity(origId);
4806        }
4807    }
4808
4809    @Override
4810    public int getRequestedOrientation(IBinder token) {
4811        synchronized (this) {
4812            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4813            if (r == null) {
4814                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4815            }
4816            return mWindowManager.getAppOrientation(r.appToken);
4817        }
4818    }
4819
4820    /**
4821     * This is the internal entry point for handling Activity.finish().
4822     *
4823     * @param token The Binder token referencing the Activity we want to finish.
4824     * @param resultCode Result code, if any, from this Activity.
4825     * @param resultData Result data (Intent), if any, from this Activity.
4826     * @param finishTask Whether to finish the task associated with this Activity.
4827     *
4828     * @return Returns true if the activity successfully finished, or false if it is still running.
4829     */
4830    @Override
4831    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4832            int finishTask) {
4833        // Refuse possible leaked file descriptors
4834        if (resultData != null && resultData.hasFileDescriptors() == true) {
4835            throw new IllegalArgumentException("File descriptors passed in Intent");
4836        }
4837
4838        synchronized(this) {
4839            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4840            if (r == null) {
4841                return true;
4842            }
4843            // Keep track of the root activity of the task before we finish it
4844            TaskRecord tr = r.task;
4845            ActivityRecord rootR = tr.getRootActivity();
4846            if (rootR == null) {
4847                Slog.w(TAG, "Finishing task with all activities already finished");
4848            }
4849            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4850            // finish.
4851            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4852                    mStackSupervisor.isLastLockedTask(tr)) {
4853                Slog.i(TAG, "Not finishing task in lock task mode");
4854                mStackSupervisor.showLockTaskToast();
4855                return false;
4856            }
4857            if (mController != null) {
4858                // Find the first activity that is not finishing.
4859                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4860                if (next != null) {
4861                    // ask watcher if this is allowed
4862                    boolean resumeOK = true;
4863                    try {
4864                        resumeOK = mController.activityResuming(next.packageName);
4865                    } catch (RemoteException e) {
4866                        mController = null;
4867                        Watchdog.getInstance().setActivityController(null);
4868                    }
4869
4870                    if (!resumeOK) {
4871                        Slog.i(TAG, "Not finishing activity because controller resumed");
4872                        return false;
4873                    }
4874                }
4875            }
4876            final long origId = Binder.clearCallingIdentity();
4877            try {
4878                boolean res;
4879                final boolean finishWithRootActivity =
4880                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4881                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4882                        || (finishWithRootActivity && r == rootR)) {
4883                    // If requested, remove the task that is associated to this activity only if it
4884                    // was the root activity in the task. The result code and data is ignored
4885                    // because we don't support returning them across task boundaries. Also, to
4886                    // keep backwards compatibility we remove the task from recents when finishing
4887                    // task with root activity.
4888                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4889                    if (!res) {
4890                        Slog.i(TAG, "Removing task failed to finish activity");
4891                    }
4892                } else {
4893                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4894                            resultData, "app-request", true);
4895                    if (!res) {
4896                        Slog.i(TAG, "Failed to finish by app-request");
4897                    }
4898                }
4899                return res;
4900            } finally {
4901                Binder.restoreCallingIdentity(origId);
4902            }
4903        }
4904    }
4905
4906    @Override
4907    public final void finishHeavyWeightApp() {
4908        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4909                != PackageManager.PERMISSION_GRANTED) {
4910            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4911                    + Binder.getCallingPid()
4912                    + ", uid=" + Binder.getCallingUid()
4913                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4914            Slog.w(TAG, msg);
4915            throw new SecurityException(msg);
4916        }
4917
4918        synchronized(this) {
4919            if (mHeavyWeightProcess == null) {
4920                return;
4921            }
4922
4923            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4924            for (int i = 0; i < activities.size(); i++) {
4925                ActivityRecord r = activities.get(i);
4926                if (!r.finishing && r.isInStackLocked()) {
4927                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4928                            null, "finish-heavy", true);
4929                }
4930            }
4931
4932            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4933                    mHeavyWeightProcess.userId, 0));
4934            mHeavyWeightProcess = null;
4935        }
4936    }
4937
4938    @Override
4939    public void crashApplication(int uid, int initialPid, String packageName,
4940            String message) {
4941        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4942                != PackageManager.PERMISSION_GRANTED) {
4943            String msg = "Permission Denial: crashApplication() from pid="
4944                    + Binder.getCallingPid()
4945                    + ", uid=" + Binder.getCallingUid()
4946                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4947            Slog.w(TAG, msg);
4948            throw new SecurityException(msg);
4949        }
4950
4951        synchronized(this) {
4952            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4953        }
4954    }
4955
4956    @Override
4957    public final void finishSubActivity(IBinder token, String resultWho,
4958            int requestCode) {
4959        synchronized(this) {
4960            final long origId = Binder.clearCallingIdentity();
4961            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4962            if (r != null) {
4963                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4964            }
4965            Binder.restoreCallingIdentity(origId);
4966        }
4967    }
4968
4969    @Override
4970    public boolean finishActivityAffinity(IBinder token) {
4971        synchronized(this) {
4972            final long origId = Binder.clearCallingIdentity();
4973            try {
4974                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4975                if (r == null) {
4976                    return false;
4977                }
4978
4979                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4980                // can finish.
4981                final TaskRecord task = r.task;
4982                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4983                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4984                    mStackSupervisor.showLockTaskToast();
4985                    return false;
4986                }
4987                return task.stack.finishActivityAffinityLocked(r);
4988            } finally {
4989                Binder.restoreCallingIdentity(origId);
4990            }
4991        }
4992    }
4993
4994    @Override
4995    public void finishVoiceTask(IVoiceInteractionSession session) {
4996        synchronized (this) {
4997            final long origId = Binder.clearCallingIdentity();
4998            try {
4999                // TODO: VI Consider treating local voice interactions and voice tasks
5000                // differently here
5001                mStackSupervisor.finishVoiceTask(session);
5002            } finally {
5003                Binder.restoreCallingIdentity(origId);
5004            }
5005        }
5006
5007    }
5008
5009    @Override
5010    public boolean releaseActivityInstance(IBinder token) {
5011        synchronized(this) {
5012            final long origId = Binder.clearCallingIdentity();
5013            try {
5014                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5015                if (r == null) {
5016                    return false;
5017                }
5018                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5019            } finally {
5020                Binder.restoreCallingIdentity(origId);
5021            }
5022        }
5023    }
5024
5025    @Override
5026    public void releaseSomeActivities(IApplicationThread appInt) {
5027        synchronized(this) {
5028            final long origId = Binder.clearCallingIdentity();
5029            try {
5030                ProcessRecord app = getRecordForAppLocked(appInt);
5031                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5032            } finally {
5033                Binder.restoreCallingIdentity(origId);
5034            }
5035        }
5036    }
5037
5038    @Override
5039    public boolean willActivityBeVisible(IBinder token) {
5040        synchronized(this) {
5041            ActivityStack stack = ActivityRecord.getStackLocked(token);
5042            if (stack != null) {
5043                return stack.willActivityBeVisibleLocked(token);
5044            }
5045            return false;
5046        }
5047    }
5048
5049    @Override
5050    public void overridePendingTransition(IBinder token, String packageName,
5051            int enterAnim, int exitAnim) {
5052        synchronized(this) {
5053            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5054            if (self == null) {
5055                return;
5056            }
5057
5058            final long origId = Binder.clearCallingIdentity();
5059
5060            if (self.state == ActivityState.RESUMED
5061                    || self.state == ActivityState.PAUSING) {
5062                mWindowManager.overridePendingAppTransition(packageName,
5063                        enterAnim, exitAnim, null);
5064            }
5065
5066            Binder.restoreCallingIdentity(origId);
5067        }
5068    }
5069
5070    /**
5071     * Main function for removing an existing process from the activity manager
5072     * as a result of that process going away.  Clears out all connections
5073     * to the process.
5074     */
5075    private final void handleAppDiedLocked(ProcessRecord app,
5076            boolean restarting, boolean allowRestart) {
5077        int pid = app.pid;
5078        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5079                false /*replacingPid*/);
5080        if (!kept && !restarting) {
5081            removeLruProcessLocked(app);
5082            if (pid > 0) {
5083                ProcessList.remove(pid);
5084            }
5085        }
5086
5087        if (mProfileProc == app) {
5088            clearProfilerLocked();
5089        }
5090
5091        // Remove this application's activities from active lists.
5092        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5093
5094        app.activities.clear();
5095
5096        if (app.instrumentationClass != null) {
5097            Slog.w(TAG, "Crash of app " + app.processName
5098                  + " running instrumentation " + app.instrumentationClass);
5099            Bundle info = new Bundle();
5100            info.putString("shortMsg", "Process crashed.");
5101            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5102        }
5103
5104        if (!restarting && hasVisibleActivities
5105                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5106            // If there was nothing to resume, and we are not already restarting this process, but
5107            // there is a visible activity that is hosted by the process...  then make sure all
5108            // visible activities are running, taking care of restarting this process.
5109            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5110        }
5111    }
5112
5113    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5114        IBinder threadBinder = thread.asBinder();
5115        // Find the application record.
5116        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5117            ProcessRecord rec = mLruProcesses.get(i);
5118            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5119                return i;
5120            }
5121        }
5122        return -1;
5123    }
5124
5125    final ProcessRecord getRecordForAppLocked(
5126            IApplicationThread thread) {
5127        if (thread == null) {
5128            return null;
5129        }
5130
5131        int appIndex = getLRURecordIndexForAppLocked(thread);
5132        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5133    }
5134
5135    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5136        // If there are no longer any background processes running,
5137        // and the app that died was not running instrumentation,
5138        // then tell everyone we are now low on memory.
5139        boolean haveBg = false;
5140        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5141            ProcessRecord rec = mLruProcesses.get(i);
5142            if (rec.thread != null
5143                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5144                haveBg = true;
5145                break;
5146            }
5147        }
5148
5149        if (!haveBg) {
5150            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5151            if (doReport) {
5152                long now = SystemClock.uptimeMillis();
5153                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5154                    doReport = false;
5155                } else {
5156                    mLastMemUsageReportTime = now;
5157                }
5158            }
5159            final ArrayList<ProcessMemInfo> memInfos
5160                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5161            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5162            long now = SystemClock.uptimeMillis();
5163            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5164                ProcessRecord rec = mLruProcesses.get(i);
5165                if (rec == dyingProc || rec.thread == null) {
5166                    continue;
5167                }
5168                if (doReport) {
5169                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5170                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5171                }
5172                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5173                    // The low memory report is overriding any current
5174                    // state for a GC request.  Make sure to do
5175                    // heavy/important/visible/foreground processes first.
5176                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5177                        rec.lastRequestedGc = 0;
5178                    } else {
5179                        rec.lastRequestedGc = rec.lastLowMemory;
5180                    }
5181                    rec.reportLowMemory = true;
5182                    rec.lastLowMemory = now;
5183                    mProcessesToGc.remove(rec);
5184                    addProcessToGcListLocked(rec);
5185                }
5186            }
5187            if (doReport) {
5188                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5189                mHandler.sendMessage(msg);
5190            }
5191            scheduleAppGcsLocked();
5192        }
5193    }
5194
5195    final void appDiedLocked(ProcessRecord app) {
5196       appDiedLocked(app, app.pid, app.thread, false);
5197    }
5198
5199    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5200            boolean fromBinderDied) {
5201        // First check if this ProcessRecord is actually active for the pid.
5202        synchronized (mPidsSelfLocked) {
5203            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5204            if (curProc != app) {
5205                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5206                return;
5207            }
5208        }
5209
5210        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5211        synchronized (stats) {
5212            stats.noteProcessDiedLocked(app.info.uid, pid);
5213        }
5214
5215        if (!app.killed) {
5216            if (!fromBinderDied) {
5217                Process.killProcessQuiet(pid);
5218            }
5219            killProcessGroup(app.uid, pid);
5220            app.killed = true;
5221        }
5222
5223        // Clean up already done if the process has been re-started.
5224        if (app.pid == pid && app.thread != null &&
5225                app.thread.asBinder() == thread.asBinder()) {
5226            boolean doLowMem = app.instrumentationClass == null;
5227            boolean doOomAdj = doLowMem;
5228            if (!app.killedByAm) {
5229                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5230                        + ") has died");
5231                mAllowLowerMemLevel = true;
5232            } else {
5233                // Note that we always want to do oom adj to update our state with the
5234                // new number of procs.
5235                mAllowLowerMemLevel = false;
5236                doLowMem = false;
5237            }
5238            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5239            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5240                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5241            handleAppDiedLocked(app, false, true);
5242
5243            if (doOomAdj) {
5244                updateOomAdjLocked();
5245            }
5246            if (doLowMem) {
5247                doLowMemReportIfNeededLocked(app);
5248            }
5249        } else if (app.pid != pid) {
5250            // A new process has already been started.
5251            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5252                    + ") has died and restarted (pid " + app.pid + ").");
5253            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5254        } else if (DEBUG_PROCESSES) {
5255            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5256                    + thread.asBinder());
5257        }
5258    }
5259
5260    /**
5261     * If a stack trace dump file is configured, dump process stack traces.
5262     * @param clearTraces causes the dump file to be erased prior to the new
5263     *    traces being written, if true; when false, the new traces will be
5264     *    appended to any existing file content.
5265     * @param firstPids of dalvik VM processes to dump stack traces for first
5266     * @param lastPids of dalvik VM processes to dump stack traces for last
5267     * @param nativeProcs optional list of native process names to dump stack crawls
5268     * @return file containing stack traces, or null if no dump file is configured
5269     */
5270    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5271            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5272        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5273        if (tracesPath == null || tracesPath.length() == 0) {
5274            return null;
5275        }
5276
5277        File tracesFile = new File(tracesPath);
5278        try {
5279            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5280            tracesFile.createNewFile();
5281            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5282        } catch (IOException e) {
5283            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5284            return null;
5285        }
5286
5287        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5288        return tracesFile;
5289    }
5290
5291    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5292            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5293        // Use a FileObserver to detect when traces finish writing.
5294        // The order of traces is considered important to maintain for legibility.
5295        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5296            @Override
5297            public synchronized void onEvent(int event, String path) { notify(); }
5298        };
5299
5300        try {
5301            observer.startWatching();
5302
5303            // First collect all of the stacks of the most important pids.
5304            if (firstPids != null) {
5305                try {
5306                    int num = firstPids.size();
5307                    for (int i = 0; i < num; i++) {
5308                        synchronized (observer) {
5309                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5310                                    + firstPids.get(i));
5311                            final long sime = SystemClock.elapsedRealtime();
5312                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5313                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5314                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5315                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5316                        }
5317                    }
5318                } catch (InterruptedException e) {
5319                    Slog.wtf(TAG, e);
5320                }
5321            }
5322
5323            // Next collect the stacks of the native pids
5324            if (nativeProcs != null) {
5325                int[] pids = Process.getPidsForCommands(nativeProcs);
5326                if (pids != null) {
5327                    for (int pid : pids) {
5328                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5329                        final long sime = SystemClock.elapsedRealtime();
5330                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5331                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5332                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5333                    }
5334                }
5335            }
5336
5337            // Lastly, measure CPU usage.
5338            if (processCpuTracker != null) {
5339                processCpuTracker.init();
5340                System.gc();
5341                processCpuTracker.update();
5342                try {
5343                    synchronized (processCpuTracker) {
5344                        processCpuTracker.wait(500); // measure over 1/2 second.
5345                    }
5346                } catch (InterruptedException e) {
5347                }
5348                processCpuTracker.update();
5349
5350                // We'll take the stack crawls of just the top apps using CPU.
5351                final int N = processCpuTracker.countWorkingStats();
5352                int numProcs = 0;
5353                for (int i=0; i<N && numProcs<5; i++) {
5354                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5355                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5356                        numProcs++;
5357                        try {
5358                            synchronized (observer) {
5359                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5360                                        + stats.pid);
5361                                final long stime = SystemClock.elapsedRealtime();
5362                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5363                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5364                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5365                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5366                            }
5367                        } catch (InterruptedException e) {
5368                            Slog.wtf(TAG, e);
5369                        }
5370                    } else if (DEBUG_ANR) {
5371                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5372                                + stats.pid);
5373                    }
5374                }
5375            }
5376        } finally {
5377            observer.stopWatching();
5378        }
5379    }
5380
5381    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5382        if (true || IS_USER_BUILD) {
5383            return;
5384        }
5385        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5386        if (tracesPath == null || tracesPath.length() == 0) {
5387            return;
5388        }
5389
5390        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5391        StrictMode.allowThreadDiskWrites();
5392        try {
5393            final File tracesFile = new File(tracesPath);
5394            final File tracesDir = tracesFile.getParentFile();
5395            final File tracesTmp = new File(tracesDir, "__tmp__");
5396            try {
5397                if (tracesFile.exists()) {
5398                    tracesTmp.delete();
5399                    tracesFile.renameTo(tracesTmp);
5400                }
5401                StringBuilder sb = new StringBuilder();
5402                Time tobj = new Time();
5403                tobj.set(System.currentTimeMillis());
5404                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5405                sb.append(": ");
5406                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5407                sb.append(" since ");
5408                sb.append(msg);
5409                FileOutputStream fos = new FileOutputStream(tracesFile);
5410                fos.write(sb.toString().getBytes());
5411                if (app == null) {
5412                    fos.write("\n*** No application process!".getBytes());
5413                }
5414                fos.close();
5415                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5416            } catch (IOException e) {
5417                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5418                return;
5419            }
5420
5421            if (app != null) {
5422                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5423                firstPids.add(app.pid);
5424                dumpStackTraces(tracesPath, firstPids, null, null, null);
5425            }
5426
5427            File lastTracesFile = null;
5428            File curTracesFile = null;
5429            for (int i=9; i>=0; i--) {
5430                String name = String.format(Locale.US, "slow%02d.txt", i);
5431                curTracesFile = new File(tracesDir, name);
5432                if (curTracesFile.exists()) {
5433                    if (lastTracesFile != null) {
5434                        curTracesFile.renameTo(lastTracesFile);
5435                    } else {
5436                        curTracesFile.delete();
5437                    }
5438                }
5439                lastTracesFile = curTracesFile;
5440            }
5441            tracesFile.renameTo(curTracesFile);
5442            if (tracesTmp.exists()) {
5443                tracesTmp.renameTo(tracesFile);
5444            }
5445        } finally {
5446            StrictMode.setThreadPolicy(oldPolicy);
5447        }
5448    }
5449
5450    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5451        if (!mLaunchWarningShown) {
5452            mLaunchWarningShown = true;
5453            mUiHandler.post(new Runnable() {
5454                @Override
5455                public void run() {
5456                    synchronized (ActivityManagerService.this) {
5457                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5458                        d.show();
5459                        mUiHandler.postDelayed(new Runnable() {
5460                            @Override
5461                            public void run() {
5462                                synchronized (ActivityManagerService.this) {
5463                                    d.dismiss();
5464                                    mLaunchWarningShown = false;
5465                                }
5466                            }
5467                        }, 4000);
5468                    }
5469                }
5470            });
5471        }
5472    }
5473
5474    @Override
5475    public boolean clearApplicationUserData(final String packageName,
5476            final IPackageDataObserver observer, int userId) {
5477        enforceNotIsolatedCaller("clearApplicationUserData");
5478        int uid = Binder.getCallingUid();
5479        int pid = Binder.getCallingPid();
5480        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5481                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5482
5483
5484        long callingId = Binder.clearCallingIdentity();
5485        try {
5486            IPackageManager pm = AppGlobals.getPackageManager();
5487            int pkgUid = -1;
5488            synchronized(this) {
5489                if (getPackageManagerInternalLocked().isPackageDataProtected(
5490                        userId, packageName)) {
5491                    throw new SecurityException(
5492                            "Cannot clear data for a protected package: " + packageName);
5493                }
5494
5495                try {
5496                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5497                } catch (RemoteException e) {
5498                }
5499                if (pkgUid == -1) {
5500                    Slog.w(TAG, "Invalid packageName: " + packageName);
5501                    if (observer != null) {
5502                        try {
5503                            observer.onRemoveCompleted(packageName, false);
5504                        } catch (RemoteException e) {
5505                            Slog.i(TAG, "Observer no longer exists.");
5506                        }
5507                    }
5508                    return false;
5509                }
5510                if (uid == pkgUid || checkComponentPermission(
5511                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5512                        pid, uid, -1, true)
5513                        == PackageManager.PERMISSION_GRANTED) {
5514                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5515                } else {
5516                    throw new SecurityException("PID " + pid + " does not have permission "
5517                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5518                                    + " of package " + packageName);
5519                }
5520
5521                // Remove all tasks match the cleared application package and user
5522                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5523                    final TaskRecord tr = mRecentTasks.get(i);
5524                    final String taskPackageName =
5525                            tr.getBaseIntent().getComponent().getPackageName();
5526                    if (tr.userId != userId) continue;
5527                    if (!taskPackageName.equals(packageName)) continue;
5528                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5529                }
5530            }
5531
5532            final int pkgUidF = pkgUid;
5533            final int userIdF = userId;
5534            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5535                @Override
5536                public void onRemoveCompleted(String packageName, boolean succeeded)
5537                        throws RemoteException {
5538                    synchronized (ActivityManagerService.this) {
5539                        finishForceStopPackageLocked(packageName, pkgUidF);
5540                    }
5541
5542                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5543                            Uri.fromParts("package", packageName, null));
5544                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5545                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5546                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5547                            null, null, 0, null, null, null, null, false, false, userIdF);
5548
5549                    if (observer != null) {
5550                        observer.onRemoveCompleted(packageName, succeeded);
5551                    }
5552                }
5553            };
5554
5555            try {
5556                // Clear application user data
5557                pm.clearApplicationUserData(packageName, localObserver, userId);
5558
5559                synchronized(this) {
5560                    // Remove all permissions granted from/to this package
5561                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5562                }
5563
5564                // Remove all zen rules created by this package; revoke it's zen access.
5565                INotificationManager inm = NotificationManager.getService();
5566                inm.removeAutomaticZenRules(packageName);
5567                inm.setNotificationPolicyAccessGranted(packageName, false);
5568
5569            } catch (RemoteException e) {
5570            }
5571        } finally {
5572            Binder.restoreCallingIdentity(callingId);
5573        }
5574        return true;
5575    }
5576
5577    @Override
5578    public void killBackgroundProcesses(final String packageName, int userId) {
5579        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5580                != PackageManager.PERMISSION_GRANTED &&
5581                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5582                        != PackageManager.PERMISSION_GRANTED) {
5583            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5584                    + Binder.getCallingPid()
5585                    + ", uid=" + Binder.getCallingUid()
5586                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5587            Slog.w(TAG, msg);
5588            throw new SecurityException(msg);
5589        }
5590
5591        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5592                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5593        long callingId = Binder.clearCallingIdentity();
5594        try {
5595            IPackageManager pm = AppGlobals.getPackageManager();
5596            synchronized(this) {
5597                int appId = -1;
5598                try {
5599                    appId = UserHandle.getAppId(
5600                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5601                } catch (RemoteException e) {
5602                }
5603                if (appId == -1) {
5604                    Slog.w(TAG, "Invalid packageName: " + packageName);
5605                    return;
5606                }
5607                killPackageProcessesLocked(packageName, appId, userId,
5608                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5609            }
5610        } finally {
5611            Binder.restoreCallingIdentity(callingId);
5612        }
5613    }
5614
5615    @Override
5616    public void killAllBackgroundProcesses() {
5617        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5618                != PackageManager.PERMISSION_GRANTED) {
5619            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5620                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5621                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5622            Slog.w(TAG, msg);
5623            throw new SecurityException(msg);
5624        }
5625
5626        final long callingId = Binder.clearCallingIdentity();
5627        try {
5628            synchronized (this) {
5629                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5630                final int NP = mProcessNames.getMap().size();
5631                for (int ip = 0; ip < NP; ip++) {
5632                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5633                    final int NA = apps.size();
5634                    for (int ia = 0; ia < NA; ia++) {
5635                        final ProcessRecord app = apps.valueAt(ia);
5636                        if (app.persistent) {
5637                            // We don't kill persistent processes.
5638                            continue;
5639                        }
5640                        if (app.removed) {
5641                            procs.add(app);
5642                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5643                            app.removed = true;
5644                            procs.add(app);
5645                        }
5646                    }
5647                }
5648
5649                final int N = procs.size();
5650                for (int i = 0; i < N; i++) {
5651                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5652                }
5653
5654                mAllowLowerMemLevel = true;
5655
5656                updateOomAdjLocked();
5657                doLowMemReportIfNeededLocked(null);
5658            }
5659        } finally {
5660            Binder.restoreCallingIdentity(callingId);
5661        }
5662    }
5663
5664    /**
5665     * Kills all background processes, except those matching any of the
5666     * specified properties.
5667     *
5668     * @param minTargetSdk the target SDK version at or above which to preserve
5669     *                     processes, or {@code -1} to ignore the target SDK
5670     * @param maxProcState the process state at or below which to preserve
5671     *                     processes, or {@code -1} to ignore the process state
5672     */
5673    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5674        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5675                != PackageManager.PERMISSION_GRANTED) {
5676            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5677                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5678                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5679            Slog.w(TAG, msg);
5680            throw new SecurityException(msg);
5681        }
5682
5683        final long callingId = Binder.clearCallingIdentity();
5684        try {
5685            synchronized (this) {
5686                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5687                final int NP = mProcessNames.getMap().size();
5688                for (int ip = 0; ip < NP; ip++) {
5689                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5690                    final int NA = apps.size();
5691                    for (int ia = 0; ia < NA; ia++) {
5692                        final ProcessRecord app = apps.valueAt(ia);
5693                        if (app.removed) {
5694                            procs.add(app);
5695                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5696                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5697                            app.removed = true;
5698                            procs.add(app);
5699                        }
5700                    }
5701                }
5702
5703                final int N = procs.size();
5704                for (int i = 0; i < N; i++) {
5705                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5706                }
5707            }
5708        } finally {
5709            Binder.restoreCallingIdentity(callingId);
5710        }
5711    }
5712
5713    @Override
5714    public void forceStopPackage(final String packageName, int userId) {
5715        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5716                != PackageManager.PERMISSION_GRANTED) {
5717            String msg = "Permission Denial: forceStopPackage() from pid="
5718                    + Binder.getCallingPid()
5719                    + ", uid=" + Binder.getCallingUid()
5720                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5721            Slog.w(TAG, msg);
5722            throw new SecurityException(msg);
5723        }
5724        final int callingPid = Binder.getCallingPid();
5725        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5726                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5727        long callingId = Binder.clearCallingIdentity();
5728        try {
5729            IPackageManager pm = AppGlobals.getPackageManager();
5730            synchronized(this) {
5731                int[] users = userId == UserHandle.USER_ALL
5732                        ? mUserController.getUsers() : new int[] { userId };
5733                for (int user : users) {
5734                    int pkgUid = -1;
5735                    try {
5736                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5737                                user);
5738                    } catch (RemoteException e) {
5739                    }
5740                    if (pkgUid == -1) {
5741                        Slog.w(TAG, "Invalid packageName: " + packageName);
5742                        continue;
5743                    }
5744                    try {
5745                        pm.setPackageStoppedState(packageName, true, user);
5746                    } catch (RemoteException e) {
5747                    } catch (IllegalArgumentException e) {
5748                        Slog.w(TAG, "Failed trying to unstop package "
5749                                + packageName + ": " + e);
5750                    }
5751                    if (mUserController.isUserRunningLocked(user, 0)) {
5752                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5753                        finishForceStopPackageLocked(packageName, pkgUid);
5754                    }
5755                }
5756            }
5757        } finally {
5758            Binder.restoreCallingIdentity(callingId);
5759        }
5760    }
5761
5762    @Override
5763    public void addPackageDependency(String packageName) {
5764        synchronized (this) {
5765            int callingPid = Binder.getCallingPid();
5766            if (callingPid == Process.myPid()) {
5767                //  Yeah, um, no.
5768                return;
5769            }
5770            ProcessRecord proc;
5771            synchronized (mPidsSelfLocked) {
5772                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5773            }
5774            if (proc != null) {
5775                if (proc.pkgDeps == null) {
5776                    proc.pkgDeps = new ArraySet<String>(1);
5777                }
5778                proc.pkgDeps.add(packageName);
5779            }
5780        }
5781    }
5782
5783    /*
5784     * The pkg name and app id have to be specified.
5785     */
5786    @Override
5787    public void killApplication(String pkg, int appId, int userId, String reason) {
5788        if (pkg == null) {
5789            return;
5790        }
5791        // Make sure the uid is valid.
5792        if (appId < 0) {
5793            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5794            return;
5795        }
5796        int callerUid = Binder.getCallingUid();
5797        // Only the system server can kill an application
5798        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5799            // Post an aysnc message to kill the application
5800            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5801            msg.arg1 = appId;
5802            msg.arg2 = userId;
5803            Bundle bundle = new Bundle();
5804            bundle.putString("pkg", pkg);
5805            bundle.putString("reason", reason);
5806            msg.obj = bundle;
5807            mHandler.sendMessage(msg);
5808        } else {
5809            throw new SecurityException(callerUid + " cannot kill pkg: " +
5810                    pkg);
5811        }
5812    }
5813
5814    @Override
5815    public void closeSystemDialogs(String reason) {
5816        enforceNotIsolatedCaller("closeSystemDialogs");
5817
5818        final int pid = Binder.getCallingPid();
5819        final int uid = Binder.getCallingUid();
5820        final long origId = Binder.clearCallingIdentity();
5821        try {
5822            synchronized (this) {
5823                // Only allow this from foreground processes, so that background
5824                // applications can't abuse it to prevent system UI from being shown.
5825                if (uid >= Process.FIRST_APPLICATION_UID) {
5826                    ProcessRecord proc;
5827                    synchronized (mPidsSelfLocked) {
5828                        proc = mPidsSelfLocked.get(pid);
5829                    }
5830                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5831                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5832                                + " from background process " + proc);
5833                        return;
5834                    }
5835                }
5836                closeSystemDialogsLocked(reason);
5837            }
5838        } finally {
5839            Binder.restoreCallingIdentity(origId);
5840        }
5841    }
5842
5843    void closeSystemDialogsLocked(String reason) {
5844        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5845        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5846                | Intent.FLAG_RECEIVER_FOREGROUND);
5847        if (reason != null) {
5848            intent.putExtra("reason", reason);
5849        }
5850        mWindowManager.closeSystemDialogs(reason);
5851
5852        mStackSupervisor.closeSystemDialogsLocked();
5853
5854        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5855                AppOpsManager.OP_NONE, null, false, false,
5856                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5857    }
5858
5859    @Override
5860    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5861        enforceNotIsolatedCaller("getProcessMemoryInfo");
5862        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5863        for (int i=pids.length-1; i>=0; i--) {
5864            ProcessRecord proc;
5865            int oomAdj;
5866            synchronized (this) {
5867                synchronized (mPidsSelfLocked) {
5868                    proc = mPidsSelfLocked.get(pids[i]);
5869                    oomAdj = proc != null ? proc.setAdj : 0;
5870                }
5871            }
5872            infos[i] = new Debug.MemoryInfo();
5873            Debug.getMemoryInfo(pids[i], infos[i]);
5874            if (proc != null) {
5875                synchronized (this) {
5876                    if (proc.thread != null && proc.setAdj == oomAdj) {
5877                        // Record this for posterity if the process has been stable.
5878                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5879                                infos[i].getTotalUss(), false, proc.pkgList);
5880                    }
5881                }
5882            }
5883        }
5884        return infos;
5885    }
5886
5887    @Override
5888    public long[] getProcessPss(int[] pids) {
5889        enforceNotIsolatedCaller("getProcessPss");
5890        long[] pss = new long[pids.length];
5891        for (int i=pids.length-1; i>=0; i--) {
5892            ProcessRecord proc;
5893            int oomAdj;
5894            synchronized (this) {
5895                synchronized (mPidsSelfLocked) {
5896                    proc = mPidsSelfLocked.get(pids[i]);
5897                    oomAdj = proc != null ? proc.setAdj : 0;
5898                }
5899            }
5900            long[] tmpUss = new long[1];
5901            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5902            if (proc != null) {
5903                synchronized (this) {
5904                    if (proc.thread != null && proc.setAdj == oomAdj) {
5905                        // Record this for posterity if the process has been stable.
5906                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5907                    }
5908                }
5909            }
5910        }
5911        return pss;
5912    }
5913
5914    @Override
5915    public void killApplicationProcess(String processName, int uid) {
5916        if (processName == null) {
5917            return;
5918        }
5919
5920        int callerUid = Binder.getCallingUid();
5921        // Only the system server can kill an application
5922        if (callerUid == Process.SYSTEM_UID) {
5923            synchronized (this) {
5924                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5925                if (app != null && app.thread != null) {
5926                    try {
5927                        app.thread.scheduleSuicide();
5928                    } catch (RemoteException e) {
5929                        // If the other end already died, then our work here is done.
5930                    }
5931                } else {
5932                    Slog.w(TAG, "Process/uid not found attempting kill of "
5933                            + processName + " / " + uid);
5934                }
5935            }
5936        } else {
5937            throw new SecurityException(callerUid + " cannot kill app process: " +
5938                    processName);
5939        }
5940    }
5941
5942    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5943        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5944                false, true, false, false, UserHandle.getUserId(uid), reason);
5945    }
5946
5947    private void finishForceStopPackageLocked(final String packageName, int uid) {
5948        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5949                Uri.fromParts("package", packageName, null));
5950        if (!mProcessesReady) {
5951            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5952                    | Intent.FLAG_RECEIVER_FOREGROUND);
5953        }
5954        intent.putExtra(Intent.EXTRA_UID, uid);
5955        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5956        broadcastIntentLocked(null, null, intent,
5957                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5958                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5959    }
5960
5961
5962    private final boolean killPackageProcessesLocked(String packageName, int appId,
5963            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5964            boolean doit, boolean evenPersistent, String reason) {
5965        ArrayList<ProcessRecord> procs = new ArrayList<>();
5966
5967        // Remove all processes this package may have touched: all with the
5968        // same UID (except for the system or root user), and all whose name
5969        // matches the package name.
5970        final int NP = mProcessNames.getMap().size();
5971        for (int ip=0; ip<NP; ip++) {
5972            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5973            final int NA = apps.size();
5974            for (int ia=0; ia<NA; ia++) {
5975                ProcessRecord app = apps.valueAt(ia);
5976                if (app.persistent && !evenPersistent) {
5977                    // we don't kill persistent processes
5978                    continue;
5979                }
5980                if (app.removed) {
5981                    if (doit) {
5982                        procs.add(app);
5983                    }
5984                    continue;
5985                }
5986
5987                // Skip process if it doesn't meet our oom adj requirement.
5988                if (app.setAdj < minOomAdj) {
5989                    continue;
5990                }
5991
5992                // If no package is specified, we call all processes under the
5993                // give user id.
5994                if (packageName == null) {
5995                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5996                        continue;
5997                    }
5998                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5999                        continue;
6000                    }
6001                // Package has been specified, we want to hit all processes
6002                // that match it.  We need to qualify this by the processes
6003                // that are running under the specified app and user ID.
6004                } else {
6005                    final boolean isDep = app.pkgDeps != null
6006                            && app.pkgDeps.contains(packageName);
6007                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6008                        continue;
6009                    }
6010                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6011                        continue;
6012                    }
6013                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6014                        continue;
6015                    }
6016                }
6017
6018                // Process has passed all conditions, kill it!
6019                if (!doit) {
6020                    return true;
6021                }
6022                app.removed = true;
6023                procs.add(app);
6024            }
6025        }
6026
6027        int N = procs.size();
6028        for (int i=0; i<N; i++) {
6029            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6030        }
6031        updateOomAdjLocked();
6032        return N > 0;
6033    }
6034
6035    private void cleanupDisabledPackageComponentsLocked(
6036            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6037
6038        Set<String> disabledClasses = null;
6039        boolean packageDisabled = false;
6040        IPackageManager pm = AppGlobals.getPackageManager();
6041
6042        if (changedClasses == null) {
6043            // Nothing changed...
6044            return;
6045        }
6046
6047        // Determine enable/disable state of the package and its components.
6048        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6049        for (int i = changedClasses.length - 1; i >= 0; i--) {
6050            final String changedClass = changedClasses[i];
6051
6052            if (changedClass.equals(packageName)) {
6053                try {
6054                    // Entire package setting changed
6055                    enabled = pm.getApplicationEnabledSetting(packageName,
6056                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6057                } catch (Exception e) {
6058                    // No such package/component; probably racing with uninstall.  In any
6059                    // event it means we have nothing further to do here.
6060                    return;
6061                }
6062                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6063                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6064                if (packageDisabled) {
6065                    // Entire package is disabled.
6066                    // No need to continue to check component states.
6067                    disabledClasses = null;
6068                    break;
6069                }
6070            } else {
6071                try {
6072                    enabled = pm.getComponentEnabledSetting(
6073                            new ComponentName(packageName, changedClass),
6074                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6075                } catch (Exception e) {
6076                    // As above, probably racing with uninstall.
6077                    return;
6078                }
6079                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6080                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6081                    if (disabledClasses == null) {
6082                        disabledClasses = new ArraySet<>(changedClasses.length);
6083                    }
6084                    disabledClasses.add(changedClass);
6085                }
6086            }
6087        }
6088
6089        if (!packageDisabled && disabledClasses == null) {
6090            // Nothing to do here...
6091            return;
6092        }
6093
6094        // Clean-up disabled activities.
6095        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6096                packageName, disabledClasses, true, false, userId) && mBooted) {
6097            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6098            mStackSupervisor.scheduleIdleLocked();
6099        }
6100
6101        // Clean-up disabled tasks
6102        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6103
6104        // Clean-up disabled services.
6105        mServices.bringDownDisabledPackageServicesLocked(
6106                packageName, disabledClasses, userId, false, killProcess, true);
6107
6108        // Clean-up disabled providers.
6109        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6110        mProviderMap.collectPackageProvidersLocked(
6111                packageName, disabledClasses, true, false, userId, providers);
6112        for (int i = providers.size() - 1; i >= 0; i--) {
6113            removeDyingProviderLocked(null, providers.get(i), true);
6114        }
6115
6116        // Clean-up disabled broadcast receivers.
6117        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6118            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6119                    packageName, disabledClasses, userId, true);
6120        }
6121
6122    }
6123
6124    final boolean clearBroadcastQueueForUserLocked(int userId) {
6125        boolean didSomething = false;
6126        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6127            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6128                    null, null, userId, true);
6129        }
6130        return didSomething;
6131    }
6132
6133    final boolean forceStopPackageLocked(String packageName, int appId,
6134            boolean callerWillRestart, boolean purgeCache, boolean doit,
6135            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6136        int i;
6137
6138        if (userId == UserHandle.USER_ALL && packageName == null) {
6139            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6140        }
6141
6142        if (appId < 0 && packageName != null) {
6143            try {
6144                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6145                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6146            } catch (RemoteException e) {
6147            }
6148        }
6149
6150        if (doit) {
6151            if (packageName != null) {
6152                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6153                        + " user=" + userId + ": " + reason);
6154            } else {
6155                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6156            }
6157
6158            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6159        }
6160
6161        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6162                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6163                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6164
6165        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6166                packageName, null, doit, evenPersistent, userId)) {
6167            if (!doit) {
6168                return true;
6169            }
6170            didSomething = true;
6171        }
6172
6173        if (mServices.bringDownDisabledPackageServicesLocked(
6174                packageName, null, userId, evenPersistent, true, doit)) {
6175            if (!doit) {
6176                return true;
6177            }
6178            didSomething = true;
6179        }
6180
6181        if (packageName == null) {
6182            // Remove all sticky broadcasts from this user.
6183            mStickyBroadcasts.remove(userId);
6184        }
6185
6186        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6187        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6188                userId, providers)) {
6189            if (!doit) {
6190                return true;
6191            }
6192            didSomething = true;
6193        }
6194        for (i = providers.size() - 1; i >= 0; i--) {
6195            removeDyingProviderLocked(null, providers.get(i), true);
6196        }
6197
6198        // Remove transient permissions granted from/to this package/user
6199        removeUriPermissionsForPackageLocked(packageName, userId, false);
6200
6201        if (doit) {
6202            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6203                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6204                        packageName, null, userId, doit);
6205            }
6206        }
6207
6208        if (packageName == null || uninstalling) {
6209            // Remove pending intents.  For now we only do this when force
6210            // stopping users, because we have some problems when doing this
6211            // for packages -- app widgets are not currently cleaned up for
6212            // such packages, so they can be left with bad pending intents.
6213            if (mIntentSenderRecords.size() > 0) {
6214                Iterator<WeakReference<PendingIntentRecord>> it
6215                        = mIntentSenderRecords.values().iterator();
6216                while (it.hasNext()) {
6217                    WeakReference<PendingIntentRecord> wpir = it.next();
6218                    if (wpir == null) {
6219                        it.remove();
6220                        continue;
6221                    }
6222                    PendingIntentRecord pir = wpir.get();
6223                    if (pir == null) {
6224                        it.remove();
6225                        continue;
6226                    }
6227                    if (packageName == null) {
6228                        // Stopping user, remove all objects for the user.
6229                        if (pir.key.userId != userId) {
6230                            // Not the same user, skip it.
6231                            continue;
6232                        }
6233                    } else {
6234                        if (UserHandle.getAppId(pir.uid) != appId) {
6235                            // Different app id, skip it.
6236                            continue;
6237                        }
6238                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6239                            // Different user, skip it.
6240                            continue;
6241                        }
6242                        if (!pir.key.packageName.equals(packageName)) {
6243                            // Different package, skip it.
6244                            continue;
6245                        }
6246                    }
6247                    if (!doit) {
6248                        return true;
6249                    }
6250                    didSomething = true;
6251                    it.remove();
6252                    pir.canceled = true;
6253                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6254                        pir.key.activity.pendingResults.remove(pir.ref);
6255                    }
6256                }
6257            }
6258        }
6259
6260        if (doit) {
6261            if (purgeCache && packageName != null) {
6262                AttributeCache ac = AttributeCache.instance();
6263                if (ac != null) {
6264                    ac.removePackage(packageName);
6265                }
6266            }
6267            if (mBooted) {
6268                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6269                mStackSupervisor.scheduleIdleLocked();
6270            }
6271        }
6272
6273        return didSomething;
6274    }
6275
6276    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6277        ProcessRecord old = mProcessNames.remove(name, uid);
6278        if (old != null) {
6279            old.uidRecord.numProcs--;
6280            if (old.uidRecord.numProcs == 0) {
6281                // No more processes using this uid, tell clients it is gone.
6282                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6283                        "No more processes in " + old.uidRecord);
6284                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6285                mActiveUids.remove(uid);
6286                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6287            }
6288            old.uidRecord = null;
6289        }
6290        mIsolatedProcesses.remove(uid);
6291        return old;
6292    }
6293
6294    private final void addProcessNameLocked(ProcessRecord proc) {
6295        // We shouldn't already have a process under this name, but just in case we
6296        // need to clean up whatever may be there now.
6297        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6298        if (old == proc && proc.persistent) {
6299            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6300            Slog.w(TAG, "Re-adding persistent process " + proc);
6301        } else if (old != null) {
6302            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6303        }
6304        UidRecord uidRec = mActiveUids.get(proc.uid);
6305        if (uidRec == null) {
6306            uidRec = new UidRecord(proc.uid);
6307            // This is the first appearance of the uid, report it now!
6308            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6309                    "Creating new process uid: " + uidRec);
6310            mActiveUids.put(proc.uid, uidRec);
6311            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6312            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6313        }
6314        proc.uidRecord = uidRec;
6315
6316        // Reset render thread tid if it was already set, so new process can set it again.
6317        proc.renderThreadTid = 0;
6318        uidRec.numProcs++;
6319        mProcessNames.put(proc.processName, proc.uid, proc);
6320        if (proc.isolated) {
6321            mIsolatedProcesses.put(proc.uid, proc);
6322        }
6323    }
6324
6325    boolean removeProcessLocked(ProcessRecord app,
6326            boolean callerWillRestart, boolean allowRestart, String reason) {
6327        final String name = app.processName;
6328        final int uid = app.uid;
6329        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6330            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6331
6332        ProcessRecord old = mProcessNames.get(name, uid);
6333        if (old != app) {
6334            // This process is no longer active, so nothing to do.
6335            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6336            return false;
6337        }
6338        removeProcessNameLocked(name, uid);
6339        if (mHeavyWeightProcess == app) {
6340            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6341                    mHeavyWeightProcess.userId, 0));
6342            mHeavyWeightProcess = null;
6343        }
6344        boolean needRestart = false;
6345        if (app.pid > 0 && app.pid != MY_PID) {
6346            int pid = app.pid;
6347            synchronized (mPidsSelfLocked) {
6348                mPidsSelfLocked.remove(pid);
6349                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6350            }
6351            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6352            if (app.isolated) {
6353                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6354            }
6355            boolean willRestart = false;
6356            if (app.persistent && !app.isolated) {
6357                if (!callerWillRestart) {
6358                    willRestart = true;
6359                } else {
6360                    needRestart = true;
6361                }
6362            }
6363            app.kill(reason, true);
6364            handleAppDiedLocked(app, willRestart, allowRestart);
6365            if (willRestart) {
6366                removeLruProcessLocked(app);
6367                addAppLocked(app.info, false, null /* ABI override */);
6368            }
6369        } else {
6370            mRemovedProcesses.add(app);
6371        }
6372
6373        return needRestart;
6374    }
6375
6376    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6377        cleanupAppInLaunchingProvidersLocked(app, true);
6378        removeProcessLocked(app, false, true, "timeout publishing content providers");
6379    }
6380
6381    private final void processStartTimedOutLocked(ProcessRecord app) {
6382        final int pid = app.pid;
6383        boolean gone = false;
6384        synchronized (mPidsSelfLocked) {
6385            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6386            if (knownApp != null && knownApp.thread == null) {
6387                mPidsSelfLocked.remove(pid);
6388                gone = true;
6389            }
6390        }
6391
6392        if (gone) {
6393            Slog.w(TAG, "Process " + app + " failed to attach");
6394            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6395                    pid, app.uid, app.processName);
6396            removeProcessNameLocked(app.processName, app.uid);
6397            if (mHeavyWeightProcess == app) {
6398                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6399                        mHeavyWeightProcess.userId, 0));
6400                mHeavyWeightProcess = null;
6401            }
6402            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6403            if (app.isolated) {
6404                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6405            }
6406            // Take care of any launching providers waiting for this process.
6407            cleanupAppInLaunchingProvidersLocked(app, true);
6408            // Take care of any services that are waiting for the process.
6409            mServices.processStartTimedOutLocked(app);
6410            app.kill("start timeout", true);
6411            removeLruProcessLocked(app);
6412            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6413                Slog.w(TAG, "Unattached app died before backup, skipping");
6414                try {
6415                    IBackupManager bm = IBackupManager.Stub.asInterface(
6416                            ServiceManager.getService(Context.BACKUP_SERVICE));
6417                    bm.agentDisconnected(app.info.packageName);
6418                } catch (RemoteException e) {
6419                    // Can't happen; the backup manager is local
6420                }
6421            }
6422            if (isPendingBroadcastProcessLocked(pid)) {
6423                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6424                skipPendingBroadcastLocked(pid);
6425            }
6426        } else {
6427            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6428        }
6429    }
6430
6431    private final boolean attachApplicationLocked(IApplicationThread thread,
6432            int pid) {
6433
6434        // Find the application record that is being attached...  either via
6435        // the pid if we are running in multiple processes, or just pull the
6436        // next app record if we are emulating process with anonymous threads.
6437        ProcessRecord app;
6438        if (pid != MY_PID && pid >= 0) {
6439            synchronized (mPidsSelfLocked) {
6440                app = mPidsSelfLocked.get(pid);
6441            }
6442        } else {
6443            app = null;
6444        }
6445
6446        if (app == null) {
6447            Slog.w(TAG, "No pending application record for pid " + pid
6448                    + " (IApplicationThread " + thread + "); dropping process");
6449            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6450            if (pid > 0 && pid != MY_PID) {
6451                Process.killProcessQuiet(pid);
6452                //TODO: killProcessGroup(app.info.uid, pid);
6453            } else {
6454                try {
6455                    thread.scheduleExit();
6456                } catch (Exception e) {
6457                    // Ignore exceptions.
6458                }
6459            }
6460            return false;
6461        }
6462
6463        // If this application record is still attached to a previous
6464        // process, clean it up now.
6465        if (app.thread != null) {
6466            handleAppDiedLocked(app, true, true);
6467        }
6468
6469        // Tell the process all about itself.
6470
6471        if (DEBUG_ALL) Slog.v(
6472                TAG, "Binding process pid " + pid + " to record " + app);
6473
6474        final String processName = app.processName;
6475        try {
6476            AppDeathRecipient adr = new AppDeathRecipient(
6477                    app, pid, thread);
6478            thread.asBinder().linkToDeath(adr, 0);
6479            app.deathRecipient = adr;
6480        } catch (RemoteException e) {
6481            app.resetPackageList(mProcessStats);
6482            startProcessLocked(app, "link fail", processName);
6483            return false;
6484        }
6485
6486        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6487
6488        app.makeActive(thread, mProcessStats);
6489        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6490        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6491        app.forcingToForeground = null;
6492        updateProcessForegroundLocked(app, false, false);
6493        app.hasShownUi = false;
6494        app.debugging = false;
6495        app.cached = false;
6496        app.killedByAm = false;
6497
6498        // We carefully use the same state that PackageManager uses for
6499        // filtering, since we use this flag to decide if we need to install
6500        // providers when user is unlocked later
6501        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6502
6503        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6504
6505        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6506        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6507
6508        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6509            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6510            msg.obj = app;
6511            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6512        }
6513
6514        if (!normalMode) {
6515            Slog.i(TAG, "Launching preboot mode app: " + app);
6516        }
6517
6518        if (DEBUG_ALL) Slog.v(
6519            TAG, "New app record " + app
6520            + " thread=" + thread.asBinder() + " pid=" + pid);
6521        try {
6522            int testMode = IApplicationThread.DEBUG_OFF;
6523            if (mDebugApp != null && mDebugApp.equals(processName)) {
6524                testMode = mWaitForDebugger
6525                    ? IApplicationThread.DEBUG_WAIT
6526                    : IApplicationThread.DEBUG_ON;
6527                app.debugging = true;
6528                if (mDebugTransient) {
6529                    mDebugApp = mOrigDebugApp;
6530                    mWaitForDebugger = mOrigWaitForDebugger;
6531                }
6532            }
6533            String profileFile = app.instrumentationProfileFile;
6534            ParcelFileDescriptor profileFd = null;
6535            int samplingInterval = 0;
6536            boolean profileAutoStop = false;
6537            if (mProfileApp != null && mProfileApp.equals(processName)) {
6538                mProfileProc = app;
6539                profileFile = mProfileFile;
6540                profileFd = mProfileFd;
6541                samplingInterval = mSamplingInterval;
6542                profileAutoStop = mAutoStopProfiler;
6543            }
6544            boolean enableTrackAllocation = false;
6545            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6546                enableTrackAllocation = true;
6547                mTrackAllocationApp = null;
6548            }
6549
6550            // If the app is being launched for restore or full backup, set it up specially
6551            boolean isRestrictedBackupMode = false;
6552            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6553                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6554                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6555                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6556                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6557            }
6558
6559            if (app.instrumentationClass != null) {
6560                notifyPackageUse(app.instrumentationClass.getPackageName(),
6561                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6562            }
6563            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6564                    + processName + " with config " + mConfiguration);
6565            ApplicationInfo appInfo = app.instrumentationInfo != null
6566                    ? app.instrumentationInfo : app.info;
6567            app.compat = compatibilityInfoForPackageLocked(appInfo);
6568            if (profileFd != null) {
6569                profileFd = profileFd.dup();
6570            }
6571            ProfilerInfo profilerInfo = profileFile == null ? null
6572                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6573            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6574                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6575                    app.instrumentationUiAutomationConnection, testMode,
6576                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6577                    isRestrictedBackupMode || !normalMode, app.persistent,
6578                    new Configuration(mConfiguration), app.compat,
6579                    getCommonServicesLocked(app.isolated),
6580                    mCoreSettingsObserver.getCoreSettingsLocked());
6581            updateLruProcessLocked(app, false, null);
6582            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6583        } catch (Exception e) {
6584            // todo: Yikes!  What should we do?  For now we will try to
6585            // start another process, but that could easily get us in
6586            // an infinite loop of restarting processes...
6587            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6588
6589            app.resetPackageList(mProcessStats);
6590            app.unlinkDeathRecipient();
6591            startProcessLocked(app, "bind fail", processName);
6592            return false;
6593        }
6594
6595        // Remove this record from the list of starting applications.
6596        mPersistentStartingProcesses.remove(app);
6597        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6598                "Attach application locked removing on hold: " + app);
6599        mProcessesOnHold.remove(app);
6600
6601        boolean badApp = false;
6602        boolean didSomething = false;
6603
6604        // See if the top visible activity is waiting to run in this process...
6605        if (normalMode) {
6606            try {
6607                if (mStackSupervisor.attachApplicationLocked(app)) {
6608                    didSomething = true;
6609                }
6610            } catch (Exception e) {
6611                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6612                badApp = true;
6613            }
6614        }
6615
6616        // Find any services that should be running in this process...
6617        if (!badApp) {
6618            try {
6619                didSomething |= mServices.attachApplicationLocked(app, processName);
6620            } catch (Exception e) {
6621                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6622                badApp = true;
6623            }
6624        }
6625
6626        // Check if a next-broadcast receiver is in this process...
6627        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6628            try {
6629                didSomething |= sendPendingBroadcastsLocked(app);
6630            } catch (Exception e) {
6631                // If the app died trying to launch the receiver we declare it 'bad'
6632                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6633                badApp = true;
6634            }
6635        }
6636
6637        // Check whether the next backup agent is in this process...
6638        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6639            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6640                    "New app is backup target, launching agent for " + app);
6641            notifyPackageUse(mBackupTarget.appInfo.packageName,
6642                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6643            try {
6644                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6645                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6646                        mBackupTarget.backupMode);
6647            } catch (Exception e) {
6648                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6649                badApp = true;
6650            }
6651        }
6652
6653        if (badApp) {
6654            app.kill("error during init", true);
6655            handleAppDiedLocked(app, false, true);
6656            return false;
6657        }
6658
6659        if (!didSomething) {
6660            updateOomAdjLocked();
6661        }
6662
6663        return true;
6664    }
6665
6666    @Override
6667    public final void attachApplication(IApplicationThread thread) {
6668        synchronized (this) {
6669            int callingPid = Binder.getCallingPid();
6670            final long origId = Binder.clearCallingIdentity();
6671            attachApplicationLocked(thread, callingPid);
6672            Binder.restoreCallingIdentity(origId);
6673        }
6674    }
6675
6676    @Override
6677    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6678        final long origId = Binder.clearCallingIdentity();
6679        synchronized (this) {
6680            ActivityStack stack = ActivityRecord.getStackLocked(token);
6681            if (stack != null) {
6682                ActivityRecord r =
6683                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6684                if (stopProfiling) {
6685                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6686                        try {
6687                            mProfileFd.close();
6688                        } catch (IOException e) {
6689                        }
6690                        clearProfilerLocked();
6691                    }
6692                }
6693            }
6694        }
6695        Binder.restoreCallingIdentity(origId);
6696    }
6697
6698    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6699        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6700                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6701    }
6702
6703    void enableScreenAfterBoot() {
6704        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6705                SystemClock.uptimeMillis());
6706        mWindowManager.enableScreenAfterBoot();
6707
6708        synchronized (this) {
6709            updateEventDispatchingLocked();
6710        }
6711    }
6712
6713    @Override
6714    public void showBootMessage(final CharSequence msg, final boolean always) {
6715        if (Binder.getCallingUid() != Process.myUid()) {
6716            throw new SecurityException();
6717        }
6718        mWindowManager.showBootMessage(msg, always);
6719    }
6720
6721    @Override
6722    public void keyguardWaitingForActivityDrawn() {
6723        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6724        final long token = Binder.clearCallingIdentity();
6725        try {
6726            synchronized (this) {
6727                if (DEBUG_LOCKSCREEN) logLockScreen("");
6728                mWindowManager.keyguardWaitingForActivityDrawn();
6729                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6730                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6731                    updateSleepIfNeededLocked();
6732                }
6733            }
6734        } finally {
6735            Binder.restoreCallingIdentity(token);
6736        }
6737    }
6738
6739    @Override
6740    public void keyguardGoingAway(int flags) {
6741        enforceNotIsolatedCaller("keyguardGoingAway");
6742        final long token = Binder.clearCallingIdentity();
6743        try {
6744            synchronized (this) {
6745                if (DEBUG_LOCKSCREEN) logLockScreen("");
6746                mWindowManager.keyguardGoingAway(flags);
6747                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6748                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6749                    updateSleepIfNeededLocked();
6750
6751                    // Some stack visibility might change (e.g. docked stack)
6752                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6753                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6754                }
6755            }
6756        } finally {
6757            Binder.restoreCallingIdentity(token);
6758        }
6759    }
6760
6761    final void finishBooting() {
6762        synchronized (this) {
6763            if (!mBootAnimationComplete) {
6764                mCallFinishBooting = true;
6765                return;
6766            }
6767            mCallFinishBooting = false;
6768        }
6769
6770        ArraySet<String> completedIsas = new ArraySet<String>();
6771        for (String abi : Build.SUPPORTED_ABIS) {
6772            Process.establishZygoteConnectionForAbi(abi);
6773            final String instructionSet = VMRuntime.getInstructionSet(abi);
6774            if (!completedIsas.contains(instructionSet)) {
6775                try {
6776                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6777                } catch (InstallerException e) {
6778                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6779                            e.getMessage() +")");
6780                }
6781                completedIsas.add(instructionSet);
6782            }
6783        }
6784
6785        IntentFilter pkgFilter = new IntentFilter();
6786        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6787        pkgFilter.addDataScheme("package");
6788        mContext.registerReceiver(new BroadcastReceiver() {
6789            @Override
6790            public void onReceive(Context context, Intent intent) {
6791                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6792                if (pkgs != null) {
6793                    for (String pkg : pkgs) {
6794                        synchronized (ActivityManagerService.this) {
6795                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6796                                    0, "query restart")) {
6797                                setResultCode(Activity.RESULT_OK);
6798                                return;
6799                            }
6800                        }
6801                    }
6802                }
6803            }
6804        }, pkgFilter);
6805
6806        IntentFilter dumpheapFilter = new IntentFilter();
6807        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6808        mContext.registerReceiver(new BroadcastReceiver() {
6809            @Override
6810            public void onReceive(Context context, Intent intent) {
6811                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6812                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6813                } else {
6814                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6815                }
6816            }
6817        }, dumpheapFilter);
6818
6819        // Let system services know.
6820        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6821
6822        synchronized (this) {
6823            // Ensure that any processes we had put on hold are now started
6824            // up.
6825            final int NP = mProcessesOnHold.size();
6826            if (NP > 0) {
6827                ArrayList<ProcessRecord> procs =
6828                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6829                for (int ip=0; ip<NP; ip++) {
6830                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6831                            + procs.get(ip));
6832                    startProcessLocked(procs.get(ip), "on-hold", null);
6833                }
6834            }
6835
6836            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6837                // Start looking for apps that are abusing wake locks.
6838                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6839                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6840                // Tell anyone interested that we are done booting!
6841                SystemProperties.set("sys.boot_completed", "1");
6842
6843                // And trigger dev.bootcomplete if we are not showing encryption progress
6844                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6845                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6846                    SystemProperties.set("dev.bootcomplete", "1");
6847                }
6848                mUserController.sendBootCompletedLocked(
6849                        new IIntentReceiver.Stub() {
6850                            @Override
6851                            public void performReceive(Intent intent, int resultCode,
6852                                    String data, Bundle extras, boolean ordered,
6853                                    boolean sticky, int sendingUser) {
6854                                synchronized (ActivityManagerService.this) {
6855                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6856                                            true, false);
6857                                }
6858                            }
6859                        });
6860                scheduleStartProfilesLocked();
6861            }
6862        }
6863    }
6864
6865    @Override
6866    public void bootAnimationComplete() {
6867        final boolean callFinishBooting;
6868        synchronized (this) {
6869            callFinishBooting = mCallFinishBooting;
6870            mBootAnimationComplete = true;
6871        }
6872        if (callFinishBooting) {
6873            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6874            finishBooting();
6875            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6876        }
6877    }
6878
6879    final void ensureBootCompleted() {
6880        boolean booting;
6881        boolean enableScreen;
6882        synchronized (this) {
6883            booting = mBooting;
6884            mBooting = false;
6885            enableScreen = !mBooted;
6886            mBooted = true;
6887        }
6888
6889        if (booting) {
6890            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6891            finishBooting();
6892            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6893        }
6894
6895        if (enableScreen) {
6896            enableScreenAfterBoot();
6897        }
6898    }
6899
6900    @Override
6901    public final void activityResumed(IBinder token) {
6902        final long origId = Binder.clearCallingIdentity();
6903        synchronized(this) {
6904            ActivityStack stack = ActivityRecord.getStackLocked(token);
6905            if (stack != null) {
6906                stack.activityResumedLocked(token);
6907            }
6908        }
6909        Binder.restoreCallingIdentity(origId);
6910    }
6911
6912    @Override
6913    public final void activityPaused(IBinder token) {
6914        final long origId = Binder.clearCallingIdentity();
6915        synchronized(this) {
6916            ActivityStack stack = ActivityRecord.getStackLocked(token);
6917            if (stack != null) {
6918                stack.activityPausedLocked(token, false);
6919            }
6920        }
6921        Binder.restoreCallingIdentity(origId);
6922    }
6923
6924    @Override
6925    public final void activityStopped(IBinder token, Bundle icicle,
6926            PersistableBundle persistentState, CharSequence description) {
6927        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6928
6929        // Refuse possible leaked file descriptors
6930        if (icicle != null && icicle.hasFileDescriptors()) {
6931            throw new IllegalArgumentException("File descriptors passed in Bundle");
6932        }
6933
6934        final long origId = Binder.clearCallingIdentity();
6935
6936        synchronized (this) {
6937            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6938            if (r != null) {
6939                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6940            }
6941        }
6942
6943        trimApplications();
6944
6945        Binder.restoreCallingIdentity(origId);
6946    }
6947
6948    @Override
6949    public final void activityDestroyed(IBinder token) {
6950        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6951        synchronized (this) {
6952            ActivityStack stack = ActivityRecord.getStackLocked(token);
6953            if (stack != null) {
6954                stack.activityDestroyedLocked(token, "activityDestroyed");
6955            }
6956        }
6957    }
6958
6959    @Override
6960    public final void activityRelaunched(IBinder token) {
6961        final long origId = Binder.clearCallingIdentity();
6962        synchronized (this) {
6963            mStackSupervisor.activityRelaunchedLocked(token);
6964        }
6965        Binder.restoreCallingIdentity(origId);
6966    }
6967
6968    @Override
6969    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6970            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6971        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6972                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6973        synchronized (this) {
6974            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6975            if (record == null) {
6976                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6977                        + "found for: " + token);
6978            }
6979            record.setSizeConfigurations(horizontalSizeConfiguration,
6980                    verticalSizeConfigurations, smallestSizeConfigurations);
6981        }
6982    }
6983
6984    @Override
6985    public final void backgroundResourcesReleased(IBinder token) {
6986        final long origId = Binder.clearCallingIdentity();
6987        try {
6988            synchronized (this) {
6989                ActivityStack stack = ActivityRecord.getStackLocked(token);
6990                if (stack != null) {
6991                    stack.backgroundResourcesReleased();
6992                }
6993            }
6994        } finally {
6995            Binder.restoreCallingIdentity(origId);
6996        }
6997    }
6998
6999    @Override
7000    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7001        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7002    }
7003
7004    @Override
7005    public final void notifyEnterAnimationComplete(IBinder token) {
7006        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7007    }
7008
7009    @Override
7010    public String getCallingPackage(IBinder token) {
7011        synchronized (this) {
7012            ActivityRecord r = getCallingRecordLocked(token);
7013            return r != null ? r.info.packageName : null;
7014        }
7015    }
7016
7017    @Override
7018    public ComponentName getCallingActivity(IBinder token) {
7019        synchronized (this) {
7020            ActivityRecord r = getCallingRecordLocked(token);
7021            return r != null ? r.intent.getComponent() : null;
7022        }
7023    }
7024
7025    private ActivityRecord getCallingRecordLocked(IBinder token) {
7026        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7027        if (r == null) {
7028            return null;
7029        }
7030        return r.resultTo;
7031    }
7032
7033    @Override
7034    public ComponentName getActivityClassForToken(IBinder token) {
7035        synchronized(this) {
7036            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7037            if (r == null) {
7038                return null;
7039            }
7040            return r.intent.getComponent();
7041        }
7042    }
7043
7044    @Override
7045    public String getPackageForToken(IBinder token) {
7046        synchronized(this) {
7047            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7048            if (r == null) {
7049                return null;
7050            }
7051            return r.packageName;
7052        }
7053    }
7054
7055    @Override
7056    public boolean isRootVoiceInteraction(IBinder token) {
7057        synchronized(this) {
7058            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7059            if (r == null) {
7060                return false;
7061            }
7062            return r.rootVoiceInteraction;
7063        }
7064    }
7065
7066    @Override
7067    public IIntentSender getIntentSender(int type,
7068            String packageName, IBinder token, String resultWho,
7069            int requestCode, Intent[] intents, String[] resolvedTypes,
7070            int flags, Bundle bOptions, int userId) {
7071        enforceNotIsolatedCaller("getIntentSender");
7072        // Refuse possible leaked file descriptors
7073        if (intents != null) {
7074            if (intents.length < 1) {
7075                throw new IllegalArgumentException("Intents array length must be >= 1");
7076            }
7077            for (int i=0; i<intents.length; i++) {
7078                Intent intent = intents[i];
7079                if (intent != null) {
7080                    if (intent.hasFileDescriptors()) {
7081                        throw new IllegalArgumentException("File descriptors passed in Intent");
7082                    }
7083                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7084                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7085                        throw new IllegalArgumentException(
7086                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7087                    }
7088                    intents[i] = new Intent(intent);
7089                }
7090            }
7091            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7092                throw new IllegalArgumentException(
7093                        "Intent array length does not match resolvedTypes length");
7094            }
7095        }
7096        if (bOptions != null) {
7097            if (bOptions.hasFileDescriptors()) {
7098                throw new IllegalArgumentException("File descriptors passed in options");
7099            }
7100        }
7101
7102        synchronized(this) {
7103            int callingUid = Binder.getCallingUid();
7104            int origUserId = userId;
7105            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7106                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7107                    ALLOW_NON_FULL, "getIntentSender", null);
7108            if (origUserId == UserHandle.USER_CURRENT) {
7109                // We don't want to evaluate this until the pending intent is
7110                // actually executed.  However, we do want to always do the
7111                // security checking for it above.
7112                userId = UserHandle.USER_CURRENT;
7113            }
7114            try {
7115                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7116                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7117                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7118                    if (!UserHandle.isSameApp(callingUid, uid)) {
7119                        String msg = "Permission Denial: getIntentSender() from pid="
7120                            + Binder.getCallingPid()
7121                            + ", uid=" + Binder.getCallingUid()
7122                            + ", (need uid=" + uid + ")"
7123                            + " is not allowed to send as package " + packageName;
7124                        Slog.w(TAG, msg);
7125                        throw new SecurityException(msg);
7126                    }
7127                }
7128
7129                return getIntentSenderLocked(type, packageName, callingUid, userId,
7130                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7131
7132            } catch (RemoteException e) {
7133                throw new SecurityException(e);
7134            }
7135        }
7136    }
7137
7138    IIntentSender getIntentSenderLocked(int type, String packageName,
7139            int callingUid, int userId, IBinder token, String resultWho,
7140            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7141            Bundle bOptions) {
7142        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7143        ActivityRecord activity = null;
7144        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7145            activity = ActivityRecord.isInStackLocked(token);
7146            if (activity == null) {
7147                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7148                return null;
7149            }
7150            if (activity.finishing) {
7151                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7152                return null;
7153            }
7154        }
7155
7156        // We're going to be splicing together extras before sending, so we're
7157        // okay poking into any contained extras.
7158        if (intents != null) {
7159            for (int i = 0; i < intents.length; i++) {
7160                intents[i].setDefusable(true);
7161            }
7162        }
7163        Bundle.setDefusable(bOptions, true);
7164
7165        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7166        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7167        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7168        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7169                |PendingIntent.FLAG_UPDATE_CURRENT);
7170
7171        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7172                type, packageName, activity, resultWho,
7173                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7174        WeakReference<PendingIntentRecord> ref;
7175        ref = mIntentSenderRecords.get(key);
7176        PendingIntentRecord rec = ref != null ? ref.get() : null;
7177        if (rec != null) {
7178            if (!cancelCurrent) {
7179                if (updateCurrent) {
7180                    if (rec.key.requestIntent != null) {
7181                        rec.key.requestIntent.replaceExtras(intents != null ?
7182                                intents[intents.length - 1] : null);
7183                    }
7184                    if (intents != null) {
7185                        intents[intents.length-1] = rec.key.requestIntent;
7186                        rec.key.allIntents = intents;
7187                        rec.key.allResolvedTypes = resolvedTypes;
7188                    } else {
7189                        rec.key.allIntents = null;
7190                        rec.key.allResolvedTypes = null;
7191                    }
7192                }
7193                return rec;
7194            }
7195            rec.canceled = true;
7196            mIntentSenderRecords.remove(key);
7197        }
7198        if (noCreate) {
7199            return rec;
7200        }
7201        rec = new PendingIntentRecord(this, key, callingUid);
7202        mIntentSenderRecords.put(key, rec.ref);
7203        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7204            if (activity.pendingResults == null) {
7205                activity.pendingResults
7206                        = new HashSet<WeakReference<PendingIntentRecord>>();
7207            }
7208            activity.pendingResults.add(rec.ref);
7209        }
7210        return rec;
7211    }
7212
7213    @Override
7214    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7215            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7216        if (target instanceof PendingIntentRecord) {
7217            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7218                    finishedReceiver, requiredPermission, options);
7219        } else {
7220            if (intent == null) {
7221                // Weird case: someone has given us their own custom IIntentSender, and now
7222                // they have someone else trying to send to it but of course this isn't
7223                // really a PendingIntent, so there is no base Intent, and the caller isn't
7224                // supplying an Intent... but we never want to dispatch a null Intent to
7225                // a receiver, so um...  let's make something up.
7226                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7227                intent = new Intent(Intent.ACTION_MAIN);
7228            }
7229            try {
7230                target.send(code, intent, resolvedType, null, requiredPermission, options);
7231            } catch (RemoteException e) {
7232            }
7233            // Platform code can rely on getting a result back when the send is done, but if
7234            // this intent sender is from outside of the system we can't rely on it doing that.
7235            // So instead we don't give it the result receiver, and instead just directly
7236            // report the finish immediately.
7237            if (finishedReceiver != null) {
7238                try {
7239                    finishedReceiver.performReceive(intent, 0,
7240                            null, null, false, false, UserHandle.getCallingUserId());
7241                } catch (RemoteException e) {
7242                }
7243            }
7244            return 0;
7245        }
7246    }
7247
7248    /**
7249     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7250     *
7251     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7252     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7253     */
7254    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7255        if (DEBUG_WHITELISTS) {
7256            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7257                    + targetUid + ", " + duration + ")");
7258        }
7259        synchronized (mPidsSelfLocked) {
7260            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7261            if (pr == null) {
7262                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7263                return;
7264            }
7265            if (!pr.whitelistManager) {
7266                if (DEBUG_WHITELISTS) {
7267                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7268                            + callerPid + " is not allowed");
7269                }
7270                return;
7271            }
7272        }
7273
7274        final long token = Binder.clearCallingIdentity();
7275        try {
7276            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7277                    true, "pe from uid:" + callerUid);
7278        } finally {
7279            Binder.restoreCallingIdentity(token);
7280        }
7281    }
7282
7283    @Override
7284    public void cancelIntentSender(IIntentSender sender) {
7285        if (!(sender instanceof PendingIntentRecord)) {
7286            return;
7287        }
7288        synchronized(this) {
7289            PendingIntentRecord rec = (PendingIntentRecord)sender;
7290            try {
7291                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7292                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7293                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7294                    String msg = "Permission Denial: cancelIntentSender() from pid="
7295                        + Binder.getCallingPid()
7296                        + ", uid=" + Binder.getCallingUid()
7297                        + " is not allowed to cancel packges "
7298                        + rec.key.packageName;
7299                    Slog.w(TAG, msg);
7300                    throw new SecurityException(msg);
7301                }
7302            } catch (RemoteException e) {
7303                throw new SecurityException(e);
7304            }
7305            cancelIntentSenderLocked(rec, true);
7306        }
7307    }
7308
7309    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7310        rec.canceled = true;
7311        mIntentSenderRecords.remove(rec.key);
7312        if (cleanActivity && rec.key.activity != null) {
7313            rec.key.activity.pendingResults.remove(rec.ref);
7314        }
7315    }
7316
7317    @Override
7318    public String getPackageForIntentSender(IIntentSender pendingResult) {
7319        if (!(pendingResult instanceof PendingIntentRecord)) {
7320            return null;
7321        }
7322        try {
7323            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7324            return res.key.packageName;
7325        } catch (ClassCastException e) {
7326        }
7327        return null;
7328    }
7329
7330    @Override
7331    public int getUidForIntentSender(IIntentSender sender) {
7332        if (sender instanceof PendingIntentRecord) {
7333            try {
7334                PendingIntentRecord res = (PendingIntentRecord)sender;
7335                return res.uid;
7336            } catch (ClassCastException e) {
7337            }
7338        }
7339        return -1;
7340    }
7341
7342    @Override
7343    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7344        if (!(pendingResult instanceof PendingIntentRecord)) {
7345            return false;
7346        }
7347        try {
7348            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7349            if (res.key.allIntents == null) {
7350                return false;
7351            }
7352            for (int i=0; i<res.key.allIntents.length; i++) {
7353                Intent intent = res.key.allIntents[i];
7354                if (intent.getPackage() != null && intent.getComponent() != null) {
7355                    return false;
7356                }
7357            }
7358            return true;
7359        } catch (ClassCastException e) {
7360        }
7361        return false;
7362    }
7363
7364    @Override
7365    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7366        if (!(pendingResult instanceof PendingIntentRecord)) {
7367            return false;
7368        }
7369        try {
7370            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7371            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7372                return true;
7373            }
7374            return false;
7375        } catch (ClassCastException e) {
7376        }
7377        return false;
7378    }
7379
7380    @Override
7381    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7382        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7383                "getIntentForIntentSender()");
7384        if (!(pendingResult instanceof PendingIntentRecord)) {
7385            return null;
7386        }
7387        try {
7388            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7389            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7390        } catch (ClassCastException e) {
7391        }
7392        return null;
7393    }
7394
7395    @Override
7396    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7397        if (!(pendingResult instanceof PendingIntentRecord)) {
7398            return null;
7399        }
7400        try {
7401            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7402            synchronized (this) {
7403                return getTagForIntentSenderLocked(res, prefix);
7404            }
7405        } catch (ClassCastException e) {
7406        }
7407        return null;
7408    }
7409
7410    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7411        final Intent intent = res.key.requestIntent;
7412        if (intent != null) {
7413            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7414                    || res.lastTagPrefix.equals(prefix))) {
7415                return res.lastTag;
7416            }
7417            res.lastTagPrefix = prefix;
7418            final StringBuilder sb = new StringBuilder(128);
7419            if (prefix != null) {
7420                sb.append(prefix);
7421            }
7422            if (intent.getAction() != null) {
7423                sb.append(intent.getAction());
7424            } else if (intent.getComponent() != null) {
7425                intent.getComponent().appendShortString(sb);
7426            } else {
7427                sb.append("?");
7428            }
7429            return res.lastTag = sb.toString();
7430        }
7431        return null;
7432    }
7433
7434    @Override
7435    public void setProcessLimit(int max) {
7436        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7437                "setProcessLimit()");
7438        synchronized (this) {
7439            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7440            mProcessLimitOverride = max;
7441        }
7442        trimApplications();
7443    }
7444
7445    @Override
7446    public int getProcessLimit() {
7447        synchronized (this) {
7448            return mProcessLimitOverride;
7449        }
7450    }
7451
7452    void foregroundTokenDied(ForegroundToken token) {
7453        synchronized (ActivityManagerService.this) {
7454            synchronized (mPidsSelfLocked) {
7455                ForegroundToken cur
7456                    = mForegroundProcesses.get(token.pid);
7457                if (cur != token) {
7458                    return;
7459                }
7460                mForegroundProcesses.remove(token.pid);
7461                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7462                if (pr == null) {
7463                    return;
7464                }
7465                pr.forcingToForeground = null;
7466                updateProcessForegroundLocked(pr, false, false);
7467            }
7468            updateOomAdjLocked();
7469        }
7470    }
7471
7472    @Override
7473    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7474        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7475                "setProcessForeground()");
7476        synchronized(this) {
7477            boolean changed = false;
7478
7479            synchronized (mPidsSelfLocked) {
7480                ProcessRecord pr = mPidsSelfLocked.get(pid);
7481                if (pr == null && isForeground) {
7482                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7483                    return;
7484                }
7485                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7486                if (oldToken != null) {
7487                    oldToken.token.unlinkToDeath(oldToken, 0);
7488                    mForegroundProcesses.remove(pid);
7489                    if (pr != null) {
7490                        pr.forcingToForeground = null;
7491                    }
7492                    changed = true;
7493                }
7494                if (isForeground && token != null) {
7495                    ForegroundToken newToken = new ForegroundToken() {
7496                        @Override
7497                        public void binderDied() {
7498                            foregroundTokenDied(this);
7499                        }
7500                    };
7501                    newToken.pid = pid;
7502                    newToken.token = token;
7503                    try {
7504                        token.linkToDeath(newToken, 0);
7505                        mForegroundProcesses.put(pid, newToken);
7506                        pr.forcingToForeground = token;
7507                        changed = true;
7508                    } catch (RemoteException e) {
7509                        // If the process died while doing this, we will later
7510                        // do the cleanup with the process death link.
7511                    }
7512                }
7513            }
7514
7515            if (changed) {
7516                updateOomAdjLocked();
7517            }
7518        }
7519    }
7520
7521    @Override
7522    public boolean isAppForeground(int uid) throws RemoteException {
7523        synchronized (this) {
7524            UidRecord uidRec = mActiveUids.get(uid);
7525            if (uidRec == null || uidRec.idle) {
7526                return false;
7527            }
7528            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7529        }
7530    }
7531
7532    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7533    // be guarded by permission checking.
7534    int getUidState(int uid) {
7535        synchronized (this) {
7536            UidRecord uidRec = mActiveUids.get(uid);
7537            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7538        }
7539    }
7540
7541    @Override
7542    public boolean isInMultiWindowMode(IBinder token) {
7543        final long origId = Binder.clearCallingIdentity();
7544        try {
7545            synchronized(this) {
7546                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7547                if (r == null) {
7548                    return false;
7549                }
7550                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7551                return !r.task.mFullscreen;
7552            }
7553        } finally {
7554            Binder.restoreCallingIdentity(origId);
7555        }
7556    }
7557
7558    @Override
7559    public boolean isInPictureInPictureMode(IBinder token) {
7560        final long origId = Binder.clearCallingIdentity();
7561        try {
7562            synchronized(this) {
7563                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7564                if (stack == null) {
7565                    return false;
7566                }
7567                return stack.mStackId == PINNED_STACK_ID;
7568            }
7569        } finally {
7570            Binder.restoreCallingIdentity(origId);
7571        }
7572    }
7573
7574    @Override
7575    public void enterPictureInPictureMode(IBinder token) {
7576        final long origId = Binder.clearCallingIdentity();
7577        try {
7578            synchronized(this) {
7579                if (!mSupportsPictureInPicture) {
7580                    throw new IllegalStateException("enterPictureInPictureMode: "
7581                            + "Device doesn't support picture-in-picture mode.");
7582                }
7583
7584                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7585
7586                if (r == null) {
7587                    throw new IllegalStateException("enterPictureInPictureMode: "
7588                            + "Can't find activity for token=" + token);
7589                }
7590
7591                if (!r.supportsPictureInPicture()) {
7592                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7593                            + "Picture-In-Picture not supported for r=" + r);
7594                }
7595
7596                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7597                // current bounds.
7598                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7599                final Rect bounds = (pinnedStack != null)
7600                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7601
7602                mStackSupervisor.moveActivityToPinnedStackLocked(
7603                        r, "enterPictureInPictureMode", bounds);
7604            }
7605        } finally {
7606            Binder.restoreCallingIdentity(origId);
7607        }
7608    }
7609
7610    // =========================================================
7611    // PROCESS INFO
7612    // =========================================================
7613
7614    static class ProcessInfoService extends IProcessInfoService.Stub {
7615        final ActivityManagerService mActivityManagerService;
7616        ProcessInfoService(ActivityManagerService activityManagerService) {
7617            mActivityManagerService = activityManagerService;
7618        }
7619
7620        @Override
7621        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7622            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7623                    /*in*/ pids, /*out*/ states, null);
7624        }
7625
7626        @Override
7627        public void getProcessStatesAndOomScoresFromPids(
7628                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7629            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7630                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7631        }
7632    }
7633
7634    /**
7635     * For each PID in the given input array, write the current process state
7636     * for that process into the states array, or -1 to indicate that no
7637     * process with the given PID exists. If scores array is provided, write
7638     * the oom score for the process into the scores array, with INVALID_ADJ
7639     * indicating the PID doesn't exist.
7640     */
7641    public void getProcessStatesAndOomScoresForPIDs(
7642            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7643        if (scores != null) {
7644            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7645                    "getProcessStatesAndOomScoresForPIDs()");
7646        }
7647
7648        if (pids == null) {
7649            throw new NullPointerException("pids");
7650        } else if (states == null) {
7651            throw new NullPointerException("states");
7652        } else if (pids.length != states.length) {
7653            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7654        } else if (scores != null && pids.length != scores.length) {
7655            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7656        }
7657
7658        synchronized (mPidsSelfLocked) {
7659            for (int i = 0; i < pids.length; i++) {
7660                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7661                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7662                        pr.curProcState;
7663                if (scores != null) {
7664                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7665                }
7666            }
7667        }
7668    }
7669
7670    // =========================================================
7671    // PERMISSIONS
7672    // =========================================================
7673
7674    static class PermissionController extends IPermissionController.Stub {
7675        ActivityManagerService mActivityManagerService;
7676        PermissionController(ActivityManagerService activityManagerService) {
7677            mActivityManagerService = activityManagerService;
7678        }
7679
7680        @Override
7681        public boolean checkPermission(String permission, int pid, int uid) {
7682            return mActivityManagerService.checkPermission(permission, pid,
7683                    uid) == PackageManager.PERMISSION_GRANTED;
7684        }
7685
7686        @Override
7687        public String[] getPackagesForUid(int uid) {
7688            return mActivityManagerService.mContext.getPackageManager()
7689                    .getPackagesForUid(uid);
7690        }
7691
7692        @Override
7693        public boolean isRuntimePermission(String permission) {
7694            try {
7695                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7696                        .getPermissionInfo(permission, 0);
7697                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7698            } catch (NameNotFoundException nnfe) {
7699                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7700            }
7701            return false;
7702        }
7703    }
7704
7705    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7706        @Override
7707        public int checkComponentPermission(String permission, int pid, int uid,
7708                int owningUid, boolean exported) {
7709            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7710                    owningUid, exported);
7711        }
7712
7713        @Override
7714        public Object getAMSLock() {
7715            return ActivityManagerService.this;
7716        }
7717    }
7718
7719    /**
7720     * This can be called with or without the global lock held.
7721     */
7722    int checkComponentPermission(String permission, int pid, int uid,
7723            int owningUid, boolean exported) {
7724        if (pid == MY_PID) {
7725            return PackageManager.PERMISSION_GRANTED;
7726        }
7727        return ActivityManager.checkComponentPermission(permission, uid,
7728                owningUid, exported);
7729    }
7730
7731    /**
7732     * As the only public entry point for permissions checking, this method
7733     * can enforce the semantic that requesting a check on a null global
7734     * permission is automatically denied.  (Internally a null permission
7735     * string is used when calling {@link #checkComponentPermission} in cases
7736     * when only uid-based security is needed.)
7737     *
7738     * This can be called with or without the global lock held.
7739     */
7740    @Override
7741    public int checkPermission(String permission, int pid, int uid) {
7742        if (permission == null) {
7743            return PackageManager.PERMISSION_DENIED;
7744        }
7745        return checkComponentPermission(permission, pid, uid, -1, true);
7746    }
7747
7748    @Override
7749    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7750        if (permission == null) {
7751            return PackageManager.PERMISSION_DENIED;
7752        }
7753
7754        // We might be performing an operation on behalf of an indirect binder
7755        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7756        // client identity accordingly before proceeding.
7757        Identity tlsIdentity = sCallerIdentity.get();
7758        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7759            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7760                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7761            uid = tlsIdentity.uid;
7762            pid = tlsIdentity.pid;
7763        }
7764
7765        return checkComponentPermission(permission, pid, uid, -1, true);
7766    }
7767
7768    /**
7769     * Binder IPC calls go through the public entry point.
7770     * This can be called with or without the global lock held.
7771     */
7772    int checkCallingPermission(String permission) {
7773        return checkPermission(permission,
7774                Binder.getCallingPid(),
7775                UserHandle.getAppId(Binder.getCallingUid()));
7776    }
7777
7778    /**
7779     * This can be called with or without the global lock held.
7780     */
7781    void enforceCallingPermission(String permission, String func) {
7782        if (checkCallingPermission(permission)
7783                == PackageManager.PERMISSION_GRANTED) {
7784            return;
7785        }
7786
7787        String msg = "Permission Denial: " + func + " from pid="
7788                + Binder.getCallingPid()
7789                + ", uid=" + Binder.getCallingUid()
7790                + " requires " + permission;
7791        Slog.w(TAG, msg);
7792        throw new SecurityException(msg);
7793    }
7794
7795    /**
7796     * Determine if UID is holding permissions required to access {@link Uri} in
7797     * the given {@link ProviderInfo}. Final permission checking is always done
7798     * in {@link ContentProvider}.
7799     */
7800    private final boolean checkHoldingPermissionsLocked(
7801            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7802        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7803                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7804        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7805            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7806                    != PERMISSION_GRANTED) {
7807                return false;
7808            }
7809        }
7810        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7811    }
7812
7813    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7814            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7815        if (pi.applicationInfo.uid == uid) {
7816            return true;
7817        } else if (!pi.exported) {
7818            return false;
7819        }
7820
7821        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7822        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7823        try {
7824            // check if target holds top-level <provider> permissions
7825            if (!readMet && pi.readPermission != null && considerUidPermissions
7826                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7827                readMet = true;
7828            }
7829            if (!writeMet && pi.writePermission != null && considerUidPermissions
7830                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7831                writeMet = true;
7832            }
7833
7834            // track if unprotected read/write is allowed; any denied
7835            // <path-permission> below removes this ability
7836            boolean allowDefaultRead = pi.readPermission == null;
7837            boolean allowDefaultWrite = pi.writePermission == null;
7838
7839            // check if target holds any <path-permission> that match uri
7840            final PathPermission[] pps = pi.pathPermissions;
7841            if (pps != null) {
7842                final String path = grantUri.uri.getPath();
7843                int i = pps.length;
7844                while (i > 0 && (!readMet || !writeMet)) {
7845                    i--;
7846                    PathPermission pp = pps[i];
7847                    if (pp.match(path)) {
7848                        if (!readMet) {
7849                            final String pprperm = pp.getReadPermission();
7850                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7851                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7852                                    + ": match=" + pp.match(path)
7853                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7854                            if (pprperm != null) {
7855                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7856                                        == PERMISSION_GRANTED) {
7857                                    readMet = true;
7858                                } else {
7859                                    allowDefaultRead = false;
7860                                }
7861                            }
7862                        }
7863                        if (!writeMet) {
7864                            final String ppwperm = pp.getWritePermission();
7865                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7866                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7867                                    + ": match=" + pp.match(path)
7868                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7869                            if (ppwperm != null) {
7870                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7871                                        == PERMISSION_GRANTED) {
7872                                    writeMet = true;
7873                                } else {
7874                                    allowDefaultWrite = false;
7875                                }
7876                            }
7877                        }
7878                    }
7879                }
7880            }
7881
7882            // grant unprotected <provider> read/write, if not blocked by
7883            // <path-permission> above
7884            if (allowDefaultRead) readMet = true;
7885            if (allowDefaultWrite) writeMet = true;
7886
7887        } catch (RemoteException e) {
7888            return false;
7889        }
7890
7891        return readMet && writeMet;
7892    }
7893
7894    public int getAppStartMode(int uid, String packageName) {
7895        synchronized (this) {
7896            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7897        }
7898    }
7899
7900    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7901            boolean allowWhenForeground) {
7902        UidRecord uidRec = mActiveUids.get(uid);
7903        if (!mLenientBackgroundCheck) {
7904            if (!allowWhenForeground || uidRec == null
7905                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7906                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7907                        packageName) != AppOpsManager.MODE_ALLOWED) {
7908                    return ActivityManager.APP_START_MODE_DELAYED;
7909                }
7910            }
7911
7912        } else if (uidRec == null || uidRec.idle) {
7913            if (callingPid >= 0) {
7914                ProcessRecord proc;
7915                synchronized (mPidsSelfLocked) {
7916                    proc = mPidsSelfLocked.get(callingPid);
7917                }
7918                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7919                    // Whoever is instigating this is in the foreground, so we will allow it
7920                    // to go through.
7921                    return ActivityManager.APP_START_MODE_NORMAL;
7922                }
7923            }
7924            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7925                    != AppOpsManager.MODE_ALLOWED) {
7926                return ActivityManager.APP_START_MODE_DELAYED;
7927            }
7928        }
7929        return ActivityManager.APP_START_MODE_NORMAL;
7930    }
7931
7932    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7933        ProviderInfo pi = null;
7934        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7935        if (cpr != null) {
7936            pi = cpr.info;
7937        } else {
7938            try {
7939                pi = AppGlobals.getPackageManager().resolveContentProvider(
7940                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7941                        userHandle);
7942            } catch (RemoteException ex) {
7943            }
7944        }
7945        return pi;
7946    }
7947
7948    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7949        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7950        if (targetUris != null) {
7951            return targetUris.get(grantUri);
7952        }
7953        return null;
7954    }
7955
7956    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7957            String targetPkg, int targetUid, GrantUri grantUri) {
7958        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7959        if (targetUris == null) {
7960            targetUris = Maps.newArrayMap();
7961            mGrantedUriPermissions.put(targetUid, targetUris);
7962        }
7963
7964        UriPermission perm = targetUris.get(grantUri);
7965        if (perm == null) {
7966            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7967            targetUris.put(grantUri, perm);
7968        }
7969
7970        return perm;
7971    }
7972
7973    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7974            final int modeFlags) {
7975        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7976        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7977                : UriPermission.STRENGTH_OWNED;
7978
7979        // Root gets to do everything.
7980        if (uid == 0) {
7981            return true;
7982        }
7983
7984        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7985        if (perms == null) return false;
7986
7987        // First look for exact match
7988        final UriPermission exactPerm = perms.get(grantUri);
7989        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7990            return true;
7991        }
7992
7993        // No exact match, look for prefixes
7994        final int N = perms.size();
7995        for (int i = 0; i < N; i++) {
7996            final UriPermission perm = perms.valueAt(i);
7997            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7998                    && perm.getStrength(modeFlags) >= minStrength) {
7999                return true;
8000            }
8001        }
8002
8003        return false;
8004    }
8005
8006    /**
8007     * @param uri This uri must NOT contain an embedded userId.
8008     * @param userId The userId in which the uri is to be resolved.
8009     */
8010    @Override
8011    public int checkUriPermission(Uri uri, int pid, int uid,
8012            final int modeFlags, int userId, IBinder callerToken) {
8013        enforceNotIsolatedCaller("checkUriPermission");
8014
8015        // Another redirected-binder-call permissions check as in
8016        // {@link checkPermissionWithToken}.
8017        Identity tlsIdentity = sCallerIdentity.get();
8018        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8019            uid = tlsIdentity.uid;
8020            pid = tlsIdentity.pid;
8021        }
8022
8023        // Our own process gets to do everything.
8024        if (pid == MY_PID) {
8025            return PackageManager.PERMISSION_GRANTED;
8026        }
8027        synchronized (this) {
8028            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8029                    ? PackageManager.PERMISSION_GRANTED
8030                    : PackageManager.PERMISSION_DENIED;
8031        }
8032    }
8033
8034    /**
8035     * Check if the targetPkg can be granted permission to access uri by
8036     * the callingUid using the given modeFlags.  Throws a security exception
8037     * if callingUid is not allowed to do this.  Returns the uid of the target
8038     * if the URI permission grant should be performed; returns -1 if it is not
8039     * needed (for example targetPkg already has permission to access the URI).
8040     * If you already know the uid of the target, you can supply it in
8041     * lastTargetUid else set that to -1.
8042     */
8043    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8044            final int modeFlags, int lastTargetUid) {
8045        if (!Intent.isAccessUriMode(modeFlags)) {
8046            return -1;
8047        }
8048
8049        if (targetPkg != null) {
8050            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8051                    "Checking grant " + targetPkg + " permission to " + grantUri);
8052        }
8053
8054        final IPackageManager pm = AppGlobals.getPackageManager();
8055
8056        // If this is not a content: uri, we can't do anything with it.
8057        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8058            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8059                    "Can't grant URI permission for non-content URI: " + grantUri);
8060            return -1;
8061        }
8062
8063        final String authority = grantUri.uri.getAuthority();
8064        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8065                MATCH_DEBUG_TRIAGED_MISSING);
8066        if (pi == null) {
8067            Slog.w(TAG, "No content provider found for permission check: " +
8068                    grantUri.uri.toSafeString());
8069            return -1;
8070        }
8071
8072        int targetUid = lastTargetUid;
8073        if (targetUid < 0 && targetPkg != null) {
8074            try {
8075                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8076                        UserHandle.getUserId(callingUid));
8077                if (targetUid < 0) {
8078                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079                            "Can't grant URI permission no uid for: " + targetPkg);
8080                    return -1;
8081                }
8082            } catch (RemoteException ex) {
8083                return -1;
8084            }
8085        }
8086
8087        if (targetUid >= 0) {
8088            // First...  does the target actually need this permission?
8089            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8090                // No need to grant the target this permission.
8091                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8092                        "Target " + targetPkg + " already has full permission to " + grantUri);
8093                return -1;
8094            }
8095        } else {
8096            // First...  there is no target package, so can anyone access it?
8097            boolean allowed = pi.exported;
8098            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8099                if (pi.readPermission != null) {
8100                    allowed = false;
8101                }
8102            }
8103            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8104                if (pi.writePermission != null) {
8105                    allowed = false;
8106                }
8107            }
8108            if (allowed) {
8109                return -1;
8110            }
8111        }
8112
8113        /* There is a special cross user grant if:
8114         * - The target is on another user.
8115         * - Apps on the current user can access the uri without any uid permissions.
8116         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8117         * grant uri permissions.
8118         */
8119        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8120                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8121                modeFlags, false /*without considering the uid permissions*/);
8122
8123        // Second...  is the provider allowing granting of URI permissions?
8124        if (!specialCrossUserGrant) {
8125            if (!pi.grantUriPermissions) {
8126                throw new SecurityException("Provider " + pi.packageName
8127                        + "/" + pi.name
8128                        + " does not allow granting of Uri permissions (uri "
8129                        + grantUri + ")");
8130            }
8131            if (pi.uriPermissionPatterns != null) {
8132                final int N = pi.uriPermissionPatterns.length;
8133                boolean allowed = false;
8134                for (int i=0; i<N; i++) {
8135                    if (pi.uriPermissionPatterns[i] != null
8136                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8137                        allowed = true;
8138                        break;
8139                    }
8140                }
8141                if (!allowed) {
8142                    throw new SecurityException("Provider " + pi.packageName
8143                            + "/" + pi.name
8144                            + " does not allow granting of permission to path of Uri "
8145                            + grantUri);
8146                }
8147            }
8148        }
8149
8150        // Third...  does the caller itself have permission to access
8151        // this uri?
8152        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8153            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8154                // Require they hold a strong enough Uri permission
8155                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8156                    throw new SecurityException("Uid " + callingUid
8157                            + " does not have permission to uri " + grantUri);
8158                }
8159            }
8160        }
8161        return targetUid;
8162    }
8163
8164    /**
8165     * @param uri This uri must NOT contain an embedded userId.
8166     * @param userId The userId in which the uri is to be resolved.
8167     */
8168    @Override
8169    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8170            final int modeFlags, int userId) {
8171        enforceNotIsolatedCaller("checkGrantUriPermission");
8172        synchronized(this) {
8173            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8174                    new GrantUri(userId, uri, false), modeFlags, -1);
8175        }
8176    }
8177
8178    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8179            final int modeFlags, UriPermissionOwner owner) {
8180        if (!Intent.isAccessUriMode(modeFlags)) {
8181            return;
8182        }
8183
8184        // So here we are: the caller has the assumed permission
8185        // to the uri, and the target doesn't.  Let's now give this to
8186        // the target.
8187
8188        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8189                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8190
8191        final String authority = grantUri.uri.getAuthority();
8192        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8193                MATCH_DEBUG_TRIAGED_MISSING);
8194        if (pi == null) {
8195            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8196            return;
8197        }
8198
8199        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8200            grantUri.prefix = true;
8201        }
8202        final UriPermission perm = findOrCreateUriPermissionLocked(
8203                pi.packageName, targetPkg, targetUid, grantUri);
8204        perm.grantModes(modeFlags, owner);
8205    }
8206
8207    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8208            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8209        if (targetPkg == null) {
8210            throw new NullPointerException("targetPkg");
8211        }
8212        int targetUid;
8213        final IPackageManager pm = AppGlobals.getPackageManager();
8214        try {
8215            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8216        } catch (RemoteException ex) {
8217            return;
8218        }
8219
8220        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8221                targetUid);
8222        if (targetUid < 0) {
8223            return;
8224        }
8225
8226        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8227                owner);
8228    }
8229
8230    static class NeededUriGrants extends ArrayList<GrantUri> {
8231        final String targetPkg;
8232        final int targetUid;
8233        final int flags;
8234
8235        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8236            this.targetPkg = targetPkg;
8237            this.targetUid = targetUid;
8238            this.flags = flags;
8239        }
8240    }
8241
8242    /**
8243     * Like checkGrantUriPermissionLocked, but takes an Intent.
8244     */
8245    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8246            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8247        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8248                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8249                + " clip=" + (intent != null ? intent.getClipData() : null)
8250                + " from " + intent + "; flags=0x"
8251                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8252
8253        if (targetPkg == null) {
8254            throw new NullPointerException("targetPkg");
8255        }
8256
8257        if (intent == null) {
8258            return null;
8259        }
8260        Uri data = intent.getData();
8261        ClipData clip = intent.getClipData();
8262        if (data == null && clip == null) {
8263            return null;
8264        }
8265        // Default userId for uris in the intent (if they don't specify it themselves)
8266        int contentUserHint = intent.getContentUserHint();
8267        if (contentUserHint == UserHandle.USER_CURRENT) {
8268            contentUserHint = UserHandle.getUserId(callingUid);
8269        }
8270        final IPackageManager pm = AppGlobals.getPackageManager();
8271        int targetUid;
8272        if (needed != null) {
8273            targetUid = needed.targetUid;
8274        } else {
8275            try {
8276                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8277                        targetUserId);
8278            } catch (RemoteException ex) {
8279                return null;
8280            }
8281            if (targetUid < 0) {
8282                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8283                        "Can't grant URI permission no uid for: " + targetPkg
8284                        + " on user " + targetUserId);
8285                return null;
8286            }
8287        }
8288        if (data != null) {
8289            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8290            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8291                    targetUid);
8292            if (targetUid > 0) {
8293                if (needed == null) {
8294                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8295                }
8296                needed.add(grantUri);
8297            }
8298        }
8299        if (clip != null) {
8300            for (int i=0; i<clip.getItemCount(); i++) {
8301                Uri uri = clip.getItemAt(i).getUri();
8302                if (uri != null) {
8303                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8304                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8305                            targetUid);
8306                    if (targetUid > 0) {
8307                        if (needed == null) {
8308                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8309                        }
8310                        needed.add(grantUri);
8311                    }
8312                } else {
8313                    Intent clipIntent = clip.getItemAt(i).getIntent();
8314                    if (clipIntent != null) {
8315                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8316                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8317                        if (newNeeded != null) {
8318                            needed = newNeeded;
8319                        }
8320                    }
8321                }
8322            }
8323        }
8324
8325        return needed;
8326    }
8327
8328    /**
8329     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8330     */
8331    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8332            UriPermissionOwner owner) {
8333        if (needed != null) {
8334            for (int i=0; i<needed.size(); i++) {
8335                GrantUri grantUri = needed.get(i);
8336                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8337                        grantUri, needed.flags, owner);
8338            }
8339        }
8340    }
8341
8342    void grantUriPermissionFromIntentLocked(int callingUid,
8343            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8344        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8345                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8346        if (needed == null) {
8347            return;
8348        }
8349
8350        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8351    }
8352
8353    /**
8354     * @param uri This uri must NOT contain an embedded userId.
8355     * @param userId The userId in which the uri is to be resolved.
8356     */
8357    @Override
8358    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8359            final int modeFlags, int userId) {
8360        enforceNotIsolatedCaller("grantUriPermission");
8361        GrantUri grantUri = new GrantUri(userId, uri, false);
8362        synchronized(this) {
8363            final ProcessRecord r = getRecordForAppLocked(caller);
8364            if (r == null) {
8365                throw new SecurityException("Unable to find app for caller "
8366                        + caller
8367                        + " when granting permission to uri " + grantUri);
8368            }
8369            if (targetPkg == null) {
8370                throw new IllegalArgumentException("null target");
8371            }
8372            if (grantUri == null) {
8373                throw new IllegalArgumentException("null uri");
8374            }
8375
8376            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8377                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8378                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8379                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8380
8381            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8382                    UserHandle.getUserId(r.uid));
8383        }
8384    }
8385
8386    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8387        if (perm.modeFlags == 0) {
8388            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8389                    perm.targetUid);
8390            if (perms != null) {
8391                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8392                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8393
8394                perms.remove(perm.uri);
8395                if (perms.isEmpty()) {
8396                    mGrantedUriPermissions.remove(perm.targetUid);
8397                }
8398            }
8399        }
8400    }
8401
8402    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8403        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8404                "Revoking all granted permissions to " + grantUri);
8405
8406        final IPackageManager pm = AppGlobals.getPackageManager();
8407        final String authority = grantUri.uri.getAuthority();
8408        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8409                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8410        if (pi == null) {
8411            Slog.w(TAG, "No content provider found for permission revoke: "
8412                    + grantUri.toSafeString());
8413            return;
8414        }
8415
8416        // Does the caller have this permission on the URI?
8417        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8418            // If they don't have direct access to the URI, then revoke any
8419            // ownerless URI permissions that have been granted to them.
8420            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8421            if (perms != null) {
8422                boolean persistChanged = false;
8423                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8424                    final UriPermission perm = it.next();
8425                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8426                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8427                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8428                                "Revoking non-owned " + perm.targetUid
8429                                + " permission to " + perm.uri);
8430                        persistChanged |= perm.revokeModes(
8431                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8432                        if (perm.modeFlags == 0) {
8433                            it.remove();
8434                        }
8435                    }
8436                }
8437                if (perms.isEmpty()) {
8438                    mGrantedUriPermissions.remove(callingUid);
8439                }
8440                if (persistChanged) {
8441                    schedulePersistUriGrants();
8442                }
8443            }
8444            return;
8445        }
8446
8447        boolean persistChanged = false;
8448
8449        // Go through all of the permissions and remove any that match.
8450        int N = mGrantedUriPermissions.size();
8451        for (int i = 0; i < N; i++) {
8452            final int targetUid = mGrantedUriPermissions.keyAt(i);
8453            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8454
8455            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8456                final UriPermission perm = it.next();
8457                if (perm.uri.sourceUserId == grantUri.sourceUserId
8458                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8459                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8460                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8461                    persistChanged |= perm.revokeModes(
8462                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8463                    if (perm.modeFlags == 0) {
8464                        it.remove();
8465                    }
8466                }
8467            }
8468
8469            if (perms.isEmpty()) {
8470                mGrantedUriPermissions.remove(targetUid);
8471                N--;
8472                i--;
8473            }
8474        }
8475
8476        if (persistChanged) {
8477            schedulePersistUriGrants();
8478        }
8479    }
8480
8481    /**
8482     * @param uri This uri must NOT contain an embedded userId.
8483     * @param userId The userId in which the uri is to be resolved.
8484     */
8485    @Override
8486    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8487            int userId) {
8488        enforceNotIsolatedCaller("revokeUriPermission");
8489        synchronized(this) {
8490            final ProcessRecord r = getRecordForAppLocked(caller);
8491            if (r == null) {
8492                throw new SecurityException("Unable to find app for caller "
8493                        + caller
8494                        + " when revoking permission to uri " + uri);
8495            }
8496            if (uri == null) {
8497                Slog.w(TAG, "revokeUriPermission: null uri");
8498                return;
8499            }
8500
8501            if (!Intent.isAccessUriMode(modeFlags)) {
8502                return;
8503            }
8504
8505            final String authority = uri.getAuthority();
8506            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8507                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8508            if (pi == null) {
8509                Slog.w(TAG, "No content provider found for permission revoke: "
8510                        + uri.toSafeString());
8511                return;
8512            }
8513
8514            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8515        }
8516    }
8517
8518    /**
8519     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8520     * given package.
8521     *
8522     * @param packageName Package name to match, or {@code null} to apply to all
8523     *            packages.
8524     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8525     *            to all users.
8526     * @param persistable If persistable grants should be removed.
8527     */
8528    private void removeUriPermissionsForPackageLocked(
8529            String packageName, int userHandle, boolean persistable) {
8530        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8531            throw new IllegalArgumentException("Must narrow by either package or user");
8532        }
8533
8534        boolean persistChanged = false;
8535
8536        int N = mGrantedUriPermissions.size();
8537        for (int i = 0; i < N; i++) {
8538            final int targetUid = mGrantedUriPermissions.keyAt(i);
8539            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8540
8541            // Only inspect grants matching user
8542            if (userHandle == UserHandle.USER_ALL
8543                    || userHandle == UserHandle.getUserId(targetUid)) {
8544                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8545                    final UriPermission perm = it.next();
8546
8547                    // Only inspect grants matching package
8548                    if (packageName == null || perm.sourcePkg.equals(packageName)
8549                            || perm.targetPkg.equals(packageName)) {
8550                        persistChanged |= perm.revokeModes(persistable
8551                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8552
8553                        // Only remove when no modes remain; any persisted grants
8554                        // will keep this alive.
8555                        if (perm.modeFlags == 0) {
8556                            it.remove();
8557                        }
8558                    }
8559                }
8560
8561                if (perms.isEmpty()) {
8562                    mGrantedUriPermissions.remove(targetUid);
8563                    N--;
8564                    i--;
8565                }
8566            }
8567        }
8568
8569        if (persistChanged) {
8570            schedulePersistUriGrants();
8571        }
8572    }
8573
8574    @Override
8575    public IBinder newUriPermissionOwner(String name) {
8576        enforceNotIsolatedCaller("newUriPermissionOwner");
8577        synchronized(this) {
8578            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8579            return owner.getExternalTokenLocked();
8580        }
8581    }
8582
8583    @Override
8584    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8585        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8586        synchronized(this) {
8587            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8588            if (r == null) {
8589                throw new IllegalArgumentException("Activity does not exist; token="
8590                        + activityToken);
8591            }
8592            return r.getUriPermissionsLocked().getExternalTokenLocked();
8593        }
8594    }
8595    /**
8596     * @param uri This uri must NOT contain an embedded userId.
8597     * @param sourceUserId The userId in which the uri is to be resolved.
8598     * @param targetUserId The userId of the app that receives the grant.
8599     */
8600    @Override
8601    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8602            final int modeFlags, int sourceUserId, int targetUserId) {
8603        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8604                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8605                "grantUriPermissionFromOwner", null);
8606        synchronized(this) {
8607            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8608            if (owner == null) {
8609                throw new IllegalArgumentException("Unknown owner: " + token);
8610            }
8611            if (fromUid != Binder.getCallingUid()) {
8612                if (Binder.getCallingUid() != Process.myUid()) {
8613                    // Only system code can grant URI permissions on behalf
8614                    // of other users.
8615                    throw new SecurityException("nice try");
8616                }
8617            }
8618            if (targetPkg == null) {
8619                throw new IllegalArgumentException("null target");
8620            }
8621            if (uri == null) {
8622                throw new IllegalArgumentException("null uri");
8623            }
8624
8625            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8626                    modeFlags, owner, targetUserId);
8627        }
8628    }
8629
8630    /**
8631     * @param uri This uri must NOT contain an embedded userId.
8632     * @param userId The userId in which the uri is to be resolved.
8633     */
8634    @Override
8635    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8636        synchronized(this) {
8637            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8638            if (owner == null) {
8639                throw new IllegalArgumentException("Unknown owner: " + token);
8640            }
8641
8642            if (uri == null) {
8643                owner.removeUriPermissionsLocked(mode);
8644            } else {
8645                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8646                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8647            }
8648        }
8649    }
8650
8651    private void schedulePersistUriGrants() {
8652        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8653            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8654                    10 * DateUtils.SECOND_IN_MILLIS);
8655        }
8656    }
8657
8658    private void writeGrantedUriPermissions() {
8659        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8660
8661        // Snapshot permissions so we can persist without lock
8662        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8663        synchronized (this) {
8664            final int size = mGrantedUriPermissions.size();
8665            for (int i = 0; i < size; i++) {
8666                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8667                for (UriPermission perm : perms.values()) {
8668                    if (perm.persistedModeFlags != 0) {
8669                        persist.add(perm.snapshot());
8670                    }
8671                }
8672            }
8673        }
8674
8675        FileOutputStream fos = null;
8676        try {
8677            fos = mGrantFile.startWrite();
8678
8679            XmlSerializer out = new FastXmlSerializer();
8680            out.setOutput(fos, StandardCharsets.UTF_8.name());
8681            out.startDocument(null, true);
8682            out.startTag(null, TAG_URI_GRANTS);
8683            for (UriPermission.Snapshot perm : persist) {
8684                out.startTag(null, TAG_URI_GRANT);
8685                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8686                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8687                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8688                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8689                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8690                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8691                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8692                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8693                out.endTag(null, TAG_URI_GRANT);
8694            }
8695            out.endTag(null, TAG_URI_GRANTS);
8696            out.endDocument();
8697
8698            mGrantFile.finishWrite(fos);
8699        } catch (IOException e) {
8700            if (fos != null) {
8701                mGrantFile.failWrite(fos);
8702            }
8703        }
8704    }
8705
8706    private void readGrantedUriPermissionsLocked() {
8707        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8708
8709        final long now = System.currentTimeMillis();
8710
8711        FileInputStream fis = null;
8712        try {
8713            fis = mGrantFile.openRead();
8714            final XmlPullParser in = Xml.newPullParser();
8715            in.setInput(fis, StandardCharsets.UTF_8.name());
8716
8717            int type;
8718            while ((type = in.next()) != END_DOCUMENT) {
8719                final String tag = in.getName();
8720                if (type == START_TAG) {
8721                    if (TAG_URI_GRANT.equals(tag)) {
8722                        final int sourceUserId;
8723                        final int targetUserId;
8724                        final int userHandle = readIntAttribute(in,
8725                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8726                        if (userHandle != UserHandle.USER_NULL) {
8727                            // For backwards compatibility.
8728                            sourceUserId = userHandle;
8729                            targetUserId = userHandle;
8730                        } else {
8731                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8732                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8733                        }
8734                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8735                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8736                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8737                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8738                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8739                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8740
8741                        // Sanity check that provider still belongs to source package
8742                        // Both direct boot aware and unaware packages are fine as we
8743                        // will do filtering at query time to avoid multiple parsing.
8744                        final ProviderInfo pi = getProviderInfoLocked(
8745                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8746                                        | MATCH_DIRECT_BOOT_UNAWARE);
8747                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8748                            int targetUid = -1;
8749                            try {
8750                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8751                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8752                            } catch (RemoteException e) {
8753                            }
8754                            if (targetUid != -1) {
8755                                final UriPermission perm = findOrCreateUriPermissionLocked(
8756                                        sourcePkg, targetPkg, targetUid,
8757                                        new GrantUri(sourceUserId, uri, prefix));
8758                                perm.initPersistedModes(modeFlags, createdTime);
8759                            }
8760                        } else {
8761                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8762                                    + " but instead found " + pi);
8763                        }
8764                    }
8765                }
8766            }
8767        } catch (FileNotFoundException e) {
8768            // Missing grants is okay
8769        } catch (IOException e) {
8770            Slog.wtf(TAG, "Failed reading Uri grants", e);
8771        } catch (XmlPullParserException e) {
8772            Slog.wtf(TAG, "Failed reading Uri grants", e);
8773        } finally {
8774            IoUtils.closeQuietly(fis);
8775        }
8776    }
8777
8778    /**
8779     * @param uri This uri must NOT contain an embedded userId.
8780     * @param userId The userId in which the uri is to be resolved.
8781     */
8782    @Override
8783    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8784        enforceNotIsolatedCaller("takePersistableUriPermission");
8785
8786        Preconditions.checkFlagsArgument(modeFlags,
8787                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8788
8789        synchronized (this) {
8790            final int callingUid = Binder.getCallingUid();
8791            boolean persistChanged = false;
8792            GrantUri grantUri = new GrantUri(userId, uri, false);
8793
8794            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8795                    new GrantUri(userId, uri, false));
8796            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8797                    new GrantUri(userId, uri, true));
8798
8799            final boolean exactValid = (exactPerm != null)
8800                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8801            final boolean prefixValid = (prefixPerm != null)
8802                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8803
8804            if (!(exactValid || prefixValid)) {
8805                throw new SecurityException("No persistable permission grants found for UID "
8806                        + callingUid + " and Uri " + grantUri.toSafeString());
8807            }
8808
8809            if (exactValid) {
8810                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8811            }
8812            if (prefixValid) {
8813                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8814            }
8815
8816            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8817
8818            if (persistChanged) {
8819                schedulePersistUriGrants();
8820            }
8821        }
8822    }
8823
8824    /**
8825     * @param uri This uri must NOT contain an embedded userId.
8826     * @param userId The userId in which the uri is to be resolved.
8827     */
8828    @Override
8829    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8830        enforceNotIsolatedCaller("releasePersistableUriPermission");
8831
8832        Preconditions.checkFlagsArgument(modeFlags,
8833                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8834
8835        synchronized (this) {
8836            final int callingUid = Binder.getCallingUid();
8837            boolean persistChanged = false;
8838
8839            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8840                    new GrantUri(userId, uri, false));
8841            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8842                    new GrantUri(userId, uri, true));
8843            if (exactPerm == null && prefixPerm == null) {
8844                throw new SecurityException("No permission grants found for UID " + callingUid
8845                        + " and Uri " + uri.toSafeString());
8846            }
8847
8848            if (exactPerm != null) {
8849                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8850                removeUriPermissionIfNeededLocked(exactPerm);
8851            }
8852            if (prefixPerm != null) {
8853                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8854                removeUriPermissionIfNeededLocked(prefixPerm);
8855            }
8856
8857            if (persistChanged) {
8858                schedulePersistUriGrants();
8859            }
8860        }
8861    }
8862
8863    /**
8864     * Prune any older {@link UriPermission} for the given UID until outstanding
8865     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8866     *
8867     * @return if any mutations occured that require persisting.
8868     */
8869    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8870        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8871        if (perms == null) return false;
8872        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8873
8874        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8875        for (UriPermission perm : perms.values()) {
8876            if (perm.persistedModeFlags != 0) {
8877                persisted.add(perm);
8878            }
8879        }
8880
8881        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8882        if (trimCount <= 0) return false;
8883
8884        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8885        for (int i = 0; i < trimCount; i++) {
8886            final UriPermission perm = persisted.get(i);
8887
8888            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8889                    "Trimming grant created at " + perm.persistedCreateTime);
8890
8891            perm.releasePersistableModes(~0);
8892            removeUriPermissionIfNeededLocked(perm);
8893        }
8894
8895        return true;
8896    }
8897
8898    @Override
8899    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8900            String packageName, boolean incoming) {
8901        enforceNotIsolatedCaller("getPersistedUriPermissions");
8902        Preconditions.checkNotNull(packageName, "packageName");
8903
8904        final int callingUid = Binder.getCallingUid();
8905        final int callingUserId = UserHandle.getUserId(callingUid);
8906        final IPackageManager pm = AppGlobals.getPackageManager();
8907        try {
8908            final int packageUid = pm.getPackageUid(packageName,
8909                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8910            if (packageUid != callingUid) {
8911                throw new SecurityException(
8912                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8913            }
8914        } catch (RemoteException e) {
8915            throw new SecurityException("Failed to verify package name ownership");
8916        }
8917
8918        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8919        synchronized (this) {
8920            if (incoming) {
8921                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8922                        callingUid);
8923                if (perms == null) {
8924                    Slog.w(TAG, "No permission grants found for " + packageName);
8925                } else {
8926                    for (UriPermission perm : perms.values()) {
8927                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8928                            result.add(perm.buildPersistedPublicApiObject());
8929                        }
8930                    }
8931                }
8932            } else {
8933                final int size = mGrantedUriPermissions.size();
8934                for (int i = 0; i < size; i++) {
8935                    final ArrayMap<GrantUri, UriPermission> perms =
8936                            mGrantedUriPermissions.valueAt(i);
8937                    for (UriPermission perm : perms.values()) {
8938                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8939                            result.add(perm.buildPersistedPublicApiObject());
8940                        }
8941                    }
8942                }
8943            }
8944        }
8945        return new ParceledListSlice<android.content.UriPermission>(result);
8946    }
8947
8948    @Override
8949    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8950            String packageName, int userId) {
8951        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8952                "getGrantedUriPermissions");
8953
8954        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8955        synchronized (this) {
8956            final int size = mGrantedUriPermissions.size();
8957            for (int i = 0; i < size; i++) {
8958                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8959                for (UriPermission perm : perms.values()) {
8960                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8961                            && perm.persistedModeFlags != 0) {
8962                        result.add(perm.buildPersistedPublicApiObject());
8963                    }
8964                }
8965            }
8966        }
8967        return new ParceledListSlice<android.content.UriPermission>(result);
8968    }
8969
8970    @Override
8971    public void clearGrantedUriPermissions(String packageName, int userId) {
8972        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8973                "clearGrantedUriPermissions");
8974        removeUriPermissionsForPackageLocked(packageName, userId, true);
8975    }
8976
8977    @Override
8978    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8979        synchronized (this) {
8980            ProcessRecord app =
8981                who != null ? getRecordForAppLocked(who) : null;
8982            if (app == null) return;
8983
8984            Message msg = Message.obtain();
8985            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8986            msg.obj = app;
8987            msg.arg1 = waiting ? 1 : 0;
8988            mUiHandler.sendMessage(msg);
8989        }
8990    }
8991
8992    @Override
8993    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8994        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8995        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8996        outInfo.availMem = Process.getFreeMemory();
8997        outInfo.totalMem = Process.getTotalMemory();
8998        outInfo.threshold = homeAppMem;
8999        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9000        outInfo.hiddenAppThreshold = cachedAppMem;
9001        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9002                ProcessList.SERVICE_ADJ);
9003        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9004                ProcessList.VISIBLE_APP_ADJ);
9005        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9006                ProcessList.FOREGROUND_APP_ADJ);
9007    }
9008
9009    // =========================================================
9010    // TASK MANAGEMENT
9011    // =========================================================
9012
9013    @Override
9014    public List<IAppTask> getAppTasks(String callingPackage) {
9015        int callingUid = Binder.getCallingUid();
9016        long ident = Binder.clearCallingIdentity();
9017
9018        synchronized(this) {
9019            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9020            try {
9021                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9022
9023                final int N = mRecentTasks.size();
9024                for (int i = 0; i < N; i++) {
9025                    TaskRecord tr = mRecentTasks.get(i);
9026                    // Skip tasks that do not match the caller.  We don't need to verify
9027                    // callingPackage, because we are also limiting to callingUid and know
9028                    // that will limit to the correct security sandbox.
9029                    if (tr.effectiveUid != callingUid) {
9030                        continue;
9031                    }
9032                    Intent intent = tr.getBaseIntent();
9033                    if (intent == null ||
9034                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9035                        continue;
9036                    }
9037                    ActivityManager.RecentTaskInfo taskInfo =
9038                            createRecentTaskInfoFromTaskRecord(tr);
9039                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9040                    list.add(taskImpl);
9041                }
9042            } finally {
9043                Binder.restoreCallingIdentity(ident);
9044            }
9045            return list;
9046        }
9047    }
9048
9049    @Override
9050    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9051        final int callingUid = Binder.getCallingUid();
9052        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9053
9054        synchronized(this) {
9055            if (DEBUG_ALL) Slog.v(
9056                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9057
9058            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9059                    callingUid);
9060
9061            // TODO: Improve with MRU list from all ActivityStacks.
9062            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9063        }
9064
9065        return list;
9066    }
9067
9068    /**
9069     * Creates a new RecentTaskInfo from a TaskRecord.
9070     */
9071    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9072        // Update the task description to reflect any changes in the task stack
9073        tr.updateTaskDescription();
9074
9075        // Compose the recent task info
9076        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9077        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9078        rti.persistentId = tr.taskId;
9079        rti.baseIntent = new Intent(tr.getBaseIntent());
9080        rti.origActivity = tr.origActivity;
9081        rti.realActivity = tr.realActivity;
9082        rti.description = tr.lastDescription;
9083        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9084        rti.userId = tr.userId;
9085        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9086        rti.firstActiveTime = tr.firstActiveTime;
9087        rti.lastActiveTime = tr.lastActiveTime;
9088        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9089        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9090        rti.numActivities = 0;
9091        if (tr.mBounds != null) {
9092            rti.bounds = new Rect(tr.mBounds);
9093        }
9094        rti.isDockable = tr.canGoInDockedStack();
9095        rti.resizeMode = tr.mResizeMode;
9096
9097        ActivityRecord base = null;
9098        ActivityRecord top = null;
9099        ActivityRecord tmp;
9100
9101        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9102            tmp = tr.mActivities.get(i);
9103            if (tmp.finishing) {
9104                continue;
9105            }
9106            base = tmp;
9107            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9108                top = base;
9109            }
9110            rti.numActivities++;
9111        }
9112
9113        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9114        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9115
9116        return rti;
9117    }
9118
9119    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9120        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9121                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9122        if (!allowed) {
9123            if (checkPermission(android.Manifest.permission.GET_TASKS,
9124                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9125                // Temporary compatibility: some existing apps on the system image may
9126                // still be requesting the old permission and not switched to the new
9127                // one; if so, we'll still allow them full access.  This means we need
9128                // to see if they are holding the old permission and are a system app.
9129                try {
9130                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9131                        allowed = true;
9132                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9133                                + " is using old GET_TASKS but privileged; allowing");
9134                    }
9135                } catch (RemoteException e) {
9136                }
9137            }
9138        }
9139        if (!allowed) {
9140            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9141                    + " does not hold REAL_GET_TASKS; limiting output");
9142        }
9143        return allowed;
9144    }
9145
9146    @Override
9147    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9148            int userId) {
9149        final int callingUid = Binder.getCallingUid();
9150        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9151                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9152
9153        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9154        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9155        synchronized (this) {
9156            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9157                    callingUid);
9158            final boolean detailed = checkCallingPermission(
9159                    android.Manifest.permission.GET_DETAILED_TASKS)
9160                    == PackageManager.PERMISSION_GRANTED;
9161
9162            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9163                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9164                return ParceledListSlice.emptyList();
9165            }
9166            mRecentTasks.loadUserRecentsLocked(userId);
9167
9168            final int recentsCount = mRecentTasks.size();
9169            ArrayList<ActivityManager.RecentTaskInfo> res =
9170                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9171
9172            final Set<Integer> includedUsers;
9173            if (includeProfiles) {
9174                includedUsers = mUserController.getProfileIds(userId);
9175            } else {
9176                includedUsers = new HashSet<>();
9177            }
9178            includedUsers.add(Integer.valueOf(userId));
9179
9180            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9181                TaskRecord tr = mRecentTasks.get(i);
9182                // Only add calling user or related users recent tasks
9183                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9184                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9185                    continue;
9186                }
9187
9188                if (tr.realActivitySuspended) {
9189                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9190                    continue;
9191                }
9192
9193                // Return the entry if desired by the caller.  We always return
9194                // the first entry, because callers always expect this to be the
9195                // foreground app.  We may filter others if the caller has
9196                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9197                // we should exclude the entry.
9198
9199                if (i == 0
9200                        || withExcluded
9201                        || (tr.intent == null)
9202                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9203                                == 0)) {
9204                    if (!allowed) {
9205                        // If the caller doesn't have the GET_TASKS permission, then only
9206                        // allow them to see a small subset of tasks -- their own and home.
9207                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9208                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9209                            continue;
9210                        }
9211                    }
9212                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9213                        if (tr.stack != null && tr.stack.isHomeStack()) {
9214                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9215                                    "Skipping, home stack task: " + tr);
9216                            continue;
9217                        }
9218                    }
9219                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9220                        final ActivityStack stack = tr.stack;
9221                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9222                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9223                                    "Skipping, top task in docked stack: " + tr);
9224                            continue;
9225                        }
9226                    }
9227                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9228                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9229                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9230                                    "Skipping, pinned stack task: " + tr);
9231                            continue;
9232                        }
9233                    }
9234                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9235                        // Don't include auto remove tasks that are finished or finishing.
9236                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9237                                "Skipping, auto-remove without activity: " + tr);
9238                        continue;
9239                    }
9240                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9241                            && !tr.isAvailable) {
9242                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9243                                "Skipping, unavail real act: " + tr);
9244                        continue;
9245                    }
9246
9247                    if (!tr.mUserSetupComplete) {
9248                        // Don't include task launched while user is not done setting-up.
9249                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9250                                "Skipping, user setup not complete: " + tr);
9251                        continue;
9252                    }
9253
9254                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9255                    if (!detailed) {
9256                        rti.baseIntent.replaceExtras((Bundle)null);
9257                    }
9258
9259                    res.add(rti);
9260                    maxNum--;
9261                }
9262            }
9263            return new ParceledListSlice<>(res);
9264        }
9265    }
9266
9267    @Override
9268    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9269        synchronized (this) {
9270            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9271                    "getTaskThumbnail()");
9272            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9273                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9274            if (tr != null) {
9275                return tr.getTaskThumbnailLocked();
9276            }
9277        }
9278        return null;
9279    }
9280
9281    @Override
9282    public int addAppTask(IBinder activityToken, Intent intent,
9283            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9284        final int callingUid = Binder.getCallingUid();
9285        final long callingIdent = Binder.clearCallingIdentity();
9286
9287        try {
9288            synchronized (this) {
9289                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9290                if (r == null) {
9291                    throw new IllegalArgumentException("Activity does not exist; token="
9292                            + activityToken);
9293                }
9294                ComponentName comp = intent.getComponent();
9295                if (comp == null) {
9296                    throw new IllegalArgumentException("Intent " + intent
9297                            + " must specify explicit component");
9298                }
9299                if (thumbnail.getWidth() != mThumbnailWidth
9300                        || thumbnail.getHeight() != mThumbnailHeight) {
9301                    throw new IllegalArgumentException("Bad thumbnail size: got "
9302                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9303                            + mThumbnailWidth + "x" + mThumbnailHeight);
9304                }
9305                if (intent.getSelector() != null) {
9306                    intent.setSelector(null);
9307                }
9308                if (intent.getSourceBounds() != null) {
9309                    intent.setSourceBounds(null);
9310                }
9311                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9312                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9313                        // The caller has added this as an auto-remove task...  that makes no
9314                        // sense, so turn off auto-remove.
9315                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9316                    }
9317                }
9318                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9319                    mLastAddedTaskActivity = null;
9320                }
9321                ActivityInfo ainfo = mLastAddedTaskActivity;
9322                if (ainfo == null) {
9323                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9324                            comp, 0, UserHandle.getUserId(callingUid));
9325                    if (ainfo.applicationInfo.uid != callingUid) {
9326                        throw new SecurityException(
9327                                "Can't add task for another application: target uid="
9328                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9329                    }
9330                }
9331
9332                // Use the full screen as the context for the task thumbnail
9333                final Point displaySize = new Point();
9334                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9335                r.task.stack.getDisplaySize(displaySize);
9336                thumbnailInfo.taskWidth = displaySize.x;
9337                thumbnailInfo.taskHeight = displaySize.y;
9338                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9339
9340                TaskRecord task = new TaskRecord(this,
9341                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9342                        ainfo, intent, description, thumbnailInfo);
9343
9344                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9345                if (trimIdx >= 0) {
9346                    // If this would have caused a trim, then we'll abort because that
9347                    // means it would be added at the end of the list but then just removed.
9348                    return INVALID_TASK_ID;
9349                }
9350
9351                final int N = mRecentTasks.size();
9352                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9353                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9354                    tr.removedFromRecents();
9355                }
9356
9357                task.inRecents = true;
9358                mRecentTasks.add(task);
9359                r.task.stack.addTask(task, false, "addAppTask");
9360
9361                task.setLastThumbnailLocked(thumbnail);
9362                task.freeLastThumbnail();
9363
9364                return task.taskId;
9365            }
9366        } finally {
9367            Binder.restoreCallingIdentity(callingIdent);
9368        }
9369    }
9370
9371    @Override
9372    public Point getAppTaskThumbnailSize() {
9373        synchronized (this) {
9374            return new Point(mThumbnailWidth,  mThumbnailHeight);
9375        }
9376    }
9377
9378    @Override
9379    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9380        synchronized (this) {
9381            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9382            if (r != null) {
9383                r.setTaskDescription(td);
9384                r.task.updateTaskDescription();
9385            }
9386        }
9387    }
9388
9389    @Override
9390    public void setTaskResizeable(int taskId, int resizeableMode) {
9391        synchronized (this) {
9392            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9393                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9394            if (task == null) {
9395                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9396                return;
9397            }
9398            if (task.mResizeMode != resizeableMode) {
9399                task.mResizeMode = resizeableMode;
9400                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9401                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9402                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9403            }
9404        }
9405    }
9406
9407    @Override
9408    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9409        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9410        long ident = Binder.clearCallingIdentity();
9411        try {
9412            synchronized (this) {
9413                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9414                if (task == null) {
9415                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9416                    return;
9417                }
9418                int stackId = task.stack.mStackId;
9419                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9420                // in crop windows resize mode or if the task size is affected by the docked stack
9421                // changing size. No need to update configuration.
9422                if (bounds != null && task.inCropWindowsResizeMode()
9423                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9424                    mWindowManager.scrollTask(task.taskId, bounds);
9425                    return;
9426                }
9427
9428                // Place the task in the right stack if it isn't there already based on
9429                // the requested bounds.
9430                // The stack transition logic is:
9431                // - a null bounds on a freeform task moves that task to fullscreen
9432                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9433                //   that task to freeform
9434                // - otherwise the task is not moved
9435                if (!StackId.isTaskResizeAllowed(stackId)) {
9436                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9437                }
9438                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9439                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9440                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9441                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9442                }
9443                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9444                if (stackId != task.stack.mStackId) {
9445                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9446                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9447                    preserveWindow = false;
9448                }
9449
9450                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9451                        false /* deferResume */);
9452            }
9453        } finally {
9454            Binder.restoreCallingIdentity(ident);
9455        }
9456    }
9457
9458    @Override
9459    public Rect getTaskBounds(int taskId) {
9460        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9461        long ident = Binder.clearCallingIdentity();
9462        Rect rect = new Rect();
9463        try {
9464            synchronized (this) {
9465                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9466                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9467                if (task == null) {
9468                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9469                    return rect;
9470                }
9471                if (task.stack != null) {
9472                    // Return the bounds from window manager since it will be adjusted for various
9473                    // things like the presense of a docked stack for tasks that aren't resizeable.
9474                    mWindowManager.getTaskBounds(task.taskId, rect);
9475                } else {
9476                    // Task isn't in window manager yet since it isn't associated with a stack.
9477                    // Return the persist value from activity manager
9478                    if (task.mBounds != null) {
9479                        rect.set(task.mBounds);
9480                    } else if (task.mLastNonFullscreenBounds != null) {
9481                        rect.set(task.mLastNonFullscreenBounds);
9482                    }
9483                }
9484            }
9485        } finally {
9486            Binder.restoreCallingIdentity(ident);
9487        }
9488        return rect;
9489    }
9490
9491    @Override
9492    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9493        if (userId != UserHandle.getCallingUserId()) {
9494            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9495                    "getTaskDescriptionIcon");
9496        }
9497        final File passedIconFile = new File(filePath);
9498        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9499                passedIconFile.getName());
9500        if (!legitIconFile.getPath().equals(filePath)
9501                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9502            throw new IllegalArgumentException("Bad file path: " + filePath
9503                    + " passed for userId " + userId);
9504        }
9505        return mRecentTasks.getTaskDescriptionIcon(filePath);
9506    }
9507
9508    @Override
9509    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9510            throws RemoteException {
9511        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9512                opts.getCustomInPlaceResId() == 0) {
9513            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9514                    "with valid animation");
9515        }
9516        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9517        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9518                opts.getCustomInPlaceResId());
9519        mWindowManager.executeAppTransition();
9520    }
9521
9522    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9523            boolean removeFromRecents) {
9524        if (removeFromRecents) {
9525            mRecentTasks.remove(tr);
9526            tr.removedFromRecents();
9527        }
9528        ComponentName component = tr.getBaseIntent().getComponent();
9529        if (component == null) {
9530            Slog.w(TAG, "No component for base intent of task: " + tr);
9531            return;
9532        }
9533
9534        // Find any running services associated with this app and stop if needed.
9535        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9536
9537        if (!killProcess) {
9538            return;
9539        }
9540
9541        // Determine if the process(es) for this task should be killed.
9542        final String pkg = component.getPackageName();
9543        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9544        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9545        for (int i = 0; i < pmap.size(); i++) {
9546
9547            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9548            for (int j = 0; j < uids.size(); j++) {
9549                ProcessRecord proc = uids.valueAt(j);
9550                if (proc.userId != tr.userId) {
9551                    // Don't kill process for a different user.
9552                    continue;
9553                }
9554                if (proc == mHomeProcess) {
9555                    // Don't kill the home process along with tasks from the same package.
9556                    continue;
9557                }
9558                if (!proc.pkgList.containsKey(pkg)) {
9559                    // Don't kill process that is not associated with this task.
9560                    continue;
9561                }
9562
9563                for (int k = 0; k < proc.activities.size(); k++) {
9564                    TaskRecord otherTask = proc.activities.get(k).task;
9565                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9566                        // Don't kill process(es) that has an activity in a different task that is
9567                        // also in recents.
9568                        return;
9569                    }
9570                }
9571
9572                if (proc.foregroundServices) {
9573                    // Don't kill process(es) with foreground service.
9574                    return;
9575                }
9576
9577                // Add process to kill list.
9578                procsToKill.add(proc);
9579            }
9580        }
9581
9582        // Kill the running processes.
9583        for (int i = 0; i < procsToKill.size(); i++) {
9584            ProcessRecord pr = procsToKill.get(i);
9585            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9586                    && pr.curReceiver == null) {
9587                pr.kill("remove task", true);
9588            } else {
9589                // We delay killing processes that are not in the background or running a receiver.
9590                pr.waitingToKill = "remove task";
9591            }
9592        }
9593    }
9594
9595    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9596        // Remove all tasks with activities in the specified package from the list of recent tasks
9597        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9598            TaskRecord tr = mRecentTasks.get(i);
9599            if (tr.userId != userId) continue;
9600
9601            ComponentName cn = tr.intent.getComponent();
9602            if (cn != null && cn.getPackageName().equals(packageName)) {
9603                // If the package name matches, remove the task.
9604                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9605            }
9606        }
9607    }
9608
9609    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9610            int userId) {
9611
9612        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9613            TaskRecord tr = mRecentTasks.get(i);
9614            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9615                continue;
9616            }
9617
9618            ComponentName cn = tr.intent.getComponent();
9619            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9620                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9621            if (sameComponent) {
9622                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9623            }
9624        }
9625    }
9626
9627    /**
9628     * Removes the task with the specified task id.
9629     *
9630     * @param taskId Identifier of the task to be removed.
9631     * @param killProcess Kill any process associated with the task if possible.
9632     * @param removeFromRecents Whether to also remove the task from recents.
9633     * @return Returns true if the given task was found and removed.
9634     */
9635    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9636            boolean removeFromRecents) {
9637        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9638                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9639        if (tr != null) {
9640            tr.removeTaskActivitiesLocked();
9641            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9642            if (tr.isPersistable) {
9643                notifyTaskPersisterLocked(null, true);
9644            }
9645            return true;
9646        }
9647        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9648        return false;
9649    }
9650
9651    @Override
9652    public void removeStack(int stackId) {
9653        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9654        if (stackId == HOME_STACK_ID) {
9655            throw new IllegalArgumentException("Removing home stack is not allowed.");
9656        }
9657
9658        synchronized (this) {
9659            final long ident = Binder.clearCallingIdentity();
9660            try {
9661                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9662                if (stack == null) {
9663                    return;
9664                }
9665                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9666                for (int i = tasks.size() - 1; i >= 0; i--) {
9667                    removeTaskByIdLocked(
9668                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9669                }
9670            } finally {
9671                Binder.restoreCallingIdentity(ident);
9672            }
9673        }
9674    }
9675
9676    @Override
9677    public boolean removeTask(int taskId) {
9678        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9679        synchronized (this) {
9680            final long ident = Binder.clearCallingIdentity();
9681            try {
9682                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9683            } finally {
9684                Binder.restoreCallingIdentity(ident);
9685            }
9686        }
9687    }
9688
9689    /**
9690     * TODO: Add mController hook
9691     */
9692    @Override
9693    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9694        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9695
9696        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9697        synchronized(this) {
9698            moveTaskToFrontLocked(taskId, flags, bOptions);
9699        }
9700    }
9701
9702    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9703        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9704
9705        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9706                Binder.getCallingUid(), -1, -1, "Task to front")) {
9707            ActivityOptions.abort(options);
9708            return;
9709        }
9710        final long origId = Binder.clearCallingIdentity();
9711        try {
9712            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9713            if (task == null) {
9714                Slog.d(TAG, "Could not find task for id: "+ taskId);
9715                return;
9716            }
9717            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9718                mStackSupervisor.showLockTaskToast();
9719                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9720                return;
9721            }
9722            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9723            if (prev != null && prev.isRecentsActivity()) {
9724                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9725            }
9726            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9727                    false /* forceNonResizable */);
9728        } finally {
9729            Binder.restoreCallingIdentity(origId);
9730        }
9731        ActivityOptions.abort(options);
9732    }
9733
9734    /**
9735     * Moves an activity, and all of the other activities within the same task, to the bottom
9736     * of the history stack.  The activity's order within the task is unchanged.
9737     *
9738     * @param token A reference to the activity we wish to move
9739     * @param nonRoot If false then this only works if the activity is the root
9740     *                of a task; if true it will work for any activity in a task.
9741     * @return Returns true if the move completed, false if not.
9742     */
9743    @Override
9744    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9745        enforceNotIsolatedCaller("moveActivityTaskToBack");
9746        synchronized(this) {
9747            final long origId = Binder.clearCallingIdentity();
9748            try {
9749                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9750                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9751                if (task != null) {
9752                    if (mStackSupervisor.isLockedTask(task)) {
9753                        mStackSupervisor.showLockTaskToast();
9754                        return false;
9755                    }
9756                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9757                }
9758            } finally {
9759                Binder.restoreCallingIdentity(origId);
9760            }
9761        }
9762        return false;
9763    }
9764
9765    @Override
9766    public void moveTaskBackwards(int task) {
9767        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9768                "moveTaskBackwards()");
9769
9770        synchronized(this) {
9771            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9772                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9773                return;
9774            }
9775            final long origId = Binder.clearCallingIdentity();
9776            moveTaskBackwardsLocked(task);
9777            Binder.restoreCallingIdentity(origId);
9778        }
9779    }
9780
9781    private final void moveTaskBackwardsLocked(int task) {
9782        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9783    }
9784
9785    @Override
9786    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9787            IActivityContainerCallback callback) throws RemoteException {
9788        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9789        synchronized (this) {
9790            if (parentActivityToken == null) {
9791                throw new IllegalArgumentException("parent token must not be null");
9792            }
9793            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9794            if (r == null) {
9795                return null;
9796            }
9797            if (callback == null) {
9798                throw new IllegalArgumentException("callback must not be null");
9799            }
9800            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9801        }
9802    }
9803
9804    @Override
9805    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9806        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9807        synchronized (this) {
9808            mStackSupervisor.deleteActivityContainer(container);
9809        }
9810    }
9811
9812    @Override
9813    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9814        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9815        synchronized (this) {
9816            final int stackId = mStackSupervisor.getNextStackId();
9817            final ActivityStack stack =
9818                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9819            if (stack == null) {
9820                return null;
9821            }
9822            return stack.mActivityContainer;
9823        }
9824    }
9825
9826    @Override
9827    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9828        synchronized (this) {
9829            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9830            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9831                return stack.mActivityContainer.getDisplayId();
9832            }
9833            return Display.DEFAULT_DISPLAY;
9834        }
9835    }
9836
9837    @Override
9838    public int getActivityStackId(IBinder token) throws RemoteException {
9839        synchronized (this) {
9840            ActivityStack stack = ActivityRecord.getStackLocked(token);
9841            if (stack == null) {
9842                return INVALID_STACK_ID;
9843            }
9844            return stack.mStackId;
9845        }
9846    }
9847
9848    @Override
9849    public void exitFreeformMode(IBinder token) throws RemoteException {
9850        synchronized (this) {
9851            long ident = Binder.clearCallingIdentity();
9852            try {
9853                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9854                if (r == null) {
9855                    throw new IllegalArgumentException(
9856                            "exitFreeformMode: No activity record matching token=" + token);
9857                }
9858                final ActivityStack stack = r.getStackLocked(token);
9859                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9860                    throw new IllegalStateException(
9861                            "exitFreeformMode: You can only go fullscreen from freeform.");
9862                }
9863                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9864                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9865                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9866            } finally {
9867                Binder.restoreCallingIdentity(ident);
9868            }
9869        }
9870    }
9871
9872    @Override
9873    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9874        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9875        if (stackId == HOME_STACK_ID) {
9876            throw new IllegalArgumentException(
9877                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9878        }
9879        synchronized (this) {
9880            long ident = Binder.clearCallingIdentity();
9881            try {
9882                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9883                        + " to stackId=" + stackId + " toTop=" + toTop);
9884                if (stackId == DOCKED_STACK_ID) {
9885                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9886                            null /* initialBounds */);
9887                }
9888                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9889                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9890                if (result && stackId == DOCKED_STACK_ID) {
9891                    // If task moved to docked stack - show recents if needed.
9892                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9893                            "moveTaskToDockedStack");
9894                }
9895            } finally {
9896                Binder.restoreCallingIdentity(ident);
9897            }
9898        }
9899    }
9900
9901    @Override
9902    public void swapDockedAndFullscreenStack() throws RemoteException {
9903        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9904        synchronized (this) {
9905            long ident = Binder.clearCallingIdentity();
9906            try {
9907                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9908                        FULLSCREEN_WORKSPACE_STACK_ID);
9909                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9910                        : null;
9911                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9912                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9913                        : null;
9914                if (topTask == null || tasks == null || tasks.size() == 0) {
9915                    Slog.w(TAG,
9916                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9917                    return;
9918                }
9919
9920                // TODO: App transition
9921                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9922
9923                // Defer the resume so resume/pausing while moving stacks is dangerous.
9924                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9925                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9926                        ANIMATE, true /* deferResume */);
9927                final int size = tasks.size();
9928                for (int i = 0; i < size; i++) {
9929                    final int id = tasks.get(i).taskId;
9930                    if (id == topTask.taskId) {
9931                        continue;
9932                    }
9933                    mStackSupervisor.moveTaskToStackLocked(id,
9934                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9935                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9936                }
9937
9938                // Because we deferred the resume, to avoid conflicts with stack switches while
9939                // resuming, we need to do it after all the tasks are moved.
9940                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9941                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9942
9943                mWindowManager.executeAppTransition();
9944            } finally {
9945                Binder.restoreCallingIdentity(ident);
9946            }
9947        }
9948    }
9949
9950    /**
9951     * Moves the input task to the docked stack.
9952     *
9953     * @param taskId Id of task to move.
9954     * @param createMode The mode the docked stack should be created in if it doesn't exist
9955     *                   already. See
9956     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9957     *                   and
9958     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9959     * @param toTop If the task and stack should be moved to the top.
9960     * @param animate Whether we should play an animation for the moving the task
9961     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9962     *                      docked stack. Pass {@code null} to use default bounds.
9963     */
9964    @Override
9965    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9966            Rect initialBounds, boolean moveHomeStackFront) {
9967        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9968        synchronized (this) {
9969            long ident = Binder.clearCallingIdentity();
9970            try {
9971                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9972                        + " to createMode=" + createMode + " toTop=" + toTop);
9973                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9974                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9975                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9976                        animate, DEFER_RESUME);
9977                if (moved) {
9978                    if (moveHomeStackFront) {
9979                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9980                    }
9981                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9982                }
9983                return moved;
9984            } finally {
9985                Binder.restoreCallingIdentity(ident);
9986            }
9987        }
9988    }
9989
9990    /**
9991     * Moves the top activity in the input stackId to the pinned stack.
9992     *
9993     * @param stackId Id of stack to move the top activity to pinned stack.
9994     * @param bounds Bounds to use for pinned stack.
9995     *
9996     * @return True if the top activity of the input stack was successfully moved to the pinned
9997     *          stack.
9998     */
9999    @Override
10000    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10001        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10002        synchronized (this) {
10003            if (!mSupportsPictureInPicture) {
10004                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10005                        + "Device doesn't support picture-in-pciture mode");
10006            }
10007
10008            long ident = Binder.clearCallingIdentity();
10009            try {
10010                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10011            } finally {
10012                Binder.restoreCallingIdentity(ident);
10013            }
10014        }
10015    }
10016
10017    @Override
10018    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10019            boolean preserveWindows, boolean animate, int animationDuration) {
10020        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10021        long ident = Binder.clearCallingIdentity();
10022        try {
10023            synchronized (this) {
10024                if (animate) {
10025                    if (stackId == PINNED_STACK_ID) {
10026                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10027                    } else {
10028                        throw new IllegalArgumentException("Stack: " + stackId
10029                                + " doesn't support animated resize.");
10030                    }
10031                } else {
10032                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10033                            null /* tempTaskInsetBounds */, preserveWindows,
10034                            allowResizeInDockedMode, !DEFER_RESUME);
10035                }
10036            }
10037        } finally {
10038            Binder.restoreCallingIdentity(ident);
10039        }
10040    }
10041
10042    @Override
10043    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10044            Rect tempDockedTaskInsetBounds,
10045            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10046        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10047                "resizeDockedStack()");
10048        long ident = Binder.clearCallingIdentity();
10049        try {
10050            synchronized (this) {
10051                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10052                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10053                        PRESERVE_WINDOWS);
10054            }
10055        } finally {
10056            Binder.restoreCallingIdentity(ident);
10057        }
10058    }
10059
10060    @Override
10061    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10062        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10063                "resizePinnedStack()");
10064        final long ident = Binder.clearCallingIdentity();
10065        try {
10066            synchronized (this) {
10067                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10068            }
10069        } finally {
10070            Binder.restoreCallingIdentity(ident);
10071        }
10072    }
10073
10074    @Override
10075    public void positionTaskInStack(int taskId, int stackId, int position) {
10076        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10077        if (stackId == HOME_STACK_ID) {
10078            throw new IllegalArgumentException(
10079                    "positionTaskInStack: Attempt to change the position of task "
10080                    + taskId + " in/to home stack");
10081        }
10082        synchronized (this) {
10083            long ident = Binder.clearCallingIdentity();
10084            try {
10085                if (DEBUG_STACK) Slog.d(TAG_STACK,
10086                        "positionTaskInStack: positioning task=" + taskId
10087                        + " in stackId=" + stackId + " at position=" + position);
10088                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10089            } finally {
10090                Binder.restoreCallingIdentity(ident);
10091            }
10092        }
10093    }
10094
10095    @Override
10096    public List<StackInfo> getAllStackInfos() {
10097        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10098        long ident = Binder.clearCallingIdentity();
10099        try {
10100            synchronized (this) {
10101                return mStackSupervisor.getAllStackInfosLocked();
10102            }
10103        } finally {
10104            Binder.restoreCallingIdentity(ident);
10105        }
10106    }
10107
10108    @Override
10109    public StackInfo getStackInfo(int stackId) {
10110        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10111        long ident = Binder.clearCallingIdentity();
10112        try {
10113            synchronized (this) {
10114                return mStackSupervisor.getStackInfoLocked(stackId);
10115            }
10116        } finally {
10117            Binder.restoreCallingIdentity(ident);
10118        }
10119    }
10120
10121    @Override
10122    public boolean isInHomeStack(int taskId) {
10123        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10124        long ident = Binder.clearCallingIdentity();
10125        try {
10126            synchronized (this) {
10127                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10128                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10129                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10130            }
10131        } finally {
10132            Binder.restoreCallingIdentity(ident);
10133        }
10134    }
10135
10136    @Override
10137    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10138        synchronized(this) {
10139            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10140        }
10141    }
10142
10143    @Override
10144    public void updateDeviceOwner(String packageName) {
10145        final int callingUid = Binder.getCallingUid();
10146        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10147            throw new SecurityException("updateDeviceOwner called from non-system process");
10148        }
10149        synchronized (this) {
10150            mDeviceOwnerName = packageName;
10151        }
10152    }
10153
10154    @Override
10155    public void updateLockTaskPackages(int userId, String[] packages) {
10156        final int callingUid = Binder.getCallingUid();
10157        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10158            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10159                    "updateLockTaskPackages()");
10160        }
10161        synchronized (this) {
10162            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10163                    Arrays.toString(packages));
10164            mLockTaskPackages.put(userId, packages);
10165            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10166        }
10167    }
10168
10169
10170    void startLockTaskModeLocked(TaskRecord task) {
10171        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10172        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10173            return;
10174        }
10175
10176        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10177        // is initiated by system after the pinning request was shown and locked mode is initiated
10178        // by an authorized app directly
10179        final int callingUid = Binder.getCallingUid();
10180        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10181        long ident = Binder.clearCallingIdentity();
10182        try {
10183            if (!isSystemInitiated) {
10184                task.mLockTaskUid = callingUid;
10185                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10186                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10187                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10188                    StatusBarManagerInternal statusBarManager =
10189                            LocalServices.getService(StatusBarManagerInternal.class);
10190                    if (statusBarManager != null) {
10191                        statusBarManager.showScreenPinningRequest(task.taskId);
10192                    }
10193                    return;
10194                }
10195
10196                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10197                if (stack == null || task != stack.topTask()) {
10198                    throw new IllegalArgumentException("Invalid task, not in foreground");
10199                }
10200            }
10201            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10202                    "Locking fully");
10203            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10204                    ActivityManager.LOCK_TASK_MODE_PINNED :
10205                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10206                    "startLockTask", true);
10207        } finally {
10208            Binder.restoreCallingIdentity(ident);
10209        }
10210    }
10211
10212    @Override
10213    public void startLockTaskMode(int taskId) {
10214        synchronized (this) {
10215            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10216            if (task != null) {
10217                startLockTaskModeLocked(task);
10218            }
10219        }
10220    }
10221
10222    @Override
10223    public void startLockTaskMode(IBinder token) {
10224        synchronized (this) {
10225            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10226            if (r == null) {
10227                return;
10228            }
10229            final TaskRecord task = r.task;
10230            if (task != null) {
10231                startLockTaskModeLocked(task);
10232            }
10233        }
10234    }
10235
10236    @Override
10237    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10238        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10239        // This makes inner call to look as if it was initiated by system.
10240        long ident = Binder.clearCallingIdentity();
10241        try {
10242            synchronized (this) {
10243                startLockTaskMode(taskId);
10244            }
10245        } finally {
10246            Binder.restoreCallingIdentity(ident);
10247        }
10248    }
10249
10250    @Override
10251    public void stopLockTaskMode() {
10252        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10253        if (lockTask == null) {
10254            // Our work here is done.
10255            return;
10256        }
10257
10258        final int callingUid = Binder.getCallingUid();
10259        final int lockTaskUid = lockTask.mLockTaskUid;
10260        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10261        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10262            // Done.
10263            return;
10264        } else {
10265            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10266            // It is possible lockTaskMode was started by the system process because
10267            // android:lockTaskMode is set to a locking value in the application manifest
10268            // instead of the app calling startLockTaskMode. In this case
10269            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10270            // {@link TaskRecord.effectiveUid} instead. Also caller with
10271            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10272            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10273                    && callingUid != lockTaskUid
10274                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10275                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10276                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10277            }
10278        }
10279        long ident = Binder.clearCallingIdentity();
10280        try {
10281            Log.d(TAG, "stopLockTaskMode");
10282            // Stop lock task
10283            synchronized (this) {
10284                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10285                        "stopLockTask", true);
10286            }
10287            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10288            if (tm != null) {
10289                tm.showInCallScreen(false);
10290            }
10291        } finally {
10292            Binder.restoreCallingIdentity(ident);
10293        }
10294    }
10295
10296    /**
10297     * This API should be called by SystemUI only when user perform certain action to dismiss
10298     * lock task mode. We should only dismiss pinned lock task mode in this case.
10299     */
10300    @Override
10301    public void stopSystemLockTaskMode() throws RemoteException {
10302        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10303            stopLockTaskMode();
10304        } else {
10305            mStackSupervisor.showLockTaskToast();
10306        }
10307    }
10308
10309    @Override
10310    public boolean isInLockTaskMode() {
10311        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10312    }
10313
10314    @Override
10315    public int getLockTaskModeState() {
10316        synchronized (this) {
10317            return mStackSupervisor.getLockTaskModeState();
10318        }
10319    }
10320
10321    @Override
10322    public void showLockTaskEscapeMessage(IBinder token) {
10323        synchronized (this) {
10324            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10325            if (r == null) {
10326                return;
10327            }
10328            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10329        }
10330    }
10331
10332    // =========================================================
10333    // CONTENT PROVIDERS
10334    // =========================================================
10335
10336    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10337        List<ProviderInfo> providers = null;
10338        try {
10339            providers = AppGlobals.getPackageManager()
10340                    .queryContentProviders(app.processName, app.uid,
10341                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10342                                    | MATCH_DEBUG_TRIAGED_MISSING)
10343                    .getList();
10344        } catch (RemoteException ex) {
10345        }
10346        if (DEBUG_MU) Slog.v(TAG_MU,
10347                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10348        int userId = app.userId;
10349        if (providers != null) {
10350            int N = providers.size();
10351            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10352            for (int i=0; i<N; i++) {
10353                // TODO: keep logic in sync with installEncryptionUnawareProviders
10354                ProviderInfo cpi =
10355                    (ProviderInfo)providers.get(i);
10356                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10357                        cpi.name, cpi.flags);
10358                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10359                    // This is a singleton provider, but a user besides the
10360                    // default user is asking to initialize a process it runs
10361                    // in...  well, no, it doesn't actually run in this process,
10362                    // it runs in the process of the default user.  Get rid of it.
10363                    providers.remove(i);
10364                    N--;
10365                    i--;
10366                    continue;
10367                }
10368
10369                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10370                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10371                if (cpr == null) {
10372                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10373                    mProviderMap.putProviderByClass(comp, cpr);
10374                }
10375                if (DEBUG_MU) Slog.v(TAG_MU,
10376                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10377                app.pubProviders.put(cpi.name, cpr);
10378                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10379                    // Don't add this if it is a platform component that is marked
10380                    // to run in multiple processes, because this is actually
10381                    // part of the framework so doesn't make sense to track as a
10382                    // separate apk in the process.
10383                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10384                            mProcessStats);
10385                }
10386                notifyPackageUse(cpi.applicationInfo.packageName,
10387                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10388            }
10389        }
10390        return providers;
10391    }
10392
10393    /**
10394     * Check if {@link ProcessRecord} has a possible chance at accessing the
10395     * given {@link ProviderInfo}. Final permission checking is always done
10396     * in {@link ContentProvider}.
10397     */
10398    private final String checkContentProviderPermissionLocked(
10399            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10400        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10401        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10402        boolean checkedGrants = false;
10403        if (checkUser) {
10404            // Looking for cross-user grants before enforcing the typical cross-users permissions
10405            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10406            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10407                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10408                    return null;
10409                }
10410                checkedGrants = true;
10411            }
10412            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10413                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10414            if (userId != tmpTargetUserId) {
10415                // When we actually went to determine the final targer user ID, this ended
10416                // up different than our initial check for the authority.  This is because
10417                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10418                // SELF.  So we need to re-check the grants again.
10419                checkedGrants = false;
10420            }
10421        }
10422        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10423                cpi.applicationInfo.uid, cpi.exported)
10424                == PackageManager.PERMISSION_GRANTED) {
10425            return null;
10426        }
10427        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10428                cpi.applicationInfo.uid, cpi.exported)
10429                == PackageManager.PERMISSION_GRANTED) {
10430            return null;
10431        }
10432
10433        PathPermission[] pps = cpi.pathPermissions;
10434        if (pps != null) {
10435            int i = pps.length;
10436            while (i > 0) {
10437                i--;
10438                PathPermission pp = pps[i];
10439                String pprperm = pp.getReadPermission();
10440                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10441                        cpi.applicationInfo.uid, cpi.exported)
10442                        == PackageManager.PERMISSION_GRANTED) {
10443                    return null;
10444                }
10445                String ppwperm = pp.getWritePermission();
10446                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10447                        cpi.applicationInfo.uid, cpi.exported)
10448                        == PackageManager.PERMISSION_GRANTED) {
10449                    return null;
10450                }
10451            }
10452        }
10453        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10454            return null;
10455        }
10456
10457        String msg;
10458        if (!cpi.exported) {
10459            msg = "Permission Denial: opening provider " + cpi.name
10460                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10461                    + ", uid=" + callingUid + ") that is not exported from uid "
10462                    + cpi.applicationInfo.uid;
10463        } else {
10464            msg = "Permission Denial: opening provider " + cpi.name
10465                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10466                    + ", uid=" + callingUid + ") requires "
10467                    + cpi.readPermission + " or " + cpi.writePermission;
10468        }
10469        Slog.w(TAG, msg);
10470        return msg;
10471    }
10472
10473    /**
10474     * Returns if the ContentProvider has granted a uri to callingUid
10475     */
10476    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10477        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10478        if (perms != null) {
10479            for (int i=perms.size()-1; i>=0; i--) {
10480                GrantUri grantUri = perms.keyAt(i);
10481                if (grantUri.sourceUserId == userId || !checkUser) {
10482                    if (matchesProvider(grantUri.uri, cpi)) {
10483                        return true;
10484                    }
10485                }
10486            }
10487        }
10488        return false;
10489    }
10490
10491    /**
10492     * Returns true if the uri authority is one of the authorities specified in the provider.
10493     */
10494    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10495        String uriAuth = uri.getAuthority();
10496        String cpiAuth = cpi.authority;
10497        if (cpiAuth.indexOf(';') == -1) {
10498            return cpiAuth.equals(uriAuth);
10499        }
10500        String[] cpiAuths = cpiAuth.split(";");
10501        int length = cpiAuths.length;
10502        for (int i = 0; i < length; i++) {
10503            if (cpiAuths[i].equals(uriAuth)) return true;
10504        }
10505        return false;
10506    }
10507
10508    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10509            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10510        if (r != null) {
10511            for (int i=0; i<r.conProviders.size(); i++) {
10512                ContentProviderConnection conn = r.conProviders.get(i);
10513                if (conn.provider == cpr) {
10514                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10515                            "Adding provider requested by "
10516                            + r.processName + " from process "
10517                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10518                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10519                    if (stable) {
10520                        conn.stableCount++;
10521                        conn.numStableIncs++;
10522                    } else {
10523                        conn.unstableCount++;
10524                        conn.numUnstableIncs++;
10525                    }
10526                    return conn;
10527                }
10528            }
10529            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10530            if (stable) {
10531                conn.stableCount = 1;
10532                conn.numStableIncs = 1;
10533            } else {
10534                conn.unstableCount = 1;
10535                conn.numUnstableIncs = 1;
10536            }
10537            cpr.connections.add(conn);
10538            r.conProviders.add(conn);
10539            startAssociationLocked(r.uid, r.processName, r.curProcState,
10540                    cpr.uid, cpr.name, cpr.info.processName);
10541            return conn;
10542        }
10543        cpr.addExternalProcessHandleLocked(externalProcessToken);
10544        return null;
10545    }
10546
10547    boolean decProviderCountLocked(ContentProviderConnection conn,
10548            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10549        if (conn != null) {
10550            cpr = conn.provider;
10551            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10552                    "Removing provider requested by "
10553                    + conn.client.processName + " from process "
10554                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10555                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10556            if (stable) {
10557                conn.stableCount--;
10558            } else {
10559                conn.unstableCount--;
10560            }
10561            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10562                cpr.connections.remove(conn);
10563                conn.client.conProviders.remove(conn);
10564                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10565                    // The client is more important than last activity -- note the time this
10566                    // is happening, so we keep the old provider process around a bit as last
10567                    // activity to avoid thrashing it.
10568                    if (cpr.proc != null) {
10569                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10570                    }
10571                }
10572                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10573                return true;
10574            }
10575            return false;
10576        }
10577        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10578        return false;
10579    }
10580
10581    private void checkTime(long startTime, String where) {
10582        long now = SystemClock.uptimeMillis();
10583        if ((now-startTime) > 50) {
10584            // If we are taking more than 50ms, log about it.
10585            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10586        }
10587    }
10588
10589    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10590            PROC_SPACE_TERM,
10591            PROC_SPACE_TERM|PROC_PARENS,
10592            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10593    };
10594
10595    private final long[] mProcessStateStatsLongs = new long[1];
10596
10597    boolean isProcessAliveLocked(ProcessRecord proc) {
10598        if (proc.procStatFile == null) {
10599            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10600        }
10601        mProcessStateStatsLongs[0] = 0;
10602        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10603                mProcessStateStatsLongs, null)) {
10604            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10605            return false;
10606        }
10607        final long state = mProcessStateStatsLongs[0];
10608        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10609                + (char)state);
10610        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10611    }
10612
10613    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10614            String name, IBinder token, boolean stable, int userId) {
10615        ContentProviderRecord cpr;
10616        ContentProviderConnection conn = null;
10617        ProviderInfo cpi = null;
10618
10619        synchronized(this) {
10620            long startTime = SystemClock.uptimeMillis();
10621
10622            ProcessRecord r = null;
10623            if (caller != null) {
10624                r = getRecordForAppLocked(caller);
10625                if (r == null) {
10626                    throw new SecurityException(
10627                            "Unable to find app for caller " + caller
10628                          + " (pid=" + Binder.getCallingPid()
10629                          + ") when getting content provider " + name);
10630                }
10631            }
10632
10633            boolean checkCrossUser = true;
10634
10635            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10636
10637            // First check if this content provider has been published...
10638            cpr = mProviderMap.getProviderByName(name, userId);
10639            // If that didn't work, check if it exists for user 0 and then
10640            // verify that it's a singleton provider before using it.
10641            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10642                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10643                if (cpr != null) {
10644                    cpi = cpr.info;
10645                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10646                            cpi.name, cpi.flags)
10647                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10648                        userId = UserHandle.USER_SYSTEM;
10649                        checkCrossUser = false;
10650                    } else {
10651                        cpr = null;
10652                        cpi = null;
10653                    }
10654                }
10655            }
10656
10657            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10658            if (providerRunning) {
10659                cpi = cpr.info;
10660                String msg;
10661                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10662                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10663                        != null) {
10664                    throw new SecurityException(msg);
10665                }
10666                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10667
10668                if (r != null && cpr.canRunHere(r)) {
10669                    // This provider has been published or is in the process
10670                    // of being published...  but it is also allowed to run
10671                    // in the caller's process, so don't make a connection
10672                    // and just let the caller instantiate its own instance.
10673                    ContentProviderHolder holder = cpr.newHolder(null);
10674                    // don't give caller the provider object, it needs
10675                    // to make its own.
10676                    holder.provider = null;
10677                    return holder;
10678                }
10679
10680                final long origId = Binder.clearCallingIdentity();
10681
10682                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10683
10684                // In this case the provider instance already exists, so we can
10685                // return it right away.
10686                conn = incProviderCountLocked(r, cpr, token, stable);
10687                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10688                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10689                        // If this is a perceptible app accessing the provider,
10690                        // make sure to count it as being accessed and thus
10691                        // back up on the LRU list.  This is good because
10692                        // content providers are often expensive to start.
10693                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10694                        updateLruProcessLocked(cpr.proc, false, null);
10695                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10696                    }
10697                }
10698
10699                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10700                final int verifiedAdj = cpr.proc.verifiedAdj;
10701                boolean success = updateOomAdjLocked(cpr.proc);
10702                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10703                // if the process has been successfully adjusted.  So to reduce races with
10704                // it, we will check whether the process still exists.  Note that this doesn't
10705                // completely get rid of races with LMK killing the process, but should make
10706                // them much smaller.
10707                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10708                    success = false;
10709                }
10710                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10711                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10712                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10713                // NOTE: there is still a race here where a signal could be
10714                // pending on the process even though we managed to update its
10715                // adj level.  Not sure what to do about this, but at least
10716                // the race is now smaller.
10717                if (!success) {
10718                    // Uh oh...  it looks like the provider's process
10719                    // has been killed on us.  We need to wait for a new
10720                    // process to be started, and make sure its death
10721                    // doesn't kill our process.
10722                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10723                            + " is crashing; detaching " + r);
10724                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10725                    checkTime(startTime, "getContentProviderImpl: before appDied");
10726                    appDiedLocked(cpr.proc);
10727                    checkTime(startTime, "getContentProviderImpl: after appDied");
10728                    if (!lastRef) {
10729                        // This wasn't the last ref our process had on
10730                        // the provider...  we have now been killed, bail.
10731                        return null;
10732                    }
10733                    providerRunning = false;
10734                    conn = null;
10735                } else {
10736                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10737                }
10738
10739                Binder.restoreCallingIdentity(origId);
10740            }
10741
10742            if (!providerRunning) {
10743                try {
10744                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10745                    cpi = AppGlobals.getPackageManager().
10746                        resolveContentProvider(name,
10747                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10748                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10749                } catch (RemoteException ex) {
10750                }
10751                if (cpi == null) {
10752                    return null;
10753                }
10754                // If the provider is a singleton AND
10755                // (it's a call within the same user || the provider is a
10756                // privileged app)
10757                // Then allow connecting to the singleton provider
10758                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10759                        cpi.name, cpi.flags)
10760                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10761                if (singleton) {
10762                    userId = UserHandle.USER_SYSTEM;
10763                }
10764                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10765                checkTime(startTime, "getContentProviderImpl: got app info for user");
10766
10767                String msg;
10768                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10769                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10770                        != null) {
10771                    throw new SecurityException(msg);
10772                }
10773                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10774
10775                if (!mProcessesReady
10776                        && !cpi.processName.equals("system")) {
10777                    // If this content provider does not run in the system
10778                    // process, and the system is not yet ready to run other
10779                    // processes, then fail fast instead of hanging.
10780                    throw new IllegalArgumentException(
10781                            "Attempt to launch content provider before system ready");
10782                }
10783
10784                // Make sure that the user who owns this provider is running.  If not,
10785                // we don't want to allow it to run.
10786                if (!mUserController.isUserRunningLocked(userId, 0)) {
10787                    Slog.w(TAG, "Unable to launch app "
10788                            + cpi.applicationInfo.packageName + "/"
10789                            + cpi.applicationInfo.uid + " for provider "
10790                            + name + ": user " + userId + " is stopped");
10791                    return null;
10792                }
10793
10794                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10795                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10796                cpr = mProviderMap.getProviderByClass(comp, userId);
10797                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10798                final boolean firstClass = cpr == null;
10799                if (firstClass) {
10800                    final long ident = Binder.clearCallingIdentity();
10801
10802                    // If permissions need a review before any of the app components can run,
10803                    // we return no provider and launch a review activity if the calling app
10804                    // is in the foreground.
10805                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10806                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10807                            return null;
10808                        }
10809                    }
10810
10811                    try {
10812                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10813                        ApplicationInfo ai =
10814                            AppGlobals.getPackageManager().
10815                                getApplicationInfo(
10816                                        cpi.applicationInfo.packageName,
10817                                        STOCK_PM_FLAGS, userId);
10818                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10819                        if (ai == null) {
10820                            Slog.w(TAG, "No package info for content provider "
10821                                    + cpi.name);
10822                            return null;
10823                        }
10824                        ai = getAppInfoForUser(ai, userId);
10825                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10826                    } catch (RemoteException ex) {
10827                        // pm is in same process, this will never happen.
10828                    } finally {
10829                        Binder.restoreCallingIdentity(ident);
10830                    }
10831                }
10832
10833                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10834
10835                if (r != null && cpr.canRunHere(r)) {
10836                    // If this is a multiprocess provider, then just return its
10837                    // info and allow the caller to instantiate it.  Only do
10838                    // this if the provider is the same user as the caller's
10839                    // process, or can run as root (so can be in any process).
10840                    return cpr.newHolder(null);
10841                }
10842
10843                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10844                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10845                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10846
10847                // This is single process, and our app is now connecting to it.
10848                // See if we are already in the process of launching this
10849                // provider.
10850                final int N = mLaunchingProviders.size();
10851                int i;
10852                for (i = 0; i < N; i++) {
10853                    if (mLaunchingProviders.get(i) == cpr) {
10854                        break;
10855                    }
10856                }
10857
10858                // If the provider is not already being launched, then get it
10859                // started.
10860                if (i >= N) {
10861                    final long origId = Binder.clearCallingIdentity();
10862
10863                    try {
10864                        // Content provider is now in use, its package can't be stopped.
10865                        try {
10866                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10867                            AppGlobals.getPackageManager().setPackageStoppedState(
10868                                    cpr.appInfo.packageName, false, userId);
10869                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10870                        } catch (RemoteException e) {
10871                        } catch (IllegalArgumentException e) {
10872                            Slog.w(TAG, "Failed trying to unstop package "
10873                                    + cpr.appInfo.packageName + ": " + e);
10874                        }
10875
10876                        // Use existing process if already started
10877                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10878                        ProcessRecord proc = getProcessRecordLocked(
10879                                cpi.processName, cpr.appInfo.uid, false);
10880                        if (proc != null && proc.thread != null && !proc.killed) {
10881                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10882                                    "Installing in existing process " + proc);
10883                            if (!proc.pubProviders.containsKey(cpi.name)) {
10884                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10885                                proc.pubProviders.put(cpi.name, cpr);
10886                                try {
10887                                    proc.thread.scheduleInstallProvider(cpi);
10888                                } catch (RemoteException e) {
10889                                }
10890                            }
10891                        } else {
10892                            checkTime(startTime, "getContentProviderImpl: before start process");
10893                            proc = startProcessLocked(cpi.processName,
10894                                    cpr.appInfo, false, 0, "content provider",
10895                                    new ComponentName(cpi.applicationInfo.packageName,
10896                                            cpi.name), false, false, false);
10897                            checkTime(startTime, "getContentProviderImpl: after start process");
10898                            if (proc == null) {
10899                                Slog.w(TAG, "Unable to launch app "
10900                                        + cpi.applicationInfo.packageName + "/"
10901                                        + cpi.applicationInfo.uid + " for provider "
10902                                        + name + ": process is bad");
10903                                return null;
10904                            }
10905                        }
10906                        cpr.launchingApp = proc;
10907                        mLaunchingProviders.add(cpr);
10908                    } finally {
10909                        Binder.restoreCallingIdentity(origId);
10910                    }
10911                }
10912
10913                checkTime(startTime, "getContentProviderImpl: updating data structures");
10914
10915                // Make sure the provider is published (the same provider class
10916                // may be published under multiple names).
10917                if (firstClass) {
10918                    mProviderMap.putProviderByClass(comp, cpr);
10919                }
10920
10921                mProviderMap.putProviderByName(name, cpr);
10922                conn = incProviderCountLocked(r, cpr, token, stable);
10923                if (conn != null) {
10924                    conn.waiting = true;
10925                }
10926            }
10927            checkTime(startTime, "getContentProviderImpl: done!");
10928        }
10929
10930        // Wait for the provider to be published...
10931        synchronized (cpr) {
10932            while (cpr.provider == null) {
10933                if (cpr.launchingApp == null) {
10934                    Slog.w(TAG, "Unable to launch app "
10935                            + cpi.applicationInfo.packageName + "/"
10936                            + cpi.applicationInfo.uid + " for provider "
10937                            + name + ": launching app became null");
10938                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10939                            UserHandle.getUserId(cpi.applicationInfo.uid),
10940                            cpi.applicationInfo.packageName,
10941                            cpi.applicationInfo.uid, name);
10942                    return null;
10943                }
10944                try {
10945                    if (DEBUG_MU) Slog.v(TAG_MU,
10946                            "Waiting to start provider " + cpr
10947                            + " launchingApp=" + cpr.launchingApp);
10948                    if (conn != null) {
10949                        conn.waiting = true;
10950                    }
10951                    cpr.wait();
10952                } catch (InterruptedException ex) {
10953                } finally {
10954                    if (conn != null) {
10955                        conn.waiting = false;
10956                    }
10957                }
10958            }
10959        }
10960        return cpr != null ? cpr.newHolder(conn) : null;
10961    }
10962
10963    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10964            ProcessRecord r, final int userId) {
10965        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10966                cpi.packageName, userId)) {
10967
10968            final boolean callerForeground = r == null || r.setSchedGroup
10969                    != ProcessList.SCHED_GROUP_BACKGROUND;
10970
10971            // Show a permission review UI only for starting from a foreground app
10972            if (!callerForeground) {
10973                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10974                        + cpi.packageName + " requires a permissions review");
10975                return false;
10976            }
10977
10978            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10979            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10980                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10981            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10982
10983            if (DEBUG_PERMISSIONS_REVIEW) {
10984                Slog.i(TAG, "u" + userId + " Launching permission review "
10985                        + "for package " + cpi.packageName);
10986            }
10987
10988            final UserHandle userHandle = new UserHandle(userId);
10989            mHandler.post(new Runnable() {
10990                @Override
10991                public void run() {
10992                    mContext.startActivityAsUser(intent, userHandle);
10993                }
10994            });
10995
10996            return false;
10997        }
10998
10999        return true;
11000    }
11001
11002    PackageManagerInternal getPackageManagerInternalLocked() {
11003        if (mPackageManagerInt == null) {
11004            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11005        }
11006        return mPackageManagerInt;
11007    }
11008
11009    @Override
11010    public final ContentProviderHolder getContentProvider(
11011            IApplicationThread caller, String name, int userId, boolean stable) {
11012        enforceNotIsolatedCaller("getContentProvider");
11013        if (caller == null) {
11014            String msg = "null IApplicationThread when getting content provider "
11015                    + name;
11016            Slog.w(TAG, msg);
11017            throw new SecurityException(msg);
11018        }
11019        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11020        // with cross-user grant.
11021        return getContentProviderImpl(caller, name, null, stable, userId);
11022    }
11023
11024    public ContentProviderHolder getContentProviderExternal(
11025            String name, int userId, IBinder token) {
11026        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11027            "Do not have permission in call getContentProviderExternal()");
11028        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11029                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11030        return getContentProviderExternalUnchecked(name, token, userId);
11031    }
11032
11033    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11034            IBinder token, int userId) {
11035        return getContentProviderImpl(null, name, token, true, userId);
11036    }
11037
11038    /**
11039     * Drop a content provider from a ProcessRecord's bookkeeping
11040     */
11041    public void removeContentProvider(IBinder connection, boolean stable) {
11042        enforceNotIsolatedCaller("removeContentProvider");
11043        long ident = Binder.clearCallingIdentity();
11044        try {
11045            synchronized (this) {
11046                ContentProviderConnection conn;
11047                try {
11048                    conn = (ContentProviderConnection)connection;
11049                } catch (ClassCastException e) {
11050                    String msg ="removeContentProvider: " + connection
11051                            + " not a ContentProviderConnection";
11052                    Slog.w(TAG, msg);
11053                    throw new IllegalArgumentException(msg);
11054                }
11055                if (conn == null) {
11056                    throw new NullPointerException("connection is null");
11057                }
11058                if (decProviderCountLocked(conn, null, null, stable)) {
11059                    updateOomAdjLocked();
11060                }
11061            }
11062        } finally {
11063            Binder.restoreCallingIdentity(ident);
11064        }
11065    }
11066
11067    public void removeContentProviderExternal(String name, IBinder token) {
11068        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11069            "Do not have permission in call removeContentProviderExternal()");
11070        int userId = UserHandle.getCallingUserId();
11071        long ident = Binder.clearCallingIdentity();
11072        try {
11073            removeContentProviderExternalUnchecked(name, token, userId);
11074        } finally {
11075            Binder.restoreCallingIdentity(ident);
11076        }
11077    }
11078
11079    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11080        synchronized (this) {
11081            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11082            if(cpr == null) {
11083                //remove from mProvidersByClass
11084                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11085                return;
11086            }
11087
11088            //update content provider record entry info
11089            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11090            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11091            if (localCpr.hasExternalProcessHandles()) {
11092                if (localCpr.removeExternalProcessHandleLocked(token)) {
11093                    updateOomAdjLocked();
11094                } else {
11095                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11096                            + " with no external reference for token: "
11097                            + token + ".");
11098                }
11099            } else {
11100                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11101                        + " with no external references.");
11102            }
11103        }
11104    }
11105
11106    public final void publishContentProviders(IApplicationThread caller,
11107            List<ContentProviderHolder> providers) {
11108        if (providers == null) {
11109            return;
11110        }
11111
11112        enforceNotIsolatedCaller("publishContentProviders");
11113        synchronized (this) {
11114            final ProcessRecord r = getRecordForAppLocked(caller);
11115            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11116            if (r == null) {
11117                throw new SecurityException(
11118                        "Unable to find app for caller " + caller
11119                      + " (pid=" + Binder.getCallingPid()
11120                      + ") when publishing content providers");
11121            }
11122
11123            final long origId = Binder.clearCallingIdentity();
11124
11125            final int N = providers.size();
11126            for (int i = 0; i < N; i++) {
11127                ContentProviderHolder src = providers.get(i);
11128                if (src == null || src.info == null || src.provider == null) {
11129                    continue;
11130                }
11131                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11132                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11133                if (dst != null) {
11134                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11135                    mProviderMap.putProviderByClass(comp, dst);
11136                    String names[] = dst.info.authority.split(";");
11137                    for (int j = 0; j < names.length; j++) {
11138                        mProviderMap.putProviderByName(names[j], dst);
11139                    }
11140
11141                    int launchingCount = mLaunchingProviders.size();
11142                    int j;
11143                    boolean wasInLaunchingProviders = false;
11144                    for (j = 0; j < launchingCount; j++) {
11145                        if (mLaunchingProviders.get(j) == dst) {
11146                            mLaunchingProviders.remove(j);
11147                            wasInLaunchingProviders = true;
11148                            j--;
11149                            launchingCount--;
11150                        }
11151                    }
11152                    if (wasInLaunchingProviders) {
11153                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11154                    }
11155                    synchronized (dst) {
11156                        dst.provider = src.provider;
11157                        dst.proc = r;
11158                        dst.notifyAll();
11159                    }
11160                    updateOomAdjLocked(r);
11161                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11162                            src.info.authority);
11163                }
11164            }
11165
11166            Binder.restoreCallingIdentity(origId);
11167        }
11168    }
11169
11170    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11171        ContentProviderConnection conn;
11172        try {
11173            conn = (ContentProviderConnection)connection;
11174        } catch (ClassCastException e) {
11175            String msg ="refContentProvider: " + connection
11176                    + " not a ContentProviderConnection";
11177            Slog.w(TAG, msg);
11178            throw new IllegalArgumentException(msg);
11179        }
11180        if (conn == null) {
11181            throw new NullPointerException("connection is null");
11182        }
11183
11184        synchronized (this) {
11185            if (stable > 0) {
11186                conn.numStableIncs += stable;
11187            }
11188            stable = conn.stableCount + stable;
11189            if (stable < 0) {
11190                throw new IllegalStateException("stableCount < 0: " + stable);
11191            }
11192
11193            if (unstable > 0) {
11194                conn.numUnstableIncs += unstable;
11195            }
11196            unstable = conn.unstableCount + unstable;
11197            if (unstable < 0) {
11198                throw new IllegalStateException("unstableCount < 0: " + unstable);
11199            }
11200
11201            if ((stable+unstable) <= 0) {
11202                throw new IllegalStateException("ref counts can't go to zero here: stable="
11203                        + stable + " unstable=" + unstable);
11204            }
11205            conn.stableCount = stable;
11206            conn.unstableCount = unstable;
11207            return !conn.dead;
11208        }
11209    }
11210
11211    public void unstableProviderDied(IBinder connection) {
11212        ContentProviderConnection conn;
11213        try {
11214            conn = (ContentProviderConnection)connection;
11215        } catch (ClassCastException e) {
11216            String msg ="refContentProvider: " + connection
11217                    + " not a ContentProviderConnection";
11218            Slog.w(TAG, msg);
11219            throw new IllegalArgumentException(msg);
11220        }
11221        if (conn == null) {
11222            throw new NullPointerException("connection is null");
11223        }
11224
11225        // Safely retrieve the content provider associated with the connection.
11226        IContentProvider provider;
11227        synchronized (this) {
11228            provider = conn.provider.provider;
11229        }
11230
11231        if (provider == null) {
11232            // Um, yeah, we're way ahead of you.
11233            return;
11234        }
11235
11236        // Make sure the caller is being honest with us.
11237        if (provider.asBinder().pingBinder()) {
11238            // Er, no, still looks good to us.
11239            synchronized (this) {
11240                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11241                        + " says " + conn + " died, but we don't agree");
11242                return;
11243            }
11244        }
11245
11246        // Well look at that!  It's dead!
11247        synchronized (this) {
11248            if (conn.provider.provider != provider) {
11249                // But something changed...  good enough.
11250                return;
11251            }
11252
11253            ProcessRecord proc = conn.provider.proc;
11254            if (proc == null || proc.thread == null) {
11255                // Seems like the process is already cleaned up.
11256                return;
11257            }
11258
11259            // As far as we're concerned, this is just like receiving a
11260            // death notification...  just a bit prematurely.
11261            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11262                    + ") early provider death");
11263            final long ident = Binder.clearCallingIdentity();
11264            try {
11265                appDiedLocked(proc);
11266            } finally {
11267                Binder.restoreCallingIdentity(ident);
11268            }
11269        }
11270    }
11271
11272    @Override
11273    public void appNotRespondingViaProvider(IBinder connection) {
11274        enforceCallingPermission(
11275                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11276
11277        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11278        if (conn == null) {
11279            Slog.w(TAG, "ContentProviderConnection is null");
11280            return;
11281        }
11282
11283        final ProcessRecord host = conn.provider.proc;
11284        if (host == null) {
11285            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11286            return;
11287        }
11288
11289        mHandler.post(new Runnable() {
11290            @Override
11291            public void run() {
11292                mAppErrors.appNotResponding(host, null, null, false,
11293                        "ContentProvider not responding");
11294            }
11295        });
11296    }
11297
11298    public final void installSystemProviders() {
11299        List<ProviderInfo> providers;
11300        synchronized (this) {
11301            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11302            providers = generateApplicationProvidersLocked(app);
11303            if (providers != null) {
11304                for (int i=providers.size()-1; i>=0; i--) {
11305                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11306                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11307                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11308                                + ": not system .apk");
11309                        providers.remove(i);
11310                    }
11311                }
11312            }
11313        }
11314        if (providers != null) {
11315            mSystemThread.installSystemProviders(providers);
11316        }
11317
11318        mCoreSettingsObserver = new CoreSettingsObserver(this);
11319        mFontScaleSettingObserver = new FontScaleSettingObserver();
11320
11321        //mUsageStatsService.monitorPackages();
11322    }
11323
11324    private void startPersistentApps(int matchFlags) {
11325        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11326
11327        synchronized (this) {
11328            try {
11329                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11330                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11331                for (ApplicationInfo app : apps) {
11332                    if (!"android".equals(app.packageName)) {
11333                        addAppLocked(app, false, null /* ABI override */);
11334                    }
11335                }
11336            } catch (RemoteException ex) {
11337            }
11338        }
11339    }
11340
11341    /**
11342     * When a user is unlocked, we need to install encryption-unaware providers
11343     * belonging to any running apps.
11344     */
11345    private void installEncryptionUnawareProviders(int userId) {
11346        // We're only interested in providers that are encryption unaware, and
11347        // we don't care about uninstalled apps, since there's no way they're
11348        // running at this point.
11349        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11350
11351        synchronized (this) {
11352            final int NP = mProcessNames.getMap().size();
11353            for (int ip = 0; ip < NP; ip++) {
11354                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11355                final int NA = apps.size();
11356                for (int ia = 0; ia < NA; ia++) {
11357                    final ProcessRecord app = apps.valueAt(ia);
11358                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11359
11360                    final int NG = app.pkgList.size();
11361                    for (int ig = 0; ig < NG; ig++) {
11362                        try {
11363                            final String pkgName = app.pkgList.keyAt(ig);
11364                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11365                                    .getPackageInfo(pkgName, matchFlags, userId);
11366                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11367                                for (ProviderInfo pi : pkgInfo.providers) {
11368                                    // TODO: keep in sync with generateApplicationProvidersLocked
11369                                    final boolean processMatch = Objects.equals(pi.processName,
11370                                            app.processName) || pi.multiprocess;
11371                                    final boolean userMatch = isSingleton(pi.processName,
11372                                            pi.applicationInfo, pi.name, pi.flags)
11373                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11374                                    if (processMatch && userMatch) {
11375                                        Log.v(TAG, "Installing " + pi);
11376                                        app.thread.scheduleInstallProvider(pi);
11377                                    } else {
11378                                        Log.v(TAG, "Skipping " + pi);
11379                                    }
11380                                }
11381                            }
11382                        } catch (RemoteException ignored) {
11383                        }
11384                    }
11385                }
11386            }
11387        }
11388    }
11389
11390    /**
11391     * Allows apps to retrieve the MIME type of a URI.
11392     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11393     * users, then it does not need permission to access the ContentProvider.
11394     * Either, it needs cross-user uri grants.
11395     *
11396     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11397     *
11398     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11399     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11400     */
11401    public String getProviderMimeType(Uri uri, int userId) {
11402        enforceNotIsolatedCaller("getProviderMimeType");
11403        final String name = uri.getAuthority();
11404        int callingUid = Binder.getCallingUid();
11405        int callingPid = Binder.getCallingPid();
11406        long ident = 0;
11407        boolean clearedIdentity = false;
11408        synchronized (this) {
11409            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11410        }
11411        if (canClearIdentity(callingPid, callingUid, userId)) {
11412            clearedIdentity = true;
11413            ident = Binder.clearCallingIdentity();
11414        }
11415        ContentProviderHolder holder = null;
11416        try {
11417            holder = getContentProviderExternalUnchecked(name, null, userId);
11418            if (holder != null) {
11419                return holder.provider.getType(uri);
11420            }
11421        } catch (RemoteException e) {
11422            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11423            return null;
11424        } catch (Exception e) {
11425            Log.w(TAG, "Exception while determining type of " + uri, e);
11426            return null;
11427        } finally {
11428            // We need to clear the identity to call removeContentProviderExternalUnchecked
11429            if (!clearedIdentity) {
11430                ident = Binder.clearCallingIdentity();
11431            }
11432            try {
11433                if (holder != null) {
11434                    removeContentProviderExternalUnchecked(name, null, userId);
11435                }
11436            } finally {
11437                Binder.restoreCallingIdentity(ident);
11438            }
11439        }
11440
11441        return null;
11442    }
11443
11444    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11445        if (UserHandle.getUserId(callingUid) == userId) {
11446            return true;
11447        }
11448        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11449                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11450                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11451                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11452                return true;
11453        }
11454        return false;
11455    }
11456
11457    // =========================================================
11458    // GLOBAL MANAGEMENT
11459    // =========================================================
11460
11461    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11462            boolean isolated, int isolatedUid) {
11463        String proc = customProcess != null ? customProcess : info.processName;
11464        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11465        final int userId = UserHandle.getUserId(info.uid);
11466        int uid = info.uid;
11467        if (isolated) {
11468            if (isolatedUid == 0) {
11469                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11470                while (true) {
11471                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11472                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11473                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11474                    }
11475                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11476                    mNextIsolatedProcessUid++;
11477                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11478                        // No process for this uid, use it.
11479                        break;
11480                    }
11481                    stepsLeft--;
11482                    if (stepsLeft <= 0) {
11483                        return null;
11484                    }
11485                }
11486            } else {
11487                // Special case for startIsolatedProcess (internal only), where
11488                // the uid of the isolated process is specified by the caller.
11489                uid = isolatedUid;
11490            }
11491
11492            // Register the isolated UID with this application so BatteryStats knows to
11493            // attribute resource usage to the application.
11494            //
11495            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11496            // about the process state of the isolated UID *before* it is registered with the
11497            // owning application.
11498            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11499        }
11500        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11501        if (!mBooted && !mBooting
11502                && userId == UserHandle.USER_SYSTEM
11503                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11504            r.persistent = true;
11505        }
11506        addProcessNameLocked(r);
11507        return r;
11508    }
11509
11510    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11511            String abiOverride) {
11512        ProcessRecord app;
11513        if (!isolated) {
11514            app = getProcessRecordLocked(info.processName, info.uid, true);
11515        } else {
11516            app = null;
11517        }
11518
11519        if (app == null) {
11520            app = newProcessRecordLocked(info, null, isolated, 0);
11521            updateLruProcessLocked(app, false, null);
11522            updateOomAdjLocked();
11523        }
11524
11525        // This package really, really can not be stopped.
11526        try {
11527            AppGlobals.getPackageManager().setPackageStoppedState(
11528                    info.packageName, false, UserHandle.getUserId(app.uid));
11529        } catch (RemoteException e) {
11530        } catch (IllegalArgumentException e) {
11531            Slog.w(TAG, "Failed trying to unstop package "
11532                    + info.packageName + ": " + e);
11533        }
11534
11535        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11536            app.persistent = true;
11537            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11538        }
11539        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11540            mPersistentStartingProcesses.add(app);
11541            startProcessLocked(app, "added application", app.processName, abiOverride,
11542                    null /* entryPoint */, null /* entryPointArgs */);
11543        }
11544
11545        return app;
11546    }
11547
11548    public void unhandledBack() {
11549        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11550                "unhandledBack()");
11551
11552        synchronized(this) {
11553            final long origId = Binder.clearCallingIdentity();
11554            try {
11555                getFocusedStack().unhandledBackLocked();
11556            } finally {
11557                Binder.restoreCallingIdentity(origId);
11558            }
11559        }
11560    }
11561
11562    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11563        enforceNotIsolatedCaller("openContentUri");
11564        final int userId = UserHandle.getCallingUserId();
11565        String name = uri.getAuthority();
11566        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11567        ParcelFileDescriptor pfd = null;
11568        if (cph != null) {
11569            // We record the binder invoker's uid in thread-local storage before
11570            // going to the content provider to open the file.  Later, in the code
11571            // that handles all permissions checks, we look for this uid and use
11572            // that rather than the Activity Manager's own uid.  The effect is that
11573            // we do the check against the caller's permissions even though it looks
11574            // to the content provider like the Activity Manager itself is making
11575            // the request.
11576            Binder token = new Binder();
11577            sCallerIdentity.set(new Identity(
11578                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11579            try {
11580                pfd = cph.provider.openFile(null, uri, "r", null, token);
11581            } catch (FileNotFoundException e) {
11582                // do nothing; pfd will be returned null
11583            } finally {
11584                // Ensure that whatever happens, we clean up the identity state
11585                sCallerIdentity.remove();
11586                // Ensure we're done with the provider.
11587                removeContentProviderExternalUnchecked(name, null, userId);
11588            }
11589        } else {
11590            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11591        }
11592        return pfd;
11593    }
11594
11595    // Actually is sleeping or shutting down or whatever else in the future
11596    // is an inactive state.
11597    boolean isSleepingOrShuttingDownLocked() {
11598        return isSleepingLocked() || mShuttingDown;
11599    }
11600
11601    boolean isShuttingDownLocked() {
11602        return mShuttingDown;
11603    }
11604
11605    boolean isSleepingLocked() {
11606        return mSleeping;
11607    }
11608
11609    void onWakefulnessChanged(int wakefulness) {
11610        synchronized(this) {
11611            mWakefulness = wakefulness;
11612            updateSleepIfNeededLocked();
11613        }
11614    }
11615
11616    void finishRunningVoiceLocked() {
11617        if (mRunningVoice != null) {
11618            mRunningVoice = null;
11619            mVoiceWakeLock.release();
11620            updateSleepIfNeededLocked();
11621        }
11622    }
11623
11624    void startTimeTrackingFocusedActivityLocked() {
11625        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11626            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11627        }
11628    }
11629
11630    void updateSleepIfNeededLocked() {
11631        if (mSleeping && !shouldSleepLocked()) {
11632            mSleeping = false;
11633            startTimeTrackingFocusedActivityLocked();
11634            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11635            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11636            updateOomAdjLocked();
11637        } else if (!mSleeping && shouldSleepLocked()) {
11638            mSleeping = true;
11639            if (mCurAppTimeTracker != null) {
11640                mCurAppTimeTracker.stop();
11641            }
11642            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11643            mStackSupervisor.goingToSleepLocked();
11644            updateOomAdjLocked();
11645
11646            // Initialize the wake times of all processes.
11647            checkExcessivePowerUsageLocked(false);
11648            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11649            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11650            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11651        }
11652    }
11653
11654    private boolean shouldSleepLocked() {
11655        // Resume applications while running a voice interactor.
11656        if (mRunningVoice != null) {
11657            return false;
11658        }
11659
11660        // TODO: Transform the lock screen state into a sleep token instead.
11661        switch (mWakefulness) {
11662            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11663            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11664            case PowerManagerInternal.WAKEFULNESS_DOZING:
11665                // Pause applications whenever the lock screen is shown or any sleep
11666                // tokens have been acquired.
11667                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11668            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11669            default:
11670                // If we're asleep then pause applications unconditionally.
11671                return true;
11672        }
11673    }
11674
11675    /** Pokes the task persister. */
11676    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11677        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11678    }
11679
11680    /** Notifies all listeners when the task stack has changed. */
11681    void notifyTaskStackChangedLocked() {
11682        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11683        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11684        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11685        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11686    }
11687
11688    /** Notifies all listeners when an Activity is pinned. */
11689    void notifyActivityPinnedLocked() {
11690        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11691        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11692    }
11693
11694    /**
11695     * Notifies all listeners when an attempt was made to start an an activity that is already
11696     * running in the pinned stack and the activity was not actually started, but the task is
11697     * either brought to the front or a new Intent is delivered to it.
11698     */
11699    void notifyPinnedActivityRestartAttemptLocked() {
11700        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11701        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11702    }
11703
11704    /** Notifies all listeners when the pinned stack animation ends. */
11705    @Override
11706    public void notifyPinnedStackAnimationEnded() {
11707        synchronized (this) {
11708            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11709            mHandler.obtainMessage(
11710                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11711        }
11712    }
11713
11714    @Override
11715    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11716        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11717    }
11718
11719    @Override
11720    public boolean shutdown(int timeout) {
11721        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11722                != PackageManager.PERMISSION_GRANTED) {
11723            throw new SecurityException("Requires permission "
11724                    + android.Manifest.permission.SHUTDOWN);
11725        }
11726
11727        boolean timedout = false;
11728
11729        synchronized(this) {
11730            mShuttingDown = true;
11731            updateEventDispatchingLocked();
11732            timedout = mStackSupervisor.shutdownLocked(timeout);
11733        }
11734
11735        mAppOpsService.shutdown();
11736        if (mUsageStatsService != null) {
11737            mUsageStatsService.prepareShutdown();
11738        }
11739        mBatteryStatsService.shutdown();
11740        synchronized (this) {
11741            mProcessStats.shutdownLocked();
11742            notifyTaskPersisterLocked(null, true);
11743        }
11744
11745        return timedout;
11746    }
11747
11748    public final void activitySlept(IBinder token) {
11749        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11750
11751        final long origId = Binder.clearCallingIdentity();
11752
11753        synchronized (this) {
11754            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11755            if (r != null) {
11756                mStackSupervisor.activitySleptLocked(r);
11757            }
11758        }
11759
11760        Binder.restoreCallingIdentity(origId);
11761    }
11762
11763    private String lockScreenShownToString() {
11764        switch (mLockScreenShown) {
11765            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11766            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11767            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11768            default: return "Unknown=" + mLockScreenShown;
11769        }
11770    }
11771
11772    void logLockScreen(String msg) {
11773        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11774                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11775                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11776                + " mSleeping=" + mSleeping);
11777    }
11778
11779    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11780        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11781        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11782        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11783            boolean wasRunningVoice = mRunningVoice != null;
11784            mRunningVoice = session;
11785            if (!wasRunningVoice) {
11786                mVoiceWakeLock.acquire();
11787                updateSleepIfNeededLocked();
11788            }
11789        }
11790    }
11791
11792    private void updateEventDispatchingLocked() {
11793        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11794    }
11795
11796    public void setLockScreenShown(boolean showing, boolean occluded) {
11797        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11798                != PackageManager.PERMISSION_GRANTED) {
11799            throw new SecurityException("Requires permission "
11800                    + android.Manifest.permission.DEVICE_POWER);
11801        }
11802
11803        synchronized(this) {
11804            long ident = Binder.clearCallingIdentity();
11805            try {
11806                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11807                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11808                if (showing && occluded) {
11809                    // The lock screen is currently showing, but is occluded by a window that can
11810                    // show on top of the lock screen. In this can we want to dismiss the docked
11811                    // stack since it will be complicated/risky to try to put the activity on top
11812                    // of the lock screen in the right fullscreen configuration.
11813                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11814                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11815                }
11816
11817                updateSleepIfNeededLocked();
11818            } finally {
11819                Binder.restoreCallingIdentity(ident);
11820            }
11821        }
11822    }
11823
11824    @Override
11825    public void notifyLockedProfile(@UserIdInt int userId) {
11826        try {
11827            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11828                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11829            }
11830        } catch (RemoteException ex) {
11831            throw new SecurityException("Fail to check is caller a privileged app", ex);
11832        }
11833
11834        synchronized (this) {
11835            if (mStackSupervisor.isUserLockedProfile(userId)) {
11836                final long ident = Binder.clearCallingIdentity();
11837                try {
11838                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11839
11840                    // Drop locked freeform tasks out into the fullscreen stack.
11841                    // TODO: Redact the tasks in place. It's much better to keep them on the screen
11842                    //       where they were before, but in an obscured state.
11843                    mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11844
11845                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11846                        // If there is no device lock, we will show the profile's credential page.
11847                        mActivityStarter.showConfirmDeviceCredential(userId);
11848                    } else {
11849                        // Showing launcher to avoid user entering credential twice.
11850                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11851                    }
11852                } finally {
11853                    Binder.restoreCallingIdentity(ident);
11854                }
11855            }
11856        }
11857    }
11858
11859    @Override
11860    public void startConfirmDeviceCredentialIntent(Intent intent) {
11861        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11862        synchronized (this) {
11863            final long ident = Binder.clearCallingIdentity();
11864            try {
11865                mActivityStarter.startConfirmCredentialIntent(intent);
11866            } finally {
11867                Binder.restoreCallingIdentity(ident);
11868            }
11869        }
11870    }
11871
11872    @Override
11873    public void stopAppSwitches() {
11874        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11875                != PackageManager.PERMISSION_GRANTED) {
11876            throw new SecurityException("viewquires permission "
11877                    + android.Manifest.permission.STOP_APP_SWITCHES);
11878        }
11879
11880        synchronized(this) {
11881            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11882                    + APP_SWITCH_DELAY_TIME;
11883            mDidAppSwitch = false;
11884            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11885            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11886            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11887        }
11888    }
11889
11890    public void resumeAppSwitches() {
11891        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11892                != PackageManager.PERMISSION_GRANTED) {
11893            throw new SecurityException("Requires permission "
11894                    + android.Manifest.permission.STOP_APP_SWITCHES);
11895        }
11896
11897        synchronized(this) {
11898            // Note that we don't execute any pending app switches... we will
11899            // let those wait until either the timeout, or the next start
11900            // activity request.
11901            mAppSwitchesAllowedTime = 0;
11902        }
11903    }
11904
11905    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11906            int callingPid, int callingUid, String name) {
11907        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11908            return true;
11909        }
11910
11911        int perm = checkComponentPermission(
11912                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11913                sourceUid, -1, true);
11914        if (perm == PackageManager.PERMISSION_GRANTED) {
11915            return true;
11916        }
11917
11918        // If the actual IPC caller is different from the logical source, then
11919        // also see if they are allowed to control app switches.
11920        if (callingUid != -1 && callingUid != sourceUid) {
11921            perm = checkComponentPermission(
11922                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11923                    callingUid, -1, true);
11924            if (perm == PackageManager.PERMISSION_GRANTED) {
11925                return true;
11926            }
11927        }
11928
11929        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11930        return false;
11931    }
11932
11933    public void setDebugApp(String packageName, boolean waitForDebugger,
11934            boolean persistent) {
11935        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11936                "setDebugApp()");
11937
11938        long ident = Binder.clearCallingIdentity();
11939        try {
11940            // Note that this is not really thread safe if there are multiple
11941            // callers into it at the same time, but that's not a situation we
11942            // care about.
11943            if (persistent) {
11944                final ContentResolver resolver = mContext.getContentResolver();
11945                Settings.Global.putString(
11946                    resolver, Settings.Global.DEBUG_APP,
11947                    packageName);
11948                Settings.Global.putInt(
11949                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11950                    waitForDebugger ? 1 : 0);
11951            }
11952
11953            synchronized (this) {
11954                if (!persistent) {
11955                    mOrigDebugApp = mDebugApp;
11956                    mOrigWaitForDebugger = mWaitForDebugger;
11957                }
11958                mDebugApp = packageName;
11959                mWaitForDebugger = waitForDebugger;
11960                mDebugTransient = !persistent;
11961                if (packageName != null) {
11962                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11963                            false, UserHandle.USER_ALL, "set debug app");
11964                }
11965            }
11966        } finally {
11967            Binder.restoreCallingIdentity(ident);
11968        }
11969    }
11970
11971    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11972        synchronized (this) {
11973            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11974            if (!isDebuggable) {
11975                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11976                    throw new SecurityException("Process not debuggable: " + app.packageName);
11977                }
11978            }
11979
11980            mTrackAllocationApp = processName;
11981        }
11982    }
11983
11984    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11985        synchronized (this) {
11986            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11987            if (!isDebuggable) {
11988                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11989                    throw new SecurityException("Process not debuggable: " + app.packageName);
11990                }
11991            }
11992            mProfileApp = processName;
11993            mProfileFile = profilerInfo.profileFile;
11994            if (mProfileFd != null) {
11995                try {
11996                    mProfileFd.close();
11997                } catch (IOException e) {
11998                }
11999                mProfileFd = null;
12000            }
12001            mProfileFd = profilerInfo.profileFd;
12002            mSamplingInterval = profilerInfo.samplingInterval;
12003            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12004            mProfileType = 0;
12005        }
12006    }
12007
12008    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12009        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12010        if (!isDebuggable) {
12011            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12012                throw new SecurityException("Process not debuggable: " + app.packageName);
12013            }
12014        }
12015        mNativeDebuggingApp = processName;
12016    }
12017
12018    @Override
12019    public void setAlwaysFinish(boolean enabled) {
12020        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12021                "setAlwaysFinish()");
12022
12023        long ident = Binder.clearCallingIdentity();
12024        try {
12025            Settings.Global.putInt(
12026                    mContext.getContentResolver(),
12027                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12028
12029            synchronized (this) {
12030                mAlwaysFinishActivities = enabled;
12031            }
12032        } finally {
12033            Binder.restoreCallingIdentity(ident);
12034        }
12035    }
12036
12037    @Override
12038    public void setLenientBackgroundCheck(boolean enabled) {
12039        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12040                "setLenientBackgroundCheck()");
12041
12042        long ident = Binder.clearCallingIdentity();
12043        try {
12044            Settings.Global.putInt(
12045                    mContext.getContentResolver(),
12046                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12047
12048            synchronized (this) {
12049                mLenientBackgroundCheck = enabled;
12050            }
12051        } finally {
12052            Binder.restoreCallingIdentity(ident);
12053        }
12054    }
12055
12056    @Override
12057    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12058        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12059                "setActivityController()");
12060        synchronized (this) {
12061            mController = controller;
12062            mControllerIsAMonkey = imAMonkey;
12063            Watchdog.getInstance().setActivityController(controller);
12064        }
12065    }
12066
12067    @Override
12068    public void setUserIsMonkey(boolean userIsMonkey) {
12069        synchronized (this) {
12070            synchronized (mPidsSelfLocked) {
12071                final int callingPid = Binder.getCallingPid();
12072                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12073                if (precessRecord == null) {
12074                    throw new SecurityException("Unknown process: " + callingPid);
12075                }
12076                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12077                    throw new SecurityException("Only an instrumentation process "
12078                            + "with a UiAutomation can call setUserIsMonkey");
12079                }
12080            }
12081            mUserIsMonkey = userIsMonkey;
12082        }
12083    }
12084
12085    @Override
12086    public boolean isUserAMonkey() {
12087        synchronized (this) {
12088            // If there is a controller also implies the user is a monkey.
12089            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12090        }
12091    }
12092
12093    public void requestBugReport(int bugreportType) {
12094        String service = null;
12095        switch (bugreportType) {
12096            case ActivityManager.BUGREPORT_OPTION_FULL:
12097                service = "bugreport";
12098                break;
12099            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12100                service = "bugreportplus";
12101                break;
12102            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12103                service = "bugreportremote";
12104                break;
12105            case ActivityManager.BUGREPORT_OPTION_WEAR:
12106                service = "bugreportwear";
12107                break;
12108        }
12109        if (service == null) {
12110            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12111                    + bugreportType);
12112        }
12113        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12114        SystemProperties.set("ctl.start", service);
12115    }
12116
12117    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12118        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12119    }
12120
12121    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12122        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12123            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12124        }
12125        return KEY_DISPATCHING_TIMEOUT;
12126    }
12127
12128    @Override
12129    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12130        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12131                != PackageManager.PERMISSION_GRANTED) {
12132            throw new SecurityException("Requires permission "
12133                    + android.Manifest.permission.FILTER_EVENTS);
12134        }
12135        ProcessRecord proc;
12136        long timeout;
12137        synchronized (this) {
12138            synchronized (mPidsSelfLocked) {
12139                proc = mPidsSelfLocked.get(pid);
12140            }
12141            timeout = getInputDispatchingTimeoutLocked(proc);
12142        }
12143
12144        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12145            return -1;
12146        }
12147
12148        return timeout;
12149    }
12150
12151    /**
12152     * Handle input dispatching timeouts.
12153     * Returns whether input dispatching should be aborted or not.
12154     */
12155    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12156            final ActivityRecord activity, final ActivityRecord parent,
12157            final boolean aboveSystem, String reason) {
12158        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12159                != PackageManager.PERMISSION_GRANTED) {
12160            throw new SecurityException("Requires permission "
12161                    + android.Manifest.permission.FILTER_EVENTS);
12162        }
12163
12164        final String annotation;
12165        if (reason == null) {
12166            annotation = "Input dispatching timed out";
12167        } else {
12168            annotation = "Input dispatching timed out (" + reason + ")";
12169        }
12170
12171        if (proc != null) {
12172            synchronized (this) {
12173                if (proc.debugging) {
12174                    return false;
12175                }
12176
12177                if (mDidDexOpt) {
12178                    // Give more time since we were dexopting.
12179                    mDidDexOpt = false;
12180                    return false;
12181                }
12182
12183                if (proc.instrumentationClass != null) {
12184                    Bundle info = new Bundle();
12185                    info.putString("shortMsg", "keyDispatchingTimedOut");
12186                    info.putString("longMsg", annotation);
12187                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12188                    return true;
12189                }
12190            }
12191            mHandler.post(new Runnable() {
12192                @Override
12193                public void run() {
12194                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12195                }
12196            });
12197        }
12198
12199        return true;
12200    }
12201
12202    @Override
12203    public Bundle getAssistContextExtras(int requestType) {
12204        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12205                null, null, true /* focused */, true /* newSessionId */,
12206                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12207        if (pae == null) {
12208            return null;
12209        }
12210        synchronized (pae) {
12211            while (!pae.haveResult) {
12212                try {
12213                    pae.wait();
12214                } catch (InterruptedException e) {
12215                }
12216            }
12217        }
12218        synchronized (this) {
12219            buildAssistBundleLocked(pae, pae.result);
12220            mPendingAssistExtras.remove(pae);
12221            mUiHandler.removeCallbacks(pae);
12222        }
12223        return pae.extras;
12224    }
12225
12226    @Override
12227    public boolean isAssistDataAllowedOnCurrentActivity() {
12228        int userId;
12229        synchronized (this) {
12230            userId = mUserController.getCurrentUserIdLocked();
12231            ActivityRecord activity = getFocusedStack().topActivity();
12232            if (activity == null) {
12233                return false;
12234            }
12235            userId = activity.userId;
12236        }
12237        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12238                Context.DEVICE_POLICY_SERVICE);
12239        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12240    }
12241
12242    @Override
12243    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12244        long ident = Binder.clearCallingIdentity();
12245        try {
12246            synchronized (this) {
12247                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12248                ActivityRecord top = getFocusedStack().topActivity();
12249                if (top != caller) {
12250                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12251                            + " is not current top " + top);
12252                    return false;
12253                }
12254                if (!top.nowVisible) {
12255                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12256                            + " is not visible");
12257                    return false;
12258                }
12259            }
12260            AssistUtils utils = new AssistUtils(mContext);
12261            return utils.showSessionForActiveService(args,
12262                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12263        } finally {
12264            Binder.restoreCallingIdentity(ident);
12265        }
12266    }
12267
12268    @Override
12269    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12270            Bundle receiverExtras,
12271            IBinder activityToken, boolean focused, boolean newSessionId) {
12272        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12273                activityToken, focused, newSessionId,
12274                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12275                != null;
12276    }
12277
12278    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12279            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12280            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12281        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12282                "enqueueAssistContext()");
12283        synchronized (this) {
12284            ActivityRecord activity = getFocusedStack().topActivity();
12285            if (activity == null) {
12286                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12287                return null;
12288            }
12289            if (activity.app == null || activity.app.thread == null) {
12290                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12291                return null;
12292            }
12293            if (focused) {
12294                if (activityToken != null) {
12295                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12296                    if (activity != caller) {
12297                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12298                                + " is not current top " + activity);
12299                        return null;
12300                    }
12301                }
12302            } else {
12303                activity = ActivityRecord.forTokenLocked(activityToken);
12304                if (activity == null) {
12305                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12306                            + " couldn't be found");
12307                    return null;
12308                }
12309            }
12310
12311            PendingAssistExtras pae;
12312            Bundle extras = new Bundle();
12313            if (args != null) {
12314                extras.putAll(args);
12315            }
12316            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12317            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12318            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12319                    userHandle);
12320            // Increment the sessionId if necessary
12321            if (newSessionId) {
12322                mViSessionId++;
12323            }
12324            try {
12325                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12326                        requestType, mViSessionId);
12327                mPendingAssistExtras.add(pae);
12328                mUiHandler.postDelayed(pae, timeout);
12329            } catch (RemoteException e) {
12330                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12331                return null;
12332            }
12333            return pae;
12334        }
12335    }
12336
12337    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12338        IResultReceiver receiver;
12339        synchronized (this) {
12340            mPendingAssistExtras.remove(pae);
12341            receiver = pae.receiver;
12342        }
12343        if (receiver != null) {
12344            // Caller wants result sent back to them.
12345            Bundle sendBundle = new Bundle();
12346            // At least return the receiver extras
12347            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12348                    pae.receiverExtras);
12349            try {
12350                pae.receiver.send(0, sendBundle);
12351            } catch (RemoteException e) {
12352            }
12353        }
12354    }
12355
12356    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12357        if (result != null) {
12358            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12359        }
12360        if (pae.hint != null) {
12361            pae.extras.putBoolean(pae.hint, true);
12362        }
12363    }
12364
12365    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12366            AssistContent content, Uri referrer) {
12367        PendingAssistExtras pae = (PendingAssistExtras)token;
12368        synchronized (pae) {
12369            pae.result = extras;
12370            pae.structure = structure;
12371            pae.content = content;
12372            if (referrer != null) {
12373                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12374            }
12375            pae.haveResult = true;
12376            pae.notifyAll();
12377            if (pae.intent == null && pae.receiver == null) {
12378                // Caller is just waiting for the result.
12379                return;
12380            }
12381        }
12382
12383        // We are now ready to launch the assist activity.
12384        IResultReceiver sendReceiver = null;
12385        Bundle sendBundle = null;
12386        synchronized (this) {
12387            buildAssistBundleLocked(pae, extras);
12388            boolean exists = mPendingAssistExtras.remove(pae);
12389            mUiHandler.removeCallbacks(pae);
12390            if (!exists) {
12391                // Timed out.
12392                return;
12393            }
12394            if ((sendReceiver=pae.receiver) != null) {
12395                // Caller wants result sent back to them.
12396                sendBundle = new Bundle();
12397                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12398                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12399                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12400                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12401                        pae.receiverExtras);
12402            }
12403        }
12404        if (sendReceiver != null) {
12405            try {
12406                sendReceiver.send(0, sendBundle);
12407            } catch (RemoteException e) {
12408            }
12409            return;
12410        }
12411
12412        long ident = Binder.clearCallingIdentity();
12413        try {
12414            pae.intent.replaceExtras(pae.extras);
12415            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12416                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12417                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12418            closeSystemDialogs("assist");
12419            try {
12420                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12421            } catch (ActivityNotFoundException e) {
12422                Slog.w(TAG, "No activity to handle assist action.", e);
12423            }
12424        } finally {
12425            Binder.restoreCallingIdentity(ident);
12426        }
12427    }
12428
12429    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12430            Bundle args) {
12431        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12432                true /* focused */, true /* newSessionId */,
12433                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12434    }
12435
12436    public void registerProcessObserver(IProcessObserver observer) {
12437        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12438                "registerProcessObserver()");
12439        synchronized (this) {
12440            mProcessObservers.register(observer);
12441        }
12442    }
12443
12444    @Override
12445    public void unregisterProcessObserver(IProcessObserver observer) {
12446        synchronized (this) {
12447            mProcessObservers.unregister(observer);
12448        }
12449    }
12450
12451    @Override
12452    public void registerUidObserver(IUidObserver observer, int which) {
12453        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12454                "registerUidObserver()");
12455        synchronized (this) {
12456            mUidObservers.register(observer, which);
12457        }
12458    }
12459
12460    @Override
12461    public void unregisterUidObserver(IUidObserver observer) {
12462        synchronized (this) {
12463            mUidObservers.unregister(observer);
12464        }
12465    }
12466
12467    @Override
12468    public boolean convertFromTranslucent(IBinder token) {
12469        final long origId = Binder.clearCallingIdentity();
12470        try {
12471            synchronized (this) {
12472                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12473                if (r == null) {
12474                    return false;
12475                }
12476                final boolean translucentChanged = r.changeWindowTranslucency(true);
12477                if (translucentChanged) {
12478                    r.task.stack.releaseBackgroundResources(r);
12479                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12480                }
12481                mWindowManager.setAppFullscreen(token, true);
12482                return translucentChanged;
12483            }
12484        } finally {
12485            Binder.restoreCallingIdentity(origId);
12486        }
12487    }
12488
12489    @Override
12490    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12491        final long origId = Binder.clearCallingIdentity();
12492        try {
12493            synchronized (this) {
12494                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12495                if (r == null) {
12496                    return false;
12497                }
12498                int index = r.task.mActivities.lastIndexOf(r);
12499                if (index > 0) {
12500                    ActivityRecord under = r.task.mActivities.get(index - 1);
12501                    under.returningOptions = options;
12502                }
12503                final boolean translucentChanged = r.changeWindowTranslucency(false);
12504                if (translucentChanged) {
12505                    r.task.stack.convertActivityToTranslucent(r);
12506                }
12507                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12508                mWindowManager.setAppFullscreen(token, false);
12509                return translucentChanged;
12510            }
12511        } finally {
12512            Binder.restoreCallingIdentity(origId);
12513        }
12514    }
12515
12516    @Override
12517    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12518        final long origId = Binder.clearCallingIdentity();
12519        try {
12520            synchronized (this) {
12521                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12522                if (r != null) {
12523                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12524                }
12525            }
12526            return false;
12527        } finally {
12528            Binder.restoreCallingIdentity(origId);
12529        }
12530    }
12531
12532    @Override
12533    public boolean isBackgroundVisibleBehind(IBinder token) {
12534        final long origId = Binder.clearCallingIdentity();
12535        try {
12536            synchronized (this) {
12537                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12538                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12539                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12540                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12541                return visible;
12542            }
12543        } finally {
12544            Binder.restoreCallingIdentity(origId);
12545        }
12546    }
12547
12548    @Override
12549    public ActivityOptions getActivityOptions(IBinder token) {
12550        final long origId = Binder.clearCallingIdentity();
12551        try {
12552            synchronized (this) {
12553                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12554                if (r != null) {
12555                    final ActivityOptions activityOptions = r.pendingOptions;
12556                    r.pendingOptions = null;
12557                    return activityOptions;
12558                }
12559                return null;
12560            }
12561        } finally {
12562            Binder.restoreCallingIdentity(origId);
12563        }
12564    }
12565
12566    @Override
12567    public void setImmersive(IBinder token, boolean immersive) {
12568        synchronized(this) {
12569            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12570            if (r == null) {
12571                throw new IllegalArgumentException();
12572            }
12573            r.immersive = immersive;
12574
12575            // update associated state if we're frontmost
12576            if (r == mFocusedActivity) {
12577                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12578                applyUpdateLockStateLocked(r);
12579            }
12580        }
12581    }
12582
12583    @Override
12584    public boolean isImmersive(IBinder token) {
12585        synchronized (this) {
12586            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12587            if (r == null) {
12588                throw new IllegalArgumentException();
12589            }
12590            return r.immersive;
12591        }
12592    }
12593
12594    public void setVrThread(int tid) {
12595        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12596            throw new UnsupportedOperationException("VR mode not supported on this device!");
12597        }
12598
12599        synchronized (this) {
12600            ProcessRecord proc;
12601            synchronized (mPidsSelfLocked) {
12602                final int pid = Binder.getCallingPid();
12603                proc = mPidsSelfLocked.get(pid);
12604
12605                if (proc != null && mInVrMode && tid >= 0) {
12606                    // ensure the tid belongs to the process
12607                    if (!Process.isThreadInProcess(pid, tid)) {
12608                        throw new IllegalArgumentException("VR thread does not belong to process");
12609                    }
12610
12611                    // reset existing VR thread to CFS if this thread still exists and belongs to
12612                    // the calling process
12613                    if (proc.vrThreadTid != 0
12614                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12615                        try {
12616                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12617                        } catch (IllegalArgumentException e) {
12618                            // Ignore this.  Only occurs in race condition where previous VR thread
12619                            // was destroyed during this method call.
12620                        }
12621                    }
12622
12623                    proc.vrThreadTid = tid;
12624
12625                    // promote to FIFO now if the tid is non-zero
12626                    try {
12627                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12628                            proc.vrThreadTid > 0) {
12629                            Process.setThreadScheduler(proc.vrThreadTid,
12630                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12631                        }
12632                    } catch (IllegalArgumentException e) {
12633                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12634                               + " not exist:\n" + e);
12635                    }
12636                }
12637            }
12638        }
12639    }
12640
12641    @Override
12642    public void setRenderThread(int tid) {
12643        synchronized (this) {
12644            ProcessRecord proc;
12645            synchronized (mPidsSelfLocked) {
12646                int pid = Binder.getCallingPid();
12647                proc = mPidsSelfLocked.get(pid);
12648                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12649                    // ensure the tid belongs to the process
12650                    if (!Process.isThreadInProcess(pid, tid)) {
12651                        throw new IllegalArgumentException(
12652                            "Render thread does not belong to process");
12653                    }
12654                    proc.renderThreadTid = tid;
12655                    if (DEBUG_OOM_ADJ) {
12656                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12657                    }
12658                    // promote to FIFO now
12659                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12660                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12661                        if (mUseFifoUiScheduling) {
12662                            Process.setThreadScheduler(proc.renderThreadTid,
12663                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12664                        } else {
12665                            Process.setThreadPriority(proc.renderThreadTid, -10);
12666                        }
12667                    }
12668                } else {
12669                    if (DEBUG_OOM_ADJ) {
12670                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12671                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12672                               mUseFifoUiScheduling);
12673                    }
12674                }
12675            }
12676        }
12677    }
12678
12679    @Override
12680    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12681        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12682            throw new UnsupportedOperationException("VR mode not supported on this device!");
12683        }
12684
12685        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12686
12687        ActivityRecord r;
12688        synchronized (this) {
12689            r = ActivityRecord.isInStackLocked(token);
12690        }
12691
12692        if (r == null) {
12693            throw new IllegalArgumentException();
12694        }
12695
12696        int err;
12697        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12698                VrManagerInternal.NO_ERROR) {
12699            return err;
12700        }
12701
12702        synchronized(this) {
12703            r.requestedVrComponent = (enabled) ? packageName : null;
12704
12705            // Update associated state if this activity is currently focused
12706            if (r == mFocusedActivity) {
12707                applyUpdateVrModeLocked(r);
12708            }
12709            return 0;
12710        }
12711    }
12712
12713    @Override
12714    public boolean isVrModePackageEnabled(ComponentName packageName) {
12715        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12716            throw new UnsupportedOperationException("VR mode not supported on this device!");
12717        }
12718
12719        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12720
12721        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12722                VrManagerInternal.NO_ERROR;
12723    }
12724
12725    public boolean isTopActivityImmersive() {
12726        enforceNotIsolatedCaller("startActivity");
12727        synchronized (this) {
12728            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12729            return (r != null) ? r.immersive : false;
12730        }
12731    }
12732
12733    @Override
12734    public boolean isTopOfTask(IBinder token) {
12735        synchronized (this) {
12736            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12737            if (r == null) {
12738                throw new IllegalArgumentException();
12739            }
12740            return r.task.getTopActivity() == r;
12741        }
12742    }
12743
12744    @Override
12745    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12746        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12747            String msg = "Permission Denial: setHasTopUi() from pid="
12748                    + Binder.getCallingPid()
12749                    + ", uid=" + Binder.getCallingUid()
12750                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12751            Slog.w(TAG, msg);
12752            throw new SecurityException(msg);
12753        }
12754        final int pid = Binder.getCallingPid();
12755        final long origId = Binder.clearCallingIdentity();
12756        try {
12757            synchronized (this) {
12758                boolean changed = false;
12759                ProcessRecord pr;
12760                synchronized (mPidsSelfLocked) {
12761                    pr = mPidsSelfLocked.get(pid);
12762                    if (pr == null) {
12763                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12764                        return;
12765                    }
12766                    if (pr.hasTopUi != hasTopUi) {
12767                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12768                        pr.hasTopUi = hasTopUi;
12769                        changed = true;
12770                    }
12771                }
12772                if (changed) {
12773                    updateOomAdjLocked(pr);
12774                }
12775            }
12776        } finally {
12777            Binder.restoreCallingIdentity(origId);
12778        }
12779    }
12780
12781    public final void enterSafeMode() {
12782        synchronized(this) {
12783            // It only makes sense to do this before the system is ready
12784            // and started launching other packages.
12785            if (!mSystemReady) {
12786                try {
12787                    AppGlobals.getPackageManager().enterSafeMode();
12788                } catch (RemoteException e) {
12789                }
12790            }
12791
12792            mSafeMode = true;
12793        }
12794    }
12795
12796    public final void showSafeModeOverlay() {
12797        View v = LayoutInflater.from(mContext).inflate(
12798                com.android.internal.R.layout.safe_mode, null);
12799        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12800        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12801        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12802        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12803        lp.gravity = Gravity.BOTTOM | Gravity.START;
12804        lp.format = v.getBackground().getOpacity();
12805        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12806                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12807        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12808        ((WindowManager)mContext.getSystemService(
12809                Context.WINDOW_SERVICE)).addView(v, lp);
12810    }
12811
12812    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12813        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12814            return;
12815        }
12816        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12817        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12818        synchronized (stats) {
12819            if (mBatteryStatsService.isOnBattery()) {
12820                mBatteryStatsService.enforceCallingPermission();
12821                int MY_UID = Binder.getCallingUid();
12822                final int uid;
12823                if (sender == null) {
12824                    uid = sourceUid;
12825                } else {
12826                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12827                }
12828                BatteryStatsImpl.Uid.Pkg pkg =
12829                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12830                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12831                pkg.noteWakeupAlarmLocked(tag);
12832            }
12833        }
12834    }
12835
12836    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12837        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12838            return;
12839        }
12840        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12841        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12842        synchronized (stats) {
12843            mBatteryStatsService.enforceCallingPermission();
12844            int MY_UID = Binder.getCallingUid();
12845            final int uid;
12846            if (sender == null) {
12847                uid = sourceUid;
12848            } else {
12849                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12850            }
12851            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12852        }
12853    }
12854
12855    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12856        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12857            return;
12858        }
12859        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12860        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12861        synchronized (stats) {
12862            mBatteryStatsService.enforceCallingPermission();
12863            int MY_UID = Binder.getCallingUid();
12864            final int uid;
12865            if (sender == null) {
12866                uid = sourceUid;
12867            } else {
12868                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12869            }
12870            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12871        }
12872    }
12873
12874    public boolean killPids(int[] pids, String pReason, boolean secure) {
12875        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12876            throw new SecurityException("killPids only available to the system");
12877        }
12878        String reason = (pReason == null) ? "Unknown" : pReason;
12879        // XXX Note: don't acquire main activity lock here, because the window
12880        // manager calls in with its locks held.
12881
12882        boolean killed = false;
12883        synchronized (mPidsSelfLocked) {
12884            int worstType = 0;
12885            for (int i=0; i<pids.length; i++) {
12886                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12887                if (proc != null) {
12888                    int type = proc.setAdj;
12889                    if (type > worstType) {
12890                        worstType = type;
12891                    }
12892                }
12893            }
12894
12895            // If the worst oom_adj is somewhere in the cached proc LRU range,
12896            // then constrain it so we will kill all cached procs.
12897            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12898                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12899                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12900            }
12901
12902            // If this is not a secure call, don't let it kill processes that
12903            // are important.
12904            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12905                worstType = ProcessList.SERVICE_ADJ;
12906            }
12907
12908            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12909            for (int i=0; i<pids.length; i++) {
12910                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12911                if (proc == null) {
12912                    continue;
12913                }
12914                int adj = proc.setAdj;
12915                if (adj >= worstType && !proc.killedByAm) {
12916                    proc.kill(reason, true);
12917                    killed = true;
12918                }
12919            }
12920        }
12921        return killed;
12922    }
12923
12924    @Override
12925    public void killUid(int appId, int userId, String reason) {
12926        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12927        synchronized (this) {
12928            final long identity = Binder.clearCallingIdentity();
12929            try {
12930                killPackageProcessesLocked(null, appId, userId,
12931                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12932                        reason != null ? reason : "kill uid");
12933            } finally {
12934                Binder.restoreCallingIdentity(identity);
12935            }
12936        }
12937    }
12938
12939    @Override
12940    public boolean killProcessesBelowForeground(String reason) {
12941        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12942            throw new SecurityException("killProcessesBelowForeground() only available to system");
12943        }
12944
12945        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12946    }
12947
12948    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12949        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12950            throw new SecurityException("killProcessesBelowAdj() only available to system");
12951        }
12952
12953        boolean killed = false;
12954        synchronized (mPidsSelfLocked) {
12955            final int size = mPidsSelfLocked.size();
12956            for (int i = 0; i < size; i++) {
12957                final int pid = mPidsSelfLocked.keyAt(i);
12958                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12959                if (proc == null) continue;
12960
12961                final int adj = proc.setAdj;
12962                if (adj > belowAdj && !proc.killedByAm) {
12963                    proc.kill(reason, true);
12964                    killed = true;
12965                }
12966            }
12967        }
12968        return killed;
12969    }
12970
12971    @Override
12972    public void hang(final IBinder who, boolean allowRestart) {
12973        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12974                != PackageManager.PERMISSION_GRANTED) {
12975            throw new SecurityException("Requires permission "
12976                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12977        }
12978
12979        final IBinder.DeathRecipient death = new DeathRecipient() {
12980            @Override
12981            public void binderDied() {
12982                synchronized (this) {
12983                    notifyAll();
12984                }
12985            }
12986        };
12987
12988        try {
12989            who.linkToDeath(death, 0);
12990        } catch (RemoteException e) {
12991            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12992            return;
12993        }
12994
12995        synchronized (this) {
12996            Watchdog.getInstance().setAllowRestart(allowRestart);
12997            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12998            synchronized (death) {
12999                while (who.isBinderAlive()) {
13000                    try {
13001                        death.wait();
13002                    } catch (InterruptedException e) {
13003                    }
13004                }
13005            }
13006            Watchdog.getInstance().setAllowRestart(true);
13007        }
13008    }
13009
13010    @Override
13011    public void restart() {
13012        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13013                != PackageManager.PERMISSION_GRANTED) {
13014            throw new SecurityException("Requires permission "
13015                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13016        }
13017
13018        Log.i(TAG, "Sending shutdown broadcast...");
13019
13020        BroadcastReceiver br = new BroadcastReceiver() {
13021            @Override public void onReceive(Context context, Intent intent) {
13022                // Now the broadcast is done, finish up the low-level shutdown.
13023                Log.i(TAG, "Shutting down activity manager...");
13024                shutdown(10000);
13025                Log.i(TAG, "Shutdown complete, restarting!");
13026                Process.killProcess(Process.myPid());
13027                System.exit(10);
13028            }
13029        };
13030
13031        // First send the high-level shut down broadcast.
13032        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13033        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13034        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13035        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13036        mContext.sendOrderedBroadcastAsUser(intent,
13037                UserHandle.ALL, null, br, mHandler, 0, null, null);
13038        */
13039        br.onReceive(mContext, intent);
13040    }
13041
13042    private long getLowRamTimeSinceIdle(long now) {
13043        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13044    }
13045
13046    @Override
13047    public void performIdleMaintenance() {
13048        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13049                != PackageManager.PERMISSION_GRANTED) {
13050            throw new SecurityException("Requires permission "
13051                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13052        }
13053
13054        synchronized (this) {
13055            final long now = SystemClock.uptimeMillis();
13056            final long timeSinceLastIdle = now - mLastIdleTime;
13057            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13058            mLastIdleTime = now;
13059            mLowRamTimeSinceLastIdle = 0;
13060            if (mLowRamStartTime != 0) {
13061                mLowRamStartTime = now;
13062            }
13063
13064            StringBuilder sb = new StringBuilder(128);
13065            sb.append("Idle maintenance over ");
13066            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13067            sb.append(" low RAM for ");
13068            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13069            Slog.i(TAG, sb.toString());
13070
13071            // If at least 1/3 of our time since the last idle period has been spent
13072            // with RAM low, then we want to kill processes.
13073            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13074
13075            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13076                ProcessRecord proc = mLruProcesses.get(i);
13077                if (proc.notCachedSinceIdle) {
13078                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13079                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13080                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13081                        if (doKilling && proc.initialIdlePss != 0
13082                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13083                            sb = new StringBuilder(128);
13084                            sb.append("Kill");
13085                            sb.append(proc.processName);
13086                            sb.append(" in idle maint: pss=");
13087                            sb.append(proc.lastPss);
13088                            sb.append(", swapPss=");
13089                            sb.append(proc.lastSwapPss);
13090                            sb.append(", initialPss=");
13091                            sb.append(proc.initialIdlePss);
13092                            sb.append(", period=");
13093                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13094                            sb.append(", lowRamPeriod=");
13095                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13096                            Slog.wtfQuiet(TAG, sb.toString());
13097                            proc.kill("idle maint (pss " + proc.lastPss
13098                                    + " from " + proc.initialIdlePss + ")", true);
13099                        }
13100                    }
13101                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13102                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13103                    proc.notCachedSinceIdle = true;
13104                    proc.initialIdlePss = 0;
13105                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13106                            mTestPssMode, isSleepingLocked(), now);
13107                }
13108            }
13109
13110            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13111            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13112        }
13113    }
13114
13115    @Override
13116    public void sendIdleJobTrigger() {
13117        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13118                != PackageManager.PERMISSION_GRANTED) {
13119            throw new SecurityException("Requires permission "
13120                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13121        }
13122
13123        final long ident = Binder.clearCallingIdentity();
13124        try {
13125            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13126                    .setPackage("android")
13127                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13128            broadcastIntent(null, intent, null, null, 0, null, null, null,
13129                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13130        } finally {
13131            Binder.restoreCallingIdentity(ident);
13132        }
13133    }
13134
13135    private void retrieveSettings() {
13136        final ContentResolver resolver = mContext.getContentResolver();
13137        final boolean freeformWindowManagement =
13138                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13139                        || Settings.Global.getInt(
13140                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13141        final boolean supportsPictureInPicture =
13142                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13143
13144        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13145        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13146        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13147        final boolean alwaysFinishActivities =
13148                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13149        final boolean lenientBackgroundCheck =
13150                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13151        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13152        final boolean forceResizable = Settings.Global.getInt(
13153                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13154        final boolean supportsLeanbackOnly =
13155                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13156
13157        // Transfer any global setting for forcing RTL layout, into a System Property
13158        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13159
13160        final Configuration configuration = new Configuration();
13161        Settings.System.getConfiguration(resolver, configuration);
13162        if (forceRtl) {
13163            // This will take care of setting the correct layout direction flags
13164            configuration.setLayoutDirection(configuration.locale);
13165        }
13166
13167        synchronized (this) {
13168            mDebugApp = mOrigDebugApp = debugApp;
13169            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13170            mAlwaysFinishActivities = alwaysFinishActivities;
13171            mLenientBackgroundCheck = lenientBackgroundCheck;
13172            mSupportsLeanbackOnly = supportsLeanbackOnly;
13173            mForceResizableActivities = forceResizable;
13174            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13175            if (supportsMultiWindow || forceResizable) {
13176                mSupportsMultiWindow = true;
13177                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13178                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13179            } else {
13180                mSupportsMultiWindow = false;
13181                mSupportsFreeformWindowManagement = false;
13182                mSupportsPictureInPicture = false;
13183            }
13184            // This happens before any activities are started, so we can
13185            // change mConfiguration in-place.
13186            updateConfigurationLocked(configuration, null, true);
13187            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13188                    "Initial config: " + mConfiguration);
13189
13190            // Load resources only after the current configuration has been set.
13191            final Resources res = mContext.getResources();
13192            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13193            mThumbnailWidth = res.getDimensionPixelSize(
13194                    com.android.internal.R.dimen.thumbnail_width);
13195            mThumbnailHeight = res.getDimensionPixelSize(
13196                    com.android.internal.R.dimen.thumbnail_height);
13197            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13198                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13199            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13200                    com.android.internal.R.string.config_appsNotReportingCrashes));
13201            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13202                mFullscreenThumbnailScale = (float) res
13203                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13204                    (float) mConfiguration.screenWidthDp;
13205            } else {
13206                mFullscreenThumbnailScale = res.getFraction(
13207                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13208            }
13209        }
13210    }
13211
13212    public boolean testIsSystemReady() {
13213        // no need to synchronize(this) just to read & return the value
13214        return mSystemReady;
13215    }
13216
13217    public void systemReady(final Runnable goingCallback) {
13218        synchronized(this) {
13219            if (mSystemReady) {
13220                // If we're done calling all the receivers, run the next "boot phase" passed in
13221                // by the SystemServer
13222                if (goingCallback != null) {
13223                    goingCallback.run();
13224                }
13225                return;
13226            }
13227
13228            mLocalDeviceIdleController
13229                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13230
13231            // Make sure we have the current profile info, since it is needed for security checks.
13232            mUserController.onSystemReady();
13233            mRecentTasks.onSystemReadyLocked();
13234            mAppOpsService.systemReady();
13235            mSystemReady = true;
13236        }
13237
13238        ArrayList<ProcessRecord> procsToKill = null;
13239        synchronized(mPidsSelfLocked) {
13240            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13241                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13242                if (!isAllowedWhileBooting(proc.info)){
13243                    if (procsToKill == null) {
13244                        procsToKill = new ArrayList<ProcessRecord>();
13245                    }
13246                    procsToKill.add(proc);
13247                }
13248            }
13249        }
13250
13251        synchronized(this) {
13252            if (procsToKill != null) {
13253                for (int i=procsToKill.size()-1; i>=0; i--) {
13254                    ProcessRecord proc = procsToKill.get(i);
13255                    Slog.i(TAG, "Removing system update proc: " + proc);
13256                    removeProcessLocked(proc, true, false, "system update done");
13257                }
13258            }
13259
13260            // Now that we have cleaned up any update processes, we
13261            // are ready to start launching real processes and know that
13262            // we won't trample on them any more.
13263            mProcessesReady = true;
13264        }
13265
13266        Slog.i(TAG, "System now ready");
13267        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13268            SystemClock.uptimeMillis());
13269
13270        synchronized(this) {
13271            // Make sure we have no pre-ready processes sitting around.
13272
13273            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13274                ResolveInfo ri = mContext.getPackageManager()
13275                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13276                                STOCK_PM_FLAGS);
13277                CharSequence errorMsg = null;
13278                if (ri != null) {
13279                    ActivityInfo ai = ri.activityInfo;
13280                    ApplicationInfo app = ai.applicationInfo;
13281                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13282                        mTopAction = Intent.ACTION_FACTORY_TEST;
13283                        mTopData = null;
13284                        mTopComponent = new ComponentName(app.packageName,
13285                                ai.name);
13286                    } else {
13287                        errorMsg = mContext.getResources().getText(
13288                                com.android.internal.R.string.factorytest_not_system);
13289                    }
13290                } else {
13291                    errorMsg = mContext.getResources().getText(
13292                            com.android.internal.R.string.factorytest_no_action);
13293                }
13294                if (errorMsg != null) {
13295                    mTopAction = null;
13296                    mTopData = null;
13297                    mTopComponent = null;
13298                    Message msg = Message.obtain();
13299                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13300                    msg.getData().putCharSequence("msg", errorMsg);
13301                    mUiHandler.sendMessage(msg);
13302                }
13303            }
13304        }
13305
13306        retrieveSettings();
13307        final int currentUserId;
13308        synchronized (this) {
13309            currentUserId = mUserController.getCurrentUserIdLocked();
13310            readGrantedUriPermissionsLocked();
13311        }
13312
13313        if (goingCallback != null) goingCallback.run();
13314
13315        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13316                Integer.toString(currentUserId), currentUserId);
13317        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13318                Integer.toString(currentUserId), currentUserId);
13319        mSystemServiceManager.startUser(currentUserId);
13320
13321        synchronized (this) {
13322            // Only start up encryption-aware persistent apps; once user is
13323            // unlocked we'll come back around and start unaware apps
13324            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13325
13326            // Start up initial activity.
13327            mBooting = true;
13328            // Enable home activity for system user, so that the system can always boot
13329            if (UserManager.isSplitSystemUser()) {
13330                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13331                try {
13332                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13333                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13334                            UserHandle.USER_SYSTEM);
13335                } catch (RemoteException e) {
13336                    throw e.rethrowAsRuntimeException();
13337                }
13338            }
13339            startHomeActivityLocked(currentUserId, "systemReady");
13340
13341            try {
13342                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13343                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13344                            + " data partition or your device will be unstable.");
13345                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13346                }
13347            } catch (RemoteException e) {
13348            }
13349
13350            if (!Build.isBuildConsistent()) {
13351                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13352                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13353            }
13354
13355            long ident = Binder.clearCallingIdentity();
13356            try {
13357                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13358                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13359                        | Intent.FLAG_RECEIVER_FOREGROUND);
13360                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13361                broadcastIntentLocked(null, null, intent,
13362                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13363                        null, false, false, MY_PID, Process.SYSTEM_UID,
13364                        currentUserId);
13365                intent = new Intent(Intent.ACTION_USER_STARTING);
13366                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13367                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13368                broadcastIntentLocked(null, null, intent,
13369                        null, new IIntentReceiver.Stub() {
13370                            @Override
13371                            public void performReceive(Intent intent, int resultCode, String data,
13372                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13373                                    throws RemoteException {
13374                            }
13375                        }, 0, null, null,
13376                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13377                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13378            } catch (Throwable t) {
13379                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13380            } finally {
13381                Binder.restoreCallingIdentity(ident);
13382            }
13383            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13384            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13385        }
13386    }
13387
13388    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13389        synchronized (this) {
13390            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13391        }
13392    }
13393
13394    void skipCurrentReceiverLocked(ProcessRecord app) {
13395        for (BroadcastQueue queue : mBroadcastQueues) {
13396            queue.skipCurrentReceiverLocked(app);
13397        }
13398    }
13399
13400    /**
13401     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13402     * The application process will exit immediately after this call returns.
13403     * @param app object of the crashing app, null for the system server
13404     * @param crashInfo describing the exception
13405     */
13406    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13407        ProcessRecord r = findAppProcess(app, "Crash");
13408        final String processName = app == null ? "system_server"
13409                : (r == null ? "unknown" : r.processName);
13410
13411        handleApplicationCrashInner("crash", r, processName, crashInfo);
13412    }
13413
13414    /* Native crash reporting uses this inner version because it needs to be somewhat
13415     * decoupled from the AM-managed cleanup lifecycle
13416     */
13417    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13418            ApplicationErrorReport.CrashInfo crashInfo) {
13419        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13420                UserHandle.getUserId(Binder.getCallingUid()), processName,
13421                r == null ? -1 : r.info.flags,
13422                crashInfo.exceptionClassName,
13423                crashInfo.exceptionMessage,
13424                crashInfo.throwFileName,
13425                crashInfo.throwLineNumber);
13426
13427        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13428
13429        mAppErrors.crashApplication(r, crashInfo);
13430    }
13431
13432    public void handleApplicationStrictModeViolation(
13433            IBinder app,
13434            int violationMask,
13435            StrictMode.ViolationInfo info) {
13436        ProcessRecord r = findAppProcess(app, "StrictMode");
13437        if (r == null) {
13438            return;
13439        }
13440
13441        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13442            Integer stackFingerprint = info.hashCode();
13443            boolean logIt = true;
13444            synchronized (mAlreadyLoggedViolatedStacks) {
13445                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13446                    logIt = false;
13447                    // TODO: sub-sample into EventLog for these, with
13448                    // the info.durationMillis?  Then we'd get
13449                    // the relative pain numbers, without logging all
13450                    // the stack traces repeatedly.  We'd want to do
13451                    // likewise in the client code, which also does
13452                    // dup suppression, before the Binder call.
13453                } else {
13454                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13455                        mAlreadyLoggedViolatedStacks.clear();
13456                    }
13457                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13458                }
13459            }
13460            if (logIt) {
13461                logStrictModeViolationToDropBox(r, info);
13462            }
13463        }
13464
13465        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13466            AppErrorResult result = new AppErrorResult();
13467            synchronized (this) {
13468                final long origId = Binder.clearCallingIdentity();
13469
13470                Message msg = Message.obtain();
13471                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13472                HashMap<String, Object> data = new HashMap<String, Object>();
13473                data.put("result", result);
13474                data.put("app", r);
13475                data.put("violationMask", violationMask);
13476                data.put("info", info);
13477                msg.obj = data;
13478                mUiHandler.sendMessage(msg);
13479
13480                Binder.restoreCallingIdentity(origId);
13481            }
13482            int res = result.get();
13483            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13484        }
13485    }
13486
13487    // Depending on the policy in effect, there could be a bunch of
13488    // these in quick succession so we try to batch these together to
13489    // minimize disk writes, number of dropbox entries, and maximize
13490    // compression, by having more fewer, larger records.
13491    private void logStrictModeViolationToDropBox(
13492            ProcessRecord process,
13493            StrictMode.ViolationInfo info) {
13494        if (info == null) {
13495            return;
13496        }
13497        final boolean isSystemApp = process == null ||
13498                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13499                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13500        final String processName = process == null ? "unknown" : process.processName;
13501        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13502        final DropBoxManager dbox = (DropBoxManager)
13503                mContext.getSystemService(Context.DROPBOX_SERVICE);
13504
13505        // Exit early if the dropbox isn't configured to accept this report type.
13506        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13507
13508        boolean bufferWasEmpty;
13509        boolean needsFlush;
13510        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13511        synchronized (sb) {
13512            bufferWasEmpty = sb.length() == 0;
13513            appendDropBoxProcessHeaders(process, processName, sb);
13514            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13515            sb.append("System-App: ").append(isSystemApp).append("\n");
13516            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13517            if (info.violationNumThisLoop != 0) {
13518                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13519            }
13520            if (info.numAnimationsRunning != 0) {
13521                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13522            }
13523            if (info.broadcastIntentAction != null) {
13524                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13525            }
13526            if (info.durationMillis != -1) {
13527                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13528            }
13529            if (info.numInstances != -1) {
13530                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13531            }
13532            if (info.tags != null) {
13533                for (String tag : info.tags) {
13534                    sb.append("Span-Tag: ").append(tag).append("\n");
13535                }
13536            }
13537            sb.append("\n");
13538            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13539                sb.append(info.crashInfo.stackTrace);
13540                sb.append("\n");
13541            }
13542            if (info.message != null) {
13543                sb.append(info.message);
13544                sb.append("\n");
13545            }
13546
13547            // Only buffer up to ~64k.  Various logging bits truncate
13548            // things at 128k.
13549            needsFlush = (sb.length() > 64 * 1024);
13550        }
13551
13552        // Flush immediately if the buffer's grown too large, or this
13553        // is a non-system app.  Non-system apps are isolated with a
13554        // different tag & policy and not batched.
13555        //
13556        // Batching is useful during internal testing with
13557        // StrictMode settings turned up high.  Without batching,
13558        // thousands of separate files could be created on boot.
13559        if (!isSystemApp || needsFlush) {
13560            new Thread("Error dump: " + dropboxTag) {
13561                @Override
13562                public void run() {
13563                    String report;
13564                    synchronized (sb) {
13565                        report = sb.toString();
13566                        sb.delete(0, sb.length());
13567                        sb.trimToSize();
13568                    }
13569                    if (report.length() != 0) {
13570                        dbox.addText(dropboxTag, report);
13571                    }
13572                }
13573            }.start();
13574            return;
13575        }
13576
13577        // System app batching:
13578        if (!bufferWasEmpty) {
13579            // An existing dropbox-writing thread is outstanding, so
13580            // we don't need to start it up.  The existing thread will
13581            // catch the buffer appends we just did.
13582            return;
13583        }
13584
13585        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13586        // (After this point, we shouldn't access AMS internal data structures.)
13587        new Thread("Error dump: " + dropboxTag) {
13588            @Override
13589            public void run() {
13590                // 5 second sleep to let stacks arrive and be batched together
13591                try {
13592                    Thread.sleep(5000);  // 5 seconds
13593                } catch (InterruptedException e) {}
13594
13595                String errorReport;
13596                synchronized (mStrictModeBuffer) {
13597                    errorReport = mStrictModeBuffer.toString();
13598                    if (errorReport.length() == 0) {
13599                        return;
13600                    }
13601                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13602                    mStrictModeBuffer.trimToSize();
13603                }
13604                dbox.addText(dropboxTag, errorReport);
13605            }
13606        }.start();
13607    }
13608
13609    /**
13610     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13611     * @param app object of the crashing app, null for the system server
13612     * @param tag reported by the caller
13613     * @param system whether this wtf is coming from the system
13614     * @param crashInfo describing the context of the error
13615     * @return true if the process should exit immediately (WTF is fatal)
13616     */
13617    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13618            final ApplicationErrorReport.CrashInfo crashInfo) {
13619        final int callingUid = Binder.getCallingUid();
13620        final int callingPid = Binder.getCallingPid();
13621
13622        if (system) {
13623            // If this is coming from the system, we could very well have low-level
13624            // system locks held, so we want to do this all asynchronously.  And we
13625            // never want this to become fatal, so there is that too.
13626            mHandler.post(new Runnable() {
13627                @Override public void run() {
13628                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13629                }
13630            });
13631            return false;
13632        }
13633
13634        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13635                crashInfo);
13636
13637        if (r != null && r.pid != Process.myPid() &&
13638                Settings.Global.getInt(mContext.getContentResolver(),
13639                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13640            mAppErrors.crashApplication(r, crashInfo);
13641            return true;
13642        } else {
13643            return false;
13644        }
13645    }
13646
13647    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13648            final ApplicationErrorReport.CrashInfo crashInfo) {
13649        final ProcessRecord r = findAppProcess(app, "WTF");
13650        final String processName = app == null ? "system_server"
13651                : (r == null ? "unknown" : r.processName);
13652
13653        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13654                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13655
13656        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13657
13658        return r;
13659    }
13660
13661    /**
13662     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13663     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13664     */
13665    private ProcessRecord findAppProcess(IBinder app, String reason) {
13666        if (app == null) {
13667            return null;
13668        }
13669
13670        synchronized (this) {
13671            final int NP = mProcessNames.getMap().size();
13672            for (int ip=0; ip<NP; ip++) {
13673                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13674                final int NA = apps.size();
13675                for (int ia=0; ia<NA; ia++) {
13676                    ProcessRecord p = apps.valueAt(ia);
13677                    if (p.thread != null && p.thread.asBinder() == app) {
13678                        return p;
13679                    }
13680                }
13681            }
13682
13683            Slog.w(TAG, "Can't find mystery application for " + reason
13684                    + " from pid=" + Binder.getCallingPid()
13685                    + " uid=" + Binder.getCallingUid() + ": " + app);
13686            return null;
13687        }
13688    }
13689
13690    /**
13691     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13692     * to append various headers to the dropbox log text.
13693     */
13694    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13695            StringBuilder sb) {
13696        // Watchdog thread ends up invoking this function (with
13697        // a null ProcessRecord) to add the stack file to dropbox.
13698        // Do not acquire a lock on this (am) in such cases, as it
13699        // could cause a potential deadlock, if and when watchdog
13700        // is invoked due to unavailability of lock on am and it
13701        // would prevent watchdog from killing system_server.
13702        if (process == null) {
13703            sb.append("Process: ").append(processName).append("\n");
13704            return;
13705        }
13706        // Note: ProcessRecord 'process' is guarded by the service
13707        // instance.  (notably process.pkgList, which could otherwise change
13708        // concurrently during execution of this method)
13709        synchronized (this) {
13710            sb.append("Process: ").append(processName).append("\n");
13711            int flags = process.info.flags;
13712            IPackageManager pm = AppGlobals.getPackageManager();
13713            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13714            for (int ip=0; ip<process.pkgList.size(); ip++) {
13715                String pkg = process.pkgList.keyAt(ip);
13716                sb.append("Package: ").append(pkg);
13717                try {
13718                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13719                    if (pi != null) {
13720                        sb.append(" v").append(pi.versionCode);
13721                        if (pi.versionName != null) {
13722                            sb.append(" (").append(pi.versionName).append(")");
13723                        }
13724                    }
13725                } catch (RemoteException e) {
13726                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13727                }
13728                sb.append("\n");
13729            }
13730        }
13731    }
13732
13733    private static String processClass(ProcessRecord process) {
13734        if (process == null || process.pid == MY_PID) {
13735            return "system_server";
13736        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13737            return "system_app";
13738        } else {
13739            return "data_app";
13740        }
13741    }
13742
13743    private volatile long mWtfClusterStart;
13744    private volatile int mWtfClusterCount;
13745
13746    /**
13747     * Write a description of an error (crash, WTF, ANR) to the drop box.
13748     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13749     * @param process which caused the error, null means the system server
13750     * @param activity which triggered the error, null if unknown
13751     * @param parent activity related to the error, null if unknown
13752     * @param subject line related to the error, null if absent
13753     * @param report in long form describing the error, null if absent
13754     * @param dataFile text file to include in the report, null if none
13755     * @param crashInfo giving an application stack trace, null if absent
13756     */
13757    public void addErrorToDropBox(String eventType,
13758            ProcessRecord process, String processName, ActivityRecord activity,
13759            ActivityRecord parent, String subject,
13760            final String report, final File dataFile,
13761            final ApplicationErrorReport.CrashInfo crashInfo) {
13762        // NOTE -- this must never acquire the ActivityManagerService lock,
13763        // otherwise the watchdog may be prevented from resetting the system.
13764
13765        final String dropboxTag = processClass(process) + "_" + eventType;
13766        final DropBoxManager dbox = (DropBoxManager)
13767                mContext.getSystemService(Context.DROPBOX_SERVICE);
13768
13769        // Exit early if the dropbox isn't configured to accept this report type.
13770        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13771
13772        // Rate-limit how often we're willing to do the heavy lifting below to
13773        // collect and record logs; currently 5 logs per 10 second period.
13774        final long now = SystemClock.elapsedRealtime();
13775        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13776            mWtfClusterStart = now;
13777            mWtfClusterCount = 1;
13778        } else {
13779            if (mWtfClusterCount++ >= 5) return;
13780        }
13781
13782        final StringBuilder sb = new StringBuilder(1024);
13783        appendDropBoxProcessHeaders(process, processName, sb);
13784        if (process != null) {
13785            sb.append("Foreground: ")
13786                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13787                    .append("\n");
13788        }
13789        if (activity != null) {
13790            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13791        }
13792        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13793            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13794        }
13795        if (parent != null && parent != activity) {
13796            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13797        }
13798        if (subject != null) {
13799            sb.append("Subject: ").append(subject).append("\n");
13800        }
13801        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13802        if (Debug.isDebuggerConnected()) {
13803            sb.append("Debugger: Connected\n");
13804        }
13805        sb.append("\n");
13806
13807        // Do the rest in a worker thread to avoid blocking the caller on I/O
13808        // (After this point, we shouldn't access AMS internal data structures.)
13809        Thread worker = new Thread("Error dump: " + dropboxTag) {
13810            @Override
13811            public void run() {
13812                if (report != null) {
13813                    sb.append(report);
13814                }
13815
13816                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13817                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13818                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13819                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13820
13821                if (dataFile != null && maxDataFileSize > 0) {
13822                    try {
13823                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13824                                    "\n\n[[TRUNCATED]]"));
13825                    } catch (IOException e) {
13826                        Slog.e(TAG, "Error reading " + dataFile, e);
13827                    }
13828                }
13829                if (crashInfo != null && crashInfo.stackTrace != null) {
13830                    sb.append(crashInfo.stackTrace);
13831                }
13832
13833                if (lines > 0) {
13834                    sb.append("\n");
13835
13836                    // Merge several logcat streams, and take the last N lines
13837                    InputStreamReader input = null;
13838                    try {
13839                        java.lang.Process logcat = new ProcessBuilder(
13840                                "/system/bin/timeout", "-k", "15s", "10s",
13841                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13842                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13843                                        .redirectErrorStream(true).start();
13844
13845                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13846                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13847                        input = new InputStreamReader(logcat.getInputStream());
13848
13849                        int num;
13850                        char[] buf = new char[8192];
13851                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13852                    } catch (IOException e) {
13853                        Slog.e(TAG, "Error running logcat", e);
13854                    } finally {
13855                        if (input != null) try { input.close(); } catch (IOException e) {}
13856                    }
13857                }
13858
13859                dbox.addText(dropboxTag, sb.toString());
13860            }
13861        };
13862
13863        if (process == null) {
13864            // If process is null, we are being called from some internal code
13865            // and may be about to die -- run this synchronously.
13866            worker.run();
13867        } else {
13868            worker.start();
13869        }
13870    }
13871
13872    @Override
13873    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13874        enforceNotIsolatedCaller("getProcessesInErrorState");
13875        // assume our apps are happy - lazy create the list
13876        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13877
13878        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13879                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13880        int userId = UserHandle.getUserId(Binder.getCallingUid());
13881
13882        synchronized (this) {
13883
13884            // iterate across all processes
13885            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13886                ProcessRecord app = mLruProcesses.get(i);
13887                if (!allUsers && app.userId != userId) {
13888                    continue;
13889                }
13890                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13891                    // This one's in trouble, so we'll generate a report for it
13892                    // crashes are higher priority (in case there's a crash *and* an anr)
13893                    ActivityManager.ProcessErrorStateInfo report = null;
13894                    if (app.crashing) {
13895                        report = app.crashingReport;
13896                    } else if (app.notResponding) {
13897                        report = app.notRespondingReport;
13898                    }
13899
13900                    if (report != null) {
13901                        if (errList == null) {
13902                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13903                        }
13904                        errList.add(report);
13905                    } else {
13906                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13907                                " crashing = " + app.crashing +
13908                                " notResponding = " + app.notResponding);
13909                    }
13910                }
13911            }
13912        }
13913
13914        return errList;
13915    }
13916
13917    static int procStateToImportance(int procState, int memAdj,
13918            ActivityManager.RunningAppProcessInfo currApp) {
13919        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13920        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13921            currApp.lru = memAdj;
13922        } else {
13923            currApp.lru = 0;
13924        }
13925        return imp;
13926    }
13927
13928    private void fillInProcMemInfo(ProcessRecord app,
13929            ActivityManager.RunningAppProcessInfo outInfo) {
13930        outInfo.pid = app.pid;
13931        outInfo.uid = app.info.uid;
13932        if (mHeavyWeightProcess == app) {
13933            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13934        }
13935        if (app.persistent) {
13936            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13937        }
13938        if (app.activities.size() > 0) {
13939            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13940        }
13941        outInfo.lastTrimLevel = app.trimMemoryLevel;
13942        int adj = app.curAdj;
13943        int procState = app.curProcState;
13944        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13945        outInfo.importanceReasonCode = app.adjTypeCode;
13946        outInfo.processState = app.curProcState;
13947    }
13948
13949    @Override
13950    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13951        enforceNotIsolatedCaller("getRunningAppProcesses");
13952
13953        final int callingUid = Binder.getCallingUid();
13954
13955        // Lazy instantiation of list
13956        List<ActivityManager.RunningAppProcessInfo> runList = null;
13957        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13958                callingUid) == PackageManager.PERMISSION_GRANTED;
13959        final int userId = UserHandle.getUserId(callingUid);
13960        final boolean allUids = isGetTasksAllowed(
13961                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13962
13963        synchronized (this) {
13964            // Iterate across all processes
13965            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13966                ProcessRecord app = mLruProcesses.get(i);
13967                if ((!allUsers && app.userId != userId)
13968                        || (!allUids && app.uid != callingUid)) {
13969                    continue;
13970                }
13971                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13972                    // Generate process state info for running application
13973                    ActivityManager.RunningAppProcessInfo currApp =
13974                        new ActivityManager.RunningAppProcessInfo(app.processName,
13975                                app.pid, app.getPackageList());
13976                    fillInProcMemInfo(app, currApp);
13977                    if (app.adjSource instanceof ProcessRecord) {
13978                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13979                        currApp.importanceReasonImportance =
13980                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13981                                        app.adjSourceProcState);
13982                    } else if (app.adjSource instanceof ActivityRecord) {
13983                        ActivityRecord r = (ActivityRecord)app.adjSource;
13984                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13985                    }
13986                    if (app.adjTarget instanceof ComponentName) {
13987                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13988                    }
13989                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13990                    //        + " lru=" + currApp.lru);
13991                    if (runList == null) {
13992                        runList = new ArrayList<>();
13993                    }
13994                    runList.add(currApp);
13995                }
13996            }
13997        }
13998        return runList;
13999    }
14000
14001    @Override
14002    public List<ApplicationInfo> getRunningExternalApplications() {
14003        enforceNotIsolatedCaller("getRunningExternalApplications");
14004        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14005        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14006        if (runningApps != null && runningApps.size() > 0) {
14007            Set<String> extList = new HashSet<String>();
14008            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14009                if (app.pkgList != null) {
14010                    for (String pkg : app.pkgList) {
14011                        extList.add(pkg);
14012                    }
14013                }
14014            }
14015            IPackageManager pm = AppGlobals.getPackageManager();
14016            for (String pkg : extList) {
14017                try {
14018                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14019                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14020                        retList.add(info);
14021                    }
14022                } catch (RemoteException e) {
14023                }
14024            }
14025        }
14026        return retList;
14027    }
14028
14029    @Override
14030    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14031        enforceNotIsolatedCaller("getMyMemoryState");
14032        synchronized (this) {
14033            ProcessRecord proc;
14034            synchronized (mPidsSelfLocked) {
14035                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14036            }
14037            fillInProcMemInfo(proc, outInfo);
14038        }
14039    }
14040
14041    @Override
14042    public int getMemoryTrimLevel() {
14043        enforceNotIsolatedCaller("getMyMemoryState");
14044        synchronized (this) {
14045            return mLastMemoryLevel;
14046        }
14047    }
14048
14049    @Override
14050    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14051            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14052        (new ActivityManagerShellCommand(this, false)).exec(
14053                this, in, out, err, args, resultReceiver);
14054    }
14055
14056    @Override
14057    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14058        if (checkCallingPermission(android.Manifest.permission.DUMP)
14059                != PackageManager.PERMISSION_GRANTED) {
14060            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14061                    + Binder.getCallingPid()
14062                    + ", uid=" + Binder.getCallingUid()
14063                    + " without permission "
14064                    + android.Manifest.permission.DUMP);
14065            return;
14066        }
14067
14068        boolean dumpAll = false;
14069        boolean dumpClient = false;
14070        boolean dumpCheckin = false;
14071        boolean dumpCheckinFormat = false;
14072        String dumpPackage = null;
14073
14074        int opti = 0;
14075        while (opti < args.length) {
14076            String opt = args[opti];
14077            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14078                break;
14079            }
14080            opti++;
14081            if ("-a".equals(opt)) {
14082                dumpAll = true;
14083            } else if ("-c".equals(opt)) {
14084                dumpClient = true;
14085            } else if ("-p".equals(opt)) {
14086                if (opti < args.length) {
14087                    dumpPackage = args[opti];
14088                    opti++;
14089                } else {
14090                    pw.println("Error: -p option requires package argument");
14091                    return;
14092                }
14093                dumpClient = true;
14094            } else if ("--checkin".equals(opt)) {
14095                dumpCheckin = dumpCheckinFormat = true;
14096            } else if ("-C".equals(opt)) {
14097                dumpCheckinFormat = true;
14098            } else if ("-h".equals(opt)) {
14099                ActivityManagerShellCommand.dumpHelp(pw, true);
14100                return;
14101            } else {
14102                pw.println("Unknown argument: " + opt + "; use -h for help");
14103            }
14104        }
14105
14106        long origId = Binder.clearCallingIdentity();
14107        boolean more = false;
14108        // Is the caller requesting to dump a particular piece of data?
14109        if (opti < args.length) {
14110            String cmd = args[opti];
14111            opti++;
14112            if ("activities".equals(cmd) || "a".equals(cmd)) {
14113                synchronized (this) {
14114                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14115                }
14116            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14117                synchronized (this) {
14118                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14119                }
14120            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14121                String[] newArgs;
14122                String name;
14123                if (opti >= args.length) {
14124                    name = null;
14125                    newArgs = EMPTY_STRING_ARRAY;
14126                } else {
14127                    dumpPackage = args[opti];
14128                    opti++;
14129                    newArgs = new String[args.length - opti];
14130                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14131                            args.length - opti);
14132                }
14133                synchronized (this) {
14134                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14135                }
14136            } else if ("broadcast-stats".equals(cmd)) {
14137                String[] newArgs;
14138                String name;
14139                if (opti >= args.length) {
14140                    name = null;
14141                    newArgs = EMPTY_STRING_ARRAY;
14142                } else {
14143                    dumpPackage = args[opti];
14144                    opti++;
14145                    newArgs = new String[args.length - opti];
14146                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14147                            args.length - opti);
14148                }
14149                synchronized (this) {
14150                    if (dumpCheckinFormat) {
14151                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14152                                dumpPackage);
14153                    } else {
14154                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14155                    }
14156                }
14157            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14158                String[] newArgs;
14159                String name;
14160                if (opti >= args.length) {
14161                    name = null;
14162                    newArgs = EMPTY_STRING_ARRAY;
14163                } else {
14164                    dumpPackage = args[opti];
14165                    opti++;
14166                    newArgs = new String[args.length - opti];
14167                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14168                            args.length - opti);
14169                }
14170                synchronized (this) {
14171                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14172                }
14173            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14174                String[] newArgs;
14175                String name;
14176                if (opti >= args.length) {
14177                    name = null;
14178                    newArgs = EMPTY_STRING_ARRAY;
14179                } else {
14180                    dumpPackage = args[opti];
14181                    opti++;
14182                    newArgs = new String[args.length - opti];
14183                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14184                            args.length - opti);
14185                }
14186                synchronized (this) {
14187                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14188                }
14189            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14190                synchronized (this) {
14191                    dumpOomLocked(fd, pw, args, opti, true);
14192                }
14193            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14194                synchronized (this) {
14195                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14196                }
14197            } else if ("provider".equals(cmd)) {
14198                String[] newArgs;
14199                String name;
14200                if (opti >= args.length) {
14201                    name = null;
14202                    newArgs = EMPTY_STRING_ARRAY;
14203                } else {
14204                    name = args[opti];
14205                    opti++;
14206                    newArgs = new String[args.length - opti];
14207                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14208                }
14209                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14210                    pw.println("No providers match: " + name);
14211                    pw.println("Use -h for help.");
14212                }
14213            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14214                synchronized (this) {
14215                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14216                }
14217            } else if ("service".equals(cmd)) {
14218                String[] newArgs;
14219                String name;
14220                if (opti >= args.length) {
14221                    name = null;
14222                    newArgs = EMPTY_STRING_ARRAY;
14223                } else {
14224                    name = args[opti];
14225                    opti++;
14226                    newArgs = new String[args.length - opti];
14227                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14228                            args.length - opti);
14229                }
14230                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14231                    pw.println("No services match: " + name);
14232                    pw.println("Use -h for help.");
14233                }
14234            } else if ("package".equals(cmd)) {
14235                String[] newArgs;
14236                if (opti >= args.length) {
14237                    pw.println("package: no package name specified");
14238                    pw.println("Use -h for help.");
14239                } else {
14240                    dumpPackage = args[opti];
14241                    opti++;
14242                    newArgs = new String[args.length - opti];
14243                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14244                            args.length - opti);
14245                    args = newArgs;
14246                    opti = 0;
14247                    more = true;
14248                }
14249            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14250                synchronized (this) {
14251                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14252                }
14253            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14254                if (dumpClient) {
14255                    ActiveServices.ServiceDumper dumper;
14256                    synchronized (this) {
14257                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14258                                dumpPackage);
14259                    }
14260                    dumper.dumpWithClient();
14261                } else {
14262                    synchronized (this) {
14263                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14264                                dumpPackage).dumpLocked();
14265                    }
14266                }
14267            } else if ("locks".equals(cmd)) {
14268                LockGuard.dump(fd, pw, args);
14269            } else {
14270                // Dumping a single activity?
14271                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14272                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14273                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14274                    if (res < 0) {
14275                        pw.println("Bad activity command, or no activities match: " + cmd);
14276                        pw.println("Use -h for help.");
14277                    }
14278                }
14279            }
14280            if (!more) {
14281                Binder.restoreCallingIdentity(origId);
14282                return;
14283            }
14284        }
14285
14286        // No piece of data specified, dump everything.
14287        if (dumpCheckinFormat) {
14288            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14289        } else if (dumpClient) {
14290            ActiveServices.ServiceDumper sdumper;
14291            synchronized (this) {
14292                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14293                pw.println();
14294                if (dumpAll) {
14295                    pw.println("-------------------------------------------------------------------------------");
14296                }
14297                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14298                pw.println();
14299                if (dumpAll) {
14300                    pw.println("-------------------------------------------------------------------------------");
14301                }
14302                if (dumpAll || dumpPackage != null) {
14303                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14304                    pw.println();
14305                    if (dumpAll) {
14306                        pw.println("-------------------------------------------------------------------------------");
14307                    }
14308                }
14309                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14310                pw.println();
14311                if (dumpAll) {
14312                    pw.println("-------------------------------------------------------------------------------");
14313                }
14314                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14315                pw.println();
14316                if (dumpAll) {
14317                    pw.println("-------------------------------------------------------------------------------");
14318                }
14319                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14320                        dumpPackage);
14321            }
14322            sdumper.dumpWithClient();
14323            pw.println();
14324            synchronized (this) {
14325                if (dumpAll) {
14326                    pw.println("-------------------------------------------------------------------------------");
14327                }
14328                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14329                pw.println();
14330                if (dumpAll) {
14331                    pw.println("-------------------------------------------------------------------------------");
14332                }
14333                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14334                if (mAssociations.size() > 0) {
14335                    pw.println();
14336                    if (dumpAll) {
14337                        pw.println("-------------------------------------------------------------------------------");
14338                    }
14339                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14340                }
14341                pw.println();
14342                if (dumpAll) {
14343                    pw.println("-------------------------------------------------------------------------------");
14344                }
14345                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14346            }
14347
14348        } else {
14349            synchronized (this) {
14350                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14351                pw.println();
14352                if (dumpAll) {
14353                    pw.println("-------------------------------------------------------------------------------");
14354                }
14355                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14356                pw.println();
14357                if (dumpAll) {
14358                    pw.println("-------------------------------------------------------------------------------");
14359                }
14360                if (dumpAll || dumpPackage != null) {
14361                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14362                    pw.println();
14363                    if (dumpAll) {
14364                        pw.println("-------------------------------------------------------------------------------");
14365                    }
14366                }
14367                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14368                pw.println();
14369                if (dumpAll) {
14370                    pw.println("-------------------------------------------------------------------------------");
14371                }
14372                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14373                pw.println();
14374                if (dumpAll) {
14375                    pw.println("-------------------------------------------------------------------------------");
14376                }
14377                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14378                        .dumpLocked();
14379                pw.println();
14380                if (dumpAll) {
14381                    pw.println("-------------------------------------------------------------------------------");
14382                }
14383                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14384                pw.println();
14385                if (dumpAll) {
14386                    pw.println("-------------------------------------------------------------------------------");
14387                }
14388                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14389                if (mAssociations.size() > 0) {
14390                    pw.println();
14391                    if (dumpAll) {
14392                        pw.println("-------------------------------------------------------------------------------");
14393                    }
14394                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14395                }
14396                pw.println();
14397                if (dumpAll) {
14398                    pw.println("-------------------------------------------------------------------------------");
14399                }
14400                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14401            }
14402        }
14403        Binder.restoreCallingIdentity(origId);
14404    }
14405
14406    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14407            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14408        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14409
14410        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14411                dumpPackage);
14412        boolean needSep = printedAnything;
14413
14414        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14415                dumpPackage, needSep, "  mFocusedActivity: ");
14416        if (printed) {
14417            printedAnything = true;
14418            needSep = false;
14419        }
14420
14421        if (dumpPackage == null) {
14422            if (needSep) {
14423                pw.println();
14424            }
14425            needSep = true;
14426            printedAnything = true;
14427            mStackSupervisor.dump(pw, "  ");
14428        }
14429
14430        if (!printedAnything) {
14431            pw.println("  (nothing)");
14432        }
14433    }
14434
14435    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14436            int opti, boolean dumpAll, String dumpPackage) {
14437        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14438
14439        boolean printedAnything = false;
14440
14441        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14442            boolean printedHeader = false;
14443
14444            final int N = mRecentTasks.size();
14445            for (int i=0; i<N; i++) {
14446                TaskRecord tr = mRecentTasks.get(i);
14447                if (dumpPackage != null) {
14448                    if (tr.realActivity == null ||
14449                            !dumpPackage.equals(tr.realActivity)) {
14450                        continue;
14451                    }
14452                }
14453                if (!printedHeader) {
14454                    pw.println("  Recent tasks:");
14455                    printedHeader = true;
14456                    printedAnything = true;
14457                }
14458                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14459                        pw.println(tr);
14460                if (dumpAll) {
14461                    mRecentTasks.get(i).dump(pw, "    ");
14462                }
14463            }
14464        }
14465
14466        if (!printedAnything) {
14467            pw.println("  (nothing)");
14468        }
14469    }
14470
14471    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14472            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14473        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14474
14475        int dumpUid = 0;
14476        if (dumpPackage != null) {
14477            IPackageManager pm = AppGlobals.getPackageManager();
14478            try {
14479                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14480            } catch (RemoteException e) {
14481            }
14482        }
14483
14484        boolean printedAnything = false;
14485
14486        final long now = SystemClock.uptimeMillis();
14487
14488        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14489            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14490                    = mAssociations.valueAt(i1);
14491            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14492                SparseArray<ArrayMap<String, Association>> sourceUids
14493                        = targetComponents.valueAt(i2);
14494                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14495                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14496                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14497                        Association ass = sourceProcesses.valueAt(i4);
14498                        if (dumpPackage != null) {
14499                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14500                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14501                                continue;
14502                            }
14503                        }
14504                        printedAnything = true;
14505                        pw.print("  ");
14506                        pw.print(ass.mTargetProcess);
14507                        pw.print("/");
14508                        UserHandle.formatUid(pw, ass.mTargetUid);
14509                        pw.print(" <- ");
14510                        pw.print(ass.mSourceProcess);
14511                        pw.print("/");
14512                        UserHandle.formatUid(pw, ass.mSourceUid);
14513                        pw.println();
14514                        pw.print("    via ");
14515                        pw.print(ass.mTargetComponent.flattenToShortString());
14516                        pw.println();
14517                        pw.print("    ");
14518                        long dur = ass.mTime;
14519                        if (ass.mNesting > 0) {
14520                            dur += now - ass.mStartTime;
14521                        }
14522                        TimeUtils.formatDuration(dur, pw);
14523                        pw.print(" (");
14524                        pw.print(ass.mCount);
14525                        pw.print(" times)");
14526                        pw.print("  ");
14527                        for (int i=0; i<ass.mStateTimes.length; i++) {
14528                            long amt = ass.mStateTimes[i];
14529                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14530                                amt += now - ass.mLastStateUptime;
14531                            }
14532                            if (amt != 0) {
14533                                pw.print(" ");
14534                                pw.print(ProcessList.makeProcStateString(
14535                                            i + ActivityManager.MIN_PROCESS_STATE));
14536                                pw.print("=");
14537                                TimeUtils.formatDuration(amt, pw);
14538                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14539                                    pw.print("*");
14540                                }
14541                            }
14542                        }
14543                        pw.println();
14544                        if (ass.mNesting > 0) {
14545                            pw.print("    Currently active: ");
14546                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14547                            pw.println();
14548                        }
14549                    }
14550                }
14551            }
14552
14553        }
14554
14555        if (!printedAnything) {
14556            pw.println("  (nothing)");
14557        }
14558    }
14559
14560    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14561            String header, boolean needSep) {
14562        boolean printed = false;
14563        int whichAppId = -1;
14564        if (dumpPackage != null) {
14565            try {
14566                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14567                        dumpPackage, 0);
14568                whichAppId = UserHandle.getAppId(info.uid);
14569            } catch (NameNotFoundException e) {
14570                e.printStackTrace();
14571            }
14572        }
14573        for (int i=0; i<uids.size(); i++) {
14574            UidRecord uidRec = uids.valueAt(i);
14575            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14576                continue;
14577            }
14578            if (!printed) {
14579                printed = true;
14580                if (needSep) {
14581                    pw.println();
14582                }
14583                pw.print("  ");
14584                pw.println(header);
14585                needSep = true;
14586            }
14587            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14588            pw.print(": "); pw.println(uidRec);
14589        }
14590        return printed;
14591    }
14592
14593    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14594            int opti, boolean dumpAll, String dumpPackage) {
14595        boolean needSep = false;
14596        boolean printedAnything = false;
14597        int numPers = 0;
14598
14599        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14600
14601        if (dumpAll) {
14602            final int NP = mProcessNames.getMap().size();
14603            for (int ip=0; ip<NP; ip++) {
14604                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14605                final int NA = procs.size();
14606                for (int ia=0; ia<NA; ia++) {
14607                    ProcessRecord r = procs.valueAt(ia);
14608                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14609                        continue;
14610                    }
14611                    if (!needSep) {
14612                        pw.println("  All known processes:");
14613                        needSep = true;
14614                        printedAnything = true;
14615                    }
14616                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14617                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14618                        pw.print(" "); pw.println(r);
14619                    r.dump(pw, "    ");
14620                    if (r.persistent) {
14621                        numPers++;
14622                    }
14623                }
14624            }
14625        }
14626
14627        if (mIsolatedProcesses.size() > 0) {
14628            boolean printed = false;
14629            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14630                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14631                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14632                    continue;
14633                }
14634                if (!printed) {
14635                    if (needSep) {
14636                        pw.println();
14637                    }
14638                    pw.println("  Isolated process list (sorted by uid):");
14639                    printedAnything = true;
14640                    printed = true;
14641                    needSep = true;
14642                }
14643                pw.println(String.format("%sIsolated #%2d: %s",
14644                        "    ", i, r.toString()));
14645            }
14646        }
14647
14648        if (mActiveUids.size() > 0) {
14649            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14650                printedAnything = needSep = true;
14651            }
14652        }
14653        if (mValidateUids.size() > 0) {
14654            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14655                printedAnything = needSep = true;
14656            }
14657        }
14658
14659        if (mLruProcesses.size() > 0) {
14660            if (needSep) {
14661                pw.println();
14662            }
14663            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14664                    pw.print(" total, non-act at ");
14665                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14666                    pw.print(", non-svc at ");
14667                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14668                    pw.println("):");
14669            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14670            needSep = true;
14671            printedAnything = true;
14672        }
14673
14674        if (dumpAll || dumpPackage != null) {
14675            synchronized (mPidsSelfLocked) {
14676                boolean printed = false;
14677                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14678                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14679                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14680                        continue;
14681                    }
14682                    if (!printed) {
14683                        if (needSep) pw.println();
14684                        needSep = true;
14685                        pw.println("  PID mappings:");
14686                        printed = true;
14687                        printedAnything = true;
14688                    }
14689                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14690                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14691                }
14692            }
14693        }
14694
14695        if (mForegroundProcesses.size() > 0) {
14696            synchronized (mPidsSelfLocked) {
14697                boolean printed = false;
14698                for (int i=0; i<mForegroundProcesses.size(); i++) {
14699                    ProcessRecord r = mPidsSelfLocked.get(
14700                            mForegroundProcesses.valueAt(i).pid);
14701                    if (dumpPackage != null && (r == null
14702                            || !r.pkgList.containsKey(dumpPackage))) {
14703                        continue;
14704                    }
14705                    if (!printed) {
14706                        if (needSep) pw.println();
14707                        needSep = true;
14708                        pw.println("  Foreground Processes:");
14709                        printed = true;
14710                        printedAnything = true;
14711                    }
14712                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14713                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14714                }
14715            }
14716        }
14717
14718        if (mPersistentStartingProcesses.size() > 0) {
14719            if (needSep) pw.println();
14720            needSep = true;
14721            printedAnything = true;
14722            pw.println("  Persisent processes that are starting:");
14723            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14724                    "Starting Norm", "Restarting PERS", dumpPackage);
14725        }
14726
14727        if (mRemovedProcesses.size() > 0) {
14728            if (needSep) pw.println();
14729            needSep = true;
14730            printedAnything = true;
14731            pw.println("  Processes that are being removed:");
14732            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14733                    "Removed Norm", "Removed PERS", dumpPackage);
14734        }
14735
14736        if (mProcessesOnHold.size() > 0) {
14737            if (needSep) pw.println();
14738            needSep = true;
14739            printedAnything = true;
14740            pw.println("  Processes that are on old until the system is ready:");
14741            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14742                    "OnHold Norm", "OnHold PERS", dumpPackage);
14743        }
14744
14745        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14746
14747        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14748        if (needSep) {
14749            printedAnything = true;
14750        }
14751
14752        if (dumpPackage == null) {
14753            pw.println();
14754            needSep = false;
14755            mUserController.dump(pw, dumpAll);
14756        }
14757        if (mHomeProcess != null && (dumpPackage == null
14758                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14759            if (needSep) {
14760                pw.println();
14761                needSep = false;
14762            }
14763            pw.println("  mHomeProcess: " + mHomeProcess);
14764        }
14765        if (mPreviousProcess != null && (dumpPackage == null
14766                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14767            if (needSep) {
14768                pw.println();
14769                needSep = false;
14770            }
14771            pw.println("  mPreviousProcess: " + mPreviousProcess);
14772        }
14773        if (dumpAll) {
14774            StringBuilder sb = new StringBuilder(128);
14775            sb.append("  mPreviousProcessVisibleTime: ");
14776            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14777            pw.println(sb);
14778        }
14779        if (mHeavyWeightProcess != null && (dumpPackage == null
14780                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14781            if (needSep) {
14782                pw.println();
14783                needSep = false;
14784            }
14785            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14786        }
14787        if (dumpPackage == null) {
14788            pw.println("  mConfiguration: " + mConfiguration);
14789        }
14790        if (dumpAll) {
14791            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14792            if (mCompatModePackages.getPackages().size() > 0) {
14793                boolean printed = false;
14794                for (Map.Entry<String, Integer> entry
14795                        : mCompatModePackages.getPackages().entrySet()) {
14796                    String pkg = entry.getKey();
14797                    int mode = entry.getValue();
14798                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14799                        continue;
14800                    }
14801                    if (!printed) {
14802                        pw.println("  mScreenCompatPackages:");
14803                        printed = true;
14804                    }
14805                    pw.print("    "); pw.print(pkg); pw.print(": ");
14806                            pw.print(mode); pw.println();
14807                }
14808            }
14809        }
14810        if (dumpPackage == null) {
14811            pw.println("  mWakefulness="
14812                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14813            pw.println("  mSleepTokens=" + mSleepTokens);
14814            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14815                    + lockScreenShownToString());
14816            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14817            if (mRunningVoice != null) {
14818                pw.println("  mRunningVoice=" + mRunningVoice);
14819                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14820            }
14821        }
14822        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14823                || mOrigWaitForDebugger) {
14824            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14825                    || dumpPackage.equals(mOrigDebugApp)) {
14826                if (needSep) {
14827                    pw.println();
14828                    needSep = false;
14829                }
14830                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14831                        + " mDebugTransient=" + mDebugTransient
14832                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14833            }
14834        }
14835        if (mCurAppTimeTracker != null) {
14836            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14837        }
14838        if (mMemWatchProcesses.getMap().size() > 0) {
14839            pw.println("  Mem watch processes:");
14840            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14841                    = mMemWatchProcesses.getMap();
14842            for (int i=0; i<procs.size(); i++) {
14843                final String proc = procs.keyAt(i);
14844                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14845                for (int j=0; j<uids.size(); j++) {
14846                    if (needSep) {
14847                        pw.println();
14848                        needSep = false;
14849                    }
14850                    StringBuilder sb = new StringBuilder();
14851                    sb.append("    ").append(proc).append('/');
14852                    UserHandle.formatUid(sb, uids.keyAt(j));
14853                    Pair<Long, String> val = uids.valueAt(j);
14854                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14855                    if (val.second != null) {
14856                        sb.append(", report to ").append(val.second);
14857                    }
14858                    pw.println(sb.toString());
14859                }
14860            }
14861            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14862            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14863            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14864                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14865        }
14866        if (mTrackAllocationApp != null) {
14867            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14868                if (needSep) {
14869                    pw.println();
14870                    needSep = false;
14871                }
14872                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14873            }
14874        }
14875        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14876                || mProfileFd != null) {
14877            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14878                if (needSep) {
14879                    pw.println();
14880                    needSep = false;
14881                }
14882                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14883                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14884                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14885                        + mAutoStopProfiler);
14886                pw.println("  mProfileType=" + mProfileType);
14887            }
14888        }
14889        if (mNativeDebuggingApp != null) {
14890            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14891                if (needSep) {
14892                    pw.println();
14893                    needSep = false;
14894                }
14895                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14896            }
14897        }
14898        if (dumpPackage == null) {
14899            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14900                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14901                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14902            }
14903            if (mController != null) {
14904                pw.println("  mController=" + mController
14905                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14906            }
14907            if (dumpAll) {
14908                pw.println("  Total persistent processes: " + numPers);
14909                pw.println("  mProcessesReady=" + mProcessesReady
14910                        + " mSystemReady=" + mSystemReady
14911                        + " mBooted=" + mBooted
14912                        + " mFactoryTest=" + mFactoryTest);
14913                pw.println("  mBooting=" + mBooting
14914                        + " mCallFinishBooting=" + mCallFinishBooting
14915                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14916                pw.print("  mLastPowerCheckRealtime=");
14917                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14918                        pw.println("");
14919                pw.print("  mLastPowerCheckUptime=");
14920                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14921                        pw.println("");
14922                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14923                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14924                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14925                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14926                        + " (" + mLruProcesses.size() + " total)"
14927                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14928                        + " mNumServiceProcs=" + mNumServiceProcs
14929                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14930                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14931                        + " mLastMemoryLevel=" + mLastMemoryLevel
14932                        + " mLastNumProcesses=" + mLastNumProcesses);
14933                long now = SystemClock.uptimeMillis();
14934                pw.print("  mLastIdleTime=");
14935                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14936                        pw.print(" mLowRamSinceLastIdle=");
14937                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14938                        pw.println();
14939            }
14940        }
14941
14942        if (!printedAnything) {
14943            pw.println("  (nothing)");
14944        }
14945    }
14946
14947    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14948            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14949        if (mProcessesToGc.size() > 0) {
14950            boolean printed = false;
14951            long now = SystemClock.uptimeMillis();
14952            for (int i=0; i<mProcessesToGc.size(); i++) {
14953                ProcessRecord proc = mProcessesToGc.get(i);
14954                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14955                    continue;
14956                }
14957                if (!printed) {
14958                    if (needSep) pw.println();
14959                    needSep = true;
14960                    pw.println("  Processes that are waiting to GC:");
14961                    printed = true;
14962                }
14963                pw.print("    Process "); pw.println(proc);
14964                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14965                        pw.print(", last gced=");
14966                        pw.print(now-proc.lastRequestedGc);
14967                        pw.print(" ms ago, last lowMem=");
14968                        pw.print(now-proc.lastLowMemory);
14969                        pw.println(" ms ago");
14970
14971            }
14972        }
14973        return needSep;
14974    }
14975
14976    void printOomLevel(PrintWriter pw, String name, int adj) {
14977        pw.print("    ");
14978        if (adj >= 0) {
14979            pw.print(' ');
14980            if (adj < 10) pw.print(' ');
14981        } else {
14982            if (adj > -10) pw.print(' ');
14983        }
14984        pw.print(adj);
14985        pw.print(": ");
14986        pw.print(name);
14987        pw.print(" (");
14988        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14989        pw.println(")");
14990    }
14991
14992    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14993            int opti, boolean dumpAll) {
14994        boolean needSep = false;
14995
14996        if (mLruProcesses.size() > 0) {
14997            if (needSep) pw.println();
14998            needSep = true;
14999            pw.println("  OOM levels:");
15000            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15001            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15002            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15003            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15004            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15005            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15006            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15007            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15008            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15009            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15010            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15011            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15012            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15013            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15014
15015            if (needSep) pw.println();
15016            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15017                    pw.print(" total, non-act at ");
15018                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15019                    pw.print(", non-svc at ");
15020                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15021                    pw.println("):");
15022            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15023            needSep = true;
15024        }
15025
15026        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15027
15028        pw.println();
15029        pw.println("  mHomeProcess: " + mHomeProcess);
15030        pw.println("  mPreviousProcess: " + mPreviousProcess);
15031        if (mHeavyWeightProcess != null) {
15032            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15033        }
15034
15035        return true;
15036    }
15037
15038    /**
15039     * There are three ways to call this:
15040     *  - no provider specified: dump all the providers
15041     *  - a flattened component name that matched an existing provider was specified as the
15042     *    first arg: dump that one provider
15043     *  - the first arg isn't the flattened component name of an existing provider:
15044     *    dump all providers whose component contains the first arg as a substring
15045     */
15046    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15047            int opti, boolean dumpAll) {
15048        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15049    }
15050
15051    static class ItemMatcher {
15052        ArrayList<ComponentName> components;
15053        ArrayList<String> strings;
15054        ArrayList<Integer> objects;
15055        boolean all;
15056
15057        ItemMatcher() {
15058            all = true;
15059        }
15060
15061        void build(String name) {
15062            ComponentName componentName = ComponentName.unflattenFromString(name);
15063            if (componentName != null) {
15064                if (components == null) {
15065                    components = new ArrayList<ComponentName>();
15066                }
15067                components.add(componentName);
15068                all = false;
15069            } else {
15070                int objectId = 0;
15071                // Not a '/' separated full component name; maybe an object ID?
15072                try {
15073                    objectId = Integer.parseInt(name, 16);
15074                    if (objects == null) {
15075                        objects = new ArrayList<Integer>();
15076                    }
15077                    objects.add(objectId);
15078                    all = false;
15079                } catch (RuntimeException e) {
15080                    // Not an integer; just do string match.
15081                    if (strings == null) {
15082                        strings = new ArrayList<String>();
15083                    }
15084                    strings.add(name);
15085                    all = false;
15086                }
15087            }
15088        }
15089
15090        int build(String[] args, int opti) {
15091            for (; opti<args.length; opti++) {
15092                String name = args[opti];
15093                if ("--".equals(name)) {
15094                    return opti+1;
15095                }
15096                build(name);
15097            }
15098            return opti;
15099        }
15100
15101        boolean match(Object object, ComponentName comp) {
15102            if (all) {
15103                return true;
15104            }
15105            if (components != null) {
15106                for (int i=0; i<components.size(); i++) {
15107                    if (components.get(i).equals(comp)) {
15108                        return true;
15109                    }
15110                }
15111            }
15112            if (objects != null) {
15113                for (int i=0; i<objects.size(); i++) {
15114                    if (System.identityHashCode(object) == objects.get(i)) {
15115                        return true;
15116                    }
15117                }
15118            }
15119            if (strings != null) {
15120                String flat = comp.flattenToString();
15121                for (int i=0; i<strings.size(); i++) {
15122                    if (flat.contains(strings.get(i))) {
15123                        return true;
15124                    }
15125                }
15126            }
15127            return false;
15128        }
15129    }
15130
15131    /**
15132     * There are three things that cmd can be:
15133     *  - a flattened component name that matches an existing activity
15134     *  - the cmd arg isn't the flattened component name of an existing activity:
15135     *    dump all activity whose component contains the cmd as a substring
15136     *  - A hex number of the ActivityRecord object instance.
15137     */
15138    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15139            int opti, boolean dumpAll) {
15140        ArrayList<ActivityRecord> activities;
15141
15142        synchronized (this) {
15143            activities = mStackSupervisor.getDumpActivitiesLocked(name);
15144        }
15145
15146        if (activities.size() <= 0) {
15147            return false;
15148        }
15149
15150        String[] newArgs = new String[args.length - opti];
15151        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15152
15153        TaskRecord lastTask = null;
15154        boolean needSep = false;
15155        for (int i=activities.size()-1; i>=0; i--) {
15156            ActivityRecord r = activities.get(i);
15157            if (needSep) {
15158                pw.println();
15159            }
15160            needSep = true;
15161            synchronized (this) {
15162                if (lastTask != r.task) {
15163                    lastTask = r.task;
15164                    pw.print("TASK "); pw.print(lastTask.affinity);
15165                            pw.print(" id="); pw.println(lastTask.taskId);
15166                    if (dumpAll) {
15167                        lastTask.dump(pw, "  ");
15168                    }
15169                }
15170            }
15171            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15172        }
15173        return true;
15174    }
15175
15176    /**
15177     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15178     * there is a thread associated with the activity.
15179     */
15180    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15181            final ActivityRecord r, String[] args, boolean dumpAll) {
15182        String innerPrefix = prefix + "  ";
15183        synchronized (this) {
15184            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15185                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15186                    pw.print(" pid=");
15187                    if (r.app != null) pw.println(r.app.pid);
15188                    else pw.println("(not running)");
15189            if (dumpAll) {
15190                r.dump(pw, innerPrefix);
15191            }
15192        }
15193        if (r.app != null && r.app.thread != null) {
15194            // flush anything that is already in the PrintWriter since the thread is going
15195            // to write to the file descriptor directly
15196            pw.flush();
15197            try {
15198                TransferPipe tp = new TransferPipe();
15199                try {
15200                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15201                            r.appToken, innerPrefix, args);
15202                    tp.go(fd);
15203                } finally {
15204                    tp.kill();
15205                }
15206            } catch (IOException e) {
15207                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15208            } catch (RemoteException e) {
15209                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15210            }
15211        }
15212    }
15213
15214    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15215            int opti, boolean dumpAll, String dumpPackage) {
15216        boolean needSep = false;
15217        boolean onlyHistory = false;
15218        boolean printedAnything = false;
15219
15220        if ("history".equals(dumpPackage)) {
15221            if (opti < args.length && "-s".equals(args[opti])) {
15222                dumpAll = false;
15223            }
15224            onlyHistory = true;
15225            dumpPackage = null;
15226        }
15227
15228        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15229        if (!onlyHistory && dumpAll) {
15230            if (mRegisteredReceivers.size() > 0) {
15231                boolean printed = false;
15232                Iterator it = mRegisteredReceivers.values().iterator();
15233                while (it.hasNext()) {
15234                    ReceiverList r = (ReceiverList)it.next();
15235                    if (dumpPackage != null && (r.app == null ||
15236                            !dumpPackage.equals(r.app.info.packageName))) {
15237                        continue;
15238                    }
15239                    if (!printed) {
15240                        pw.println("  Registered Receivers:");
15241                        needSep = true;
15242                        printed = true;
15243                        printedAnything = true;
15244                    }
15245                    pw.print("  * "); pw.println(r);
15246                    r.dump(pw, "    ");
15247                }
15248            }
15249
15250            if (mReceiverResolver.dump(pw, needSep ?
15251                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15252                    "    ", dumpPackage, false, false)) {
15253                needSep = true;
15254                printedAnything = true;
15255            }
15256        }
15257
15258        for (BroadcastQueue q : mBroadcastQueues) {
15259            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15260            printedAnything |= needSep;
15261        }
15262
15263        needSep = true;
15264
15265        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15266            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15267                if (needSep) {
15268                    pw.println();
15269                }
15270                needSep = true;
15271                printedAnything = true;
15272                pw.print("  Sticky broadcasts for user ");
15273                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15274                StringBuilder sb = new StringBuilder(128);
15275                for (Map.Entry<String, ArrayList<Intent>> ent
15276                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15277                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15278                    if (dumpAll) {
15279                        pw.println(":");
15280                        ArrayList<Intent> intents = ent.getValue();
15281                        final int N = intents.size();
15282                        for (int i=0; i<N; i++) {
15283                            sb.setLength(0);
15284                            sb.append("    Intent: ");
15285                            intents.get(i).toShortString(sb, false, true, false, false);
15286                            pw.println(sb.toString());
15287                            Bundle bundle = intents.get(i).getExtras();
15288                            if (bundle != null) {
15289                                pw.print("      ");
15290                                pw.println(bundle.toString());
15291                            }
15292                        }
15293                    } else {
15294                        pw.println("");
15295                    }
15296                }
15297            }
15298        }
15299
15300        if (!onlyHistory && dumpAll) {
15301            pw.println();
15302            for (BroadcastQueue queue : mBroadcastQueues) {
15303                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15304                        + queue.mBroadcastsScheduled);
15305            }
15306            pw.println("  mHandler:");
15307            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15308            needSep = true;
15309            printedAnything = true;
15310        }
15311
15312        if (!printedAnything) {
15313            pw.println("  (nothing)");
15314        }
15315    }
15316
15317    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15318            int opti, boolean dumpAll, String dumpPackage) {
15319        if (mCurBroadcastStats == null) {
15320            return;
15321        }
15322
15323        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15324        final long now = SystemClock.elapsedRealtime();
15325        if (mLastBroadcastStats != null) {
15326            pw.print("  Last stats (from ");
15327            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15328            pw.print(" to ");
15329            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15330            pw.print(", ");
15331            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15332                    - mLastBroadcastStats.mStartUptime, pw);
15333            pw.println(" uptime):");
15334            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15335                pw.println("    (nothing)");
15336            }
15337            pw.println();
15338        }
15339        pw.print("  Current stats (from ");
15340        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15341        pw.print(" to now, ");
15342        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15343                - mCurBroadcastStats.mStartUptime, pw);
15344        pw.println(" uptime):");
15345        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15346            pw.println("    (nothing)");
15347        }
15348    }
15349
15350    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15351            int opti, boolean fullCheckin, String dumpPackage) {
15352        if (mCurBroadcastStats == null) {
15353            return;
15354        }
15355
15356        if (mLastBroadcastStats != null) {
15357            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15358            if (fullCheckin) {
15359                mLastBroadcastStats = null;
15360                return;
15361            }
15362        }
15363        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15364        if (fullCheckin) {
15365            mCurBroadcastStats = null;
15366        }
15367    }
15368
15369    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15370            int opti, boolean dumpAll, String dumpPackage) {
15371        boolean needSep;
15372        boolean printedAnything = false;
15373
15374        ItemMatcher matcher = new ItemMatcher();
15375        matcher.build(args, opti);
15376
15377        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15378
15379        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15380        printedAnything |= needSep;
15381
15382        if (mLaunchingProviders.size() > 0) {
15383            boolean printed = false;
15384            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15385                ContentProviderRecord r = mLaunchingProviders.get(i);
15386                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15387                    continue;
15388                }
15389                if (!printed) {
15390                    if (needSep) pw.println();
15391                    needSep = true;
15392                    pw.println("  Launching content providers:");
15393                    printed = true;
15394                    printedAnything = true;
15395                }
15396                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15397                        pw.println(r);
15398            }
15399        }
15400
15401        if (!printedAnything) {
15402            pw.println("  (nothing)");
15403        }
15404    }
15405
15406    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15407            int opti, boolean dumpAll, String dumpPackage) {
15408        boolean needSep = false;
15409        boolean printedAnything = false;
15410
15411        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15412
15413        if (mGrantedUriPermissions.size() > 0) {
15414            boolean printed = false;
15415            int dumpUid = -2;
15416            if (dumpPackage != null) {
15417                try {
15418                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15419                            MATCH_UNINSTALLED_PACKAGES, 0);
15420                } catch (NameNotFoundException e) {
15421                    dumpUid = -1;
15422                }
15423            }
15424            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15425                int uid = mGrantedUriPermissions.keyAt(i);
15426                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15427                    continue;
15428                }
15429                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15430                if (!printed) {
15431                    if (needSep) pw.println();
15432                    needSep = true;
15433                    pw.println("  Granted Uri Permissions:");
15434                    printed = true;
15435                    printedAnything = true;
15436                }
15437                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15438                for (UriPermission perm : perms.values()) {
15439                    pw.print("    "); pw.println(perm);
15440                    if (dumpAll) {
15441                        perm.dump(pw, "      ");
15442                    }
15443                }
15444            }
15445        }
15446
15447        if (!printedAnything) {
15448            pw.println("  (nothing)");
15449        }
15450    }
15451
15452    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15453            int opti, boolean dumpAll, String dumpPackage) {
15454        boolean printed = false;
15455
15456        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15457
15458        if (mIntentSenderRecords.size() > 0) {
15459            Iterator<WeakReference<PendingIntentRecord>> it
15460                    = mIntentSenderRecords.values().iterator();
15461            while (it.hasNext()) {
15462                WeakReference<PendingIntentRecord> ref = it.next();
15463                PendingIntentRecord rec = ref != null ? ref.get(): null;
15464                if (dumpPackage != null && (rec == null
15465                        || !dumpPackage.equals(rec.key.packageName))) {
15466                    continue;
15467                }
15468                printed = true;
15469                if (rec != null) {
15470                    pw.print("  * "); pw.println(rec);
15471                    if (dumpAll) {
15472                        rec.dump(pw, "    ");
15473                    }
15474                } else {
15475                    pw.print("  * "); pw.println(ref);
15476                }
15477            }
15478        }
15479
15480        if (!printed) {
15481            pw.println("  (nothing)");
15482        }
15483    }
15484
15485    private static final int dumpProcessList(PrintWriter pw,
15486            ActivityManagerService service, List list,
15487            String prefix, String normalLabel, String persistentLabel,
15488            String dumpPackage) {
15489        int numPers = 0;
15490        final int N = list.size()-1;
15491        for (int i=N; i>=0; i--) {
15492            ProcessRecord r = (ProcessRecord)list.get(i);
15493            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15494                continue;
15495            }
15496            pw.println(String.format("%s%s #%2d: %s",
15497                    prefix, (r.persistent ? persistentLabel : normalLabel),
15498                    i, r.toString()));
15499            if (r.persistent) {
15500                numPers++;
15501            }
15502        }
15503        return numPers;
15504    }
15505
15506    private static final boolean dumpProcessOomList(PrintWriter pw,
15507            ActivityManagerService service, List<ProcessRecord> origList,
15508            String prefix, String normalLabel, String persistentLabel,
15509            boolean inclDetails, String dumpPackage) {
15510
15511        ArrayList<Pair<ProcessRecord, Integer>> list
15512                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15513        for (int i=0; i<origList.size(); i++) {
15514            ProcessRecord r = origList.get(i);
15515            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15516                continue;
15517            }
15518            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15519        }
15520
15521        if (list.size() <= 0) {
15522            return false;
15523        }
15524
15525        Comparator<Pair<ProcessRecord, Integer>> comparator
15526                = new Comparator<Pair<ProcessRecord, Integer>>() {
15527            @Override
15528            public int compare(Pair<ProcessRecord, Integer> object1,
15529                    Pair<ProcessRecord, Integer> object2) {
15530                if (object1.first.setAdj != object2.first.setAdj) {
15531                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15532                }
15533                if (object1.first.setProcState != object2.first.setProcState) {
15534                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15535                }
15536                if (object1.second.intValue() != object2.second.intValue()) {
15537                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15538                }
15539                return 0;
15540            }
15541        };
15542
15543        Collections.sort(list, comparator);
15544
15545        final long curRealtime = SystemClock.elapsedRealtime();
15546        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15547        final long curUptime = SystemClock.uptimeMillis();
15548        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15549
15550        for (int i=list.size()-1; i>=0; i--) {
15551            ProcessRecord r = list.get(i).first;
15552            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15553            char schedGroup;
15554            switch (r.setSchedGroup) {
15555                case ProcessList.SCHED_GROUP_BACKGROUND:
15556                    schedGroup = 'B';
15557                    break;
15558                case ProcessList.SCHED_GROUP_DEFAULT:
15559                    schedGroup = 'F';
15560                    break;
15561                case ProcessList.SCHED_GROUP_TOP_APP:
15562                    schedGroup = 'T';
15563                    break;
15564                default:
15565                    schedGroup = '?';
15566                    break;
15567            }
15568            char foreground;
15569            if (r.foregroundActivities) {
15570                foreground = 'A';
15571            } else if (r.foregroundServices) {
15572                foreground = 'S';
15573            } else {
15574                foreground = ' ';
15575            }
15576            String procState = ProcessList.makeProcStateString(r.curProcState);
15577            pw.print(prefix);
15578            pw.print(r.persistent ? persistentLabel : normalLabel);
15579            pw.print(" #");
15580            int num = (origList.size()-1)-list.get(i).second;
15581            if (num < 10) pw.print(' ');
15582            pw.print(num);
15583            pw.print(": ");
15584            pw.print(oomAdj);
15585            pw.print(' ');
15586            pw.print(schedGroup);
15587            pw.print('/');
15588            pw.print(foreground);
15589            pw.print('/');
15590            pw.print(procState);
15591            pw.print(" trm:");
15592            if (r.trimMemoryLevel < 10) pw.print(' ');
15593            pw.print(r.trimMemoryLevel);
15594            pw.print(' ');
15595            pw.print(r.toShortString());
15596            pw.print(" (");
15597            pw.print(r.adjType);
15598            pw.println(')');
15599            if (r.adjSource != null || r.adjTarget != null) {
15600                pw.print(prefix);
15601                pw.print("    ");
15602                if (r.adjTarget instanceof ComponentName) {
15603                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15604                } else if (r.adjTarget != null) {
15605                    pw.print(r.adjTarget.toString());
15606                } else {
15607                    pw.print("{null}");
15608                }
15609                pw.print("<=");
15610                if (r.adjSource instanceof ProcessRecord) {
15611                    pw.print("Proc{");
15612                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15613                    pw.println("}");
15614                } else if (r.adjSource != null) {
15615                    pw.println(r.adjSource.toString());
15616                } else {
15617                    pw.println("{null}");
15618                }
15619            }
15620            if (inclDetails) {
15621                pw.print(prefix);
15622                pw.print("    ");
15623                pw.print("oom: max="); pw.print(r.maxAdj);
15624                pw.print(" curRaw="); pw.print(r.curRawAdj);
15625                pw.print(" setRaw="); pw.print(r.setRawAdj);
15626                pw.print(" cur="); pw.print(r.curAdj);
15627                pw.print(" set="); pw.println(r.setAdj);
15628                pw.print(prefix);
15629                pw.print("    ");
15630                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15631                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15632                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15633                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15634                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15635                pw.println();
15636                pw.print(prefix);
15637                pw.print("    ");
15638                pw.print("cached="); pw.print(r.cached);
15639                pw.print(" empty="); pw.print(r.empty);
15640                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15641
15642                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15643                    if (r.lastWakeTime != 0) {
15644                        long wtime;
15645                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15646                        synchronized (stats) {
15647                            wtime = stats.getProcessWakeTime(r.info.uid,
15648                                    r.pid, curRealtime);
15649                        }
15650                        long timeUsed = wtime - r.lastWakeTime;
15651                        pw.print(prefix);
15652                        pw.print("    ");
15653                        pw.print("keep awake over ");
15654                        TimeUtils.formatDuration(realtimeSince, pw);
15655                        pw.print(" used ");
15656                        TimeUtils.formatDuration(timeUsed, pw);
15657                        pw.print(" (");
15658                        pw.print((timeUsed*100)/realtimeSince);
15659                        pw.println("%)");
15660                    }
15661                    if (r.lastCpuTime != 0) {
15662                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15663                        pw.print(prefix);
15664                        pw.print("    ");
15665                        pw.print("run cpu over ");
15666                        TimeUtils.formatDuration(uptimeSince, pw);
15667                        pw.print(" used ");
15668                        TimeUtils.formatDuration(timeUsed, pw);
15669                        pw.print(" (");
15670                        pw.print((timeUsed*100)/uptimeSince);
15671                        pw.println("%)");
15672                    }
15673                }
15674            }
15675        }
15676        return true;
15677    }
15678
15679    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15680            String[] args) {
15681        ArrayList<ProcessRecord> procs;
15682        synchronized (this) {
15683            if (args != null && args.length > start
15684                    && args[start].charAt(0) != '-') {
15685                procs = new ArrayList<ProcessRecord>();
15686                int pid = -1;
15687                try {
15688                    pid = Integer.parseInt(args[start]);
15689                } catch (NumberFormatException e) {
15690                }
15691                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15692                    ProcessRecord proc = mLruProcesses.get(i);
15693                    if (proc.pid == pid) {
15694                        procs.add(proc);
15695                    } else if (allPkgs && proc.pkgList != null
15696                            && proc.pkgList.containsKey(args[start])) {
15697                        procs.add(proc);
15698                    } else if (proc.processName.equals(args[start])) {
15699                        procs.add(proc);
15700                    }
15701                }
15702                if (procs.size() <= 0) {
15703                    return null;
15704                }
15705            } else {
15706                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15707            }
15708        }
15709        return procs;
15710    }
15711
15712    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15713            PrintWriter pw, String[] args) {
15714        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15715        if (procs == null) {
15716            pw.println("No process found for: " + args[0]);
15717            return;
15718        }
15719
15720        long uptime = SystemClock.uptimeMillis();
15721        long realtime = SystemClock.elapsedRealtime();
15722        pw.println("Applications Graphics Acceleration Info:");
15723        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15724
15725        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15726            ProcessRecord r = procs.get(i);
15727            if (r.thread != null) {
15728                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15729                pw.flush();
15730                try {
15731                    TransferPipe tp = new TransferPipe();
15732                    try {
15733                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15734                        tp.go(fd);
15735                    } finally {
15736                        tp.kill();
15737                    }
15738                } catch (IOException e) {
15739                    pw.println("Failure while dumping the app: " + r);
15740                    pw.flush();
15741                } catch (RemoteException e) {
15742                    pw.println("Got a RemoteException while dumping the app " + r);
15743                    pw.flush();
15744                }
15745            }
15746        }
15747    }
15748
15749    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15750        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15751        if (procs == null) {
15752            pw.println("No process found for: " + args[0]);
15753            return;
15754        }
15755
15756        pw.println("Applications Database Info:");
15757
15758        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15759            ProcessRecord r = procs.get(i);
15760            if (r.thread != null) {
15761                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15762                pw.flush();
15763                try {
15764                    TransferPipe tp = new TransferPipe();
15765                    try {
15766                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15767                        tp.go(fd);
15768                    } finally {
15769                        tp.kill();
15770                    }
15771                } catch (IOException e) {
15772                    pw.println("Failure while dumping the app: " + r);
15773                    pw.flush();
15774                } catch (RemoteException e) {
15775                    pw.println("Got a RemoteException while dumping the app " + r);
15776                    pw.flush();
15777                }
15778            }
15779        }
15780    }
15781
15782    final static class MemItem {
15783        final boolean isProc;
15784        final String label;
15785        final String shortLabel;
15786        final long pss;
15787        final long swapPss;
15788        final int id;
15789        final boolean hasActivities;
15790        ArrayList<MemItem> subitems;
15791
15792        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15793                boolean _hasActivities) {
15794            isProc = true;
15795            label = _label;
15796            shortLabel = _shortLabel;
15797            pss = _pss;
15798            swapPss = _swapPss;
15799            id = _id;
15800            hasActivities = _hasActivities;
15801        }
15802
15803        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15804            isProc = false;
15805            label = _label;
15806            shortLabel = _shortLabel;
15807            pss = _pss;
15808            swapPss = _swapPss;
15809            id = _id;
15810            hasActivities = false;
15811        }
15812    }
15813
15814    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15815            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15816        if (sort && !isCompact) {
15817            Collections.sort(items, new Comparator<MemItem>() {
15818                @Override
15819                public int compare(MemItem lhs, MemItem rhs) {
15820                    if (lhs.pss < rhs.pss) {
15821                        return 1;
15822                    } else if (lhs.pss > rhs.pss) {
15823                        return -1;
15824                    }
15825                    return 0;
15826                }
15827            });
15828        }
15829
15830        for (int i=0; i<items.size(); i++) {
15831            MemItem mi = items.get(i);
15832            if (!isCompact) {
15833                if (dumpSwapPss) {
15834                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15835                            mi.label, stringifyKBSize(mi.swapPss));
15836                } else {
15837                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15838                }
15839            } else if (mi.isProc) {
15840                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15841                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15842                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15843                pw.println(mi.hasActivities ? ",a" : ",e");
15844            } else {
15845                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15846                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15847            }
15848            if (mi.subitems != null) {
15849                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15850                        true, isCompact, dumpSwapPss);
15851            }
15852        }
15853    }
15854
15855    // These are in KB.
15856    static final long[] DUMP_MEM_BUCKETS = new long[] {
15857        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15858        120*1024, 160*1024, 200*1024,
15859        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15860        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15861    };
15862
15863    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15864            boolean stackLike) {
15865        int start = label.lastIndexOf('.');
15866        if (start >= 0) start++;
15867        else start = 0;
15868        int end = label.length();
15869        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15870            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15871                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15872                out.append(bucket);
15873                out.append(stackLike ? "MB." : "MB ");
15874                out.append(label, start, end);
15875                return;
15876            }
15877        }
15878        out.append(memKB/1024);
15879        out.append(stackLike ? "MB." : "MB ");
15880        out.append(label, start, end);
15881    }
15882
15883    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15884            ProcessList.NATIVE_ADJ,
15885            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15886            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15887            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15888            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15889            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15890            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15891    };
15892    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15893            "Native",
15894            "System", "Persistent", "Persistent Service", "Foreground",
15895            "Visible", "Perceptible",
15896            "Heavy Weight", "Backup",
15897            "A Services", "Home",
15898            "Previous", "B Services", "Cached"
15899    };
15900    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15901            "native",
15902            "sys", "pers", "persvc", "fore",
15903            "vis", "percept",
15904            "heavy", "backup",
15905            "servicea", "home",
15906            "prev", "serviceb", "cached"
15907    };
15908
15909    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15910            long realtime, boolean isCheckinRequest, boolean isCompact) {
15911        if (isCompact) {
15912            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15913        }
15914        if (isCheckinRequest || isCompact) {
15915            // short checkin version
15916            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15917        } else {
15918            pw.println("Applications Memory Usage (in Kilobytes):");
15919            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15920        }
15921    }
15922
15923    private static final int KSM_SHARED = 0;
15924    private static final int KSM_SHARING = 1;
15925    private static final int KSM_UNSHARED = 2;
15926    private static final int KSM_VOLATILE = 3;
15927
15928    private final long[] getKsmInfo() {
15929        long[] longOut = new long[4];
15930        final int[] SINGLE_LONG_FORMAT = new int[] {
15931            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15932        };
15933        long[] longTmp = new long[1];
15934        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15935                SINGLE_LONG_FORMAT, null, longTmp, null);
15936        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15937        longTmp[0] = 0;
15938        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15939                SINGLE_LONG_FORMAT, null, longTmp, null);
15940        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15941        longTmp[0] = 0;
15942        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15943                SINGLE_LONG_FORMAT, null, longTmp, null);
15944        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15945        longTmp[0] = 0;
15946        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15947                SINGLE_LONG_FORMAT, null, longTmp, null);
15948        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15949        return longOut;
15950    }
15951
15952    private static String stringifySize(long size, int order) {
15953        Locale locale = Locale.US;
15954        switch (order) {
15955            case 1:
15956                return String.format(locale, "%,13d", size);
15957            case 1024:
15958                return String.format(locale, "%,9dK", size / 1024);
15959            case 1024 * 1024:
15960                return String.format(locale, "%,5dM", size / 1024 / 1024);
15961            case 1024 * 1024 * 1024:
15962                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15963            default:
15964                throw new IllegalArgumentException("Invalid size order");
15965        }
15966    }
15967
15968    private static String stringifyKBSize(long size) {
15969        return stringifySize(size * 1024, 1024);
15970    }
15971
15972    // Update this version number in case you change the 'compact' format
15973    private static final int MEMINFO_COMPACT_VERSION = 1;
15974
15975    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15976            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15977        boolean dumpDetails = false;
15978        boolean dumpFullDetails = false;
15979        boolean dumpDalvik = false;
15980        boolean dumpSummaryOnly = false;
15981        boolean dumpUnreachable = false;
15982        boolean oomOnly = false;
15983        boolean isCompact = false;
15984        boolean localOnly = false;
15985        boolean packages = false;
15986        boolean isCheckinRequest = false;
15987        boolean dumpSwapPss = false;
15988
15989        int opti = 0;
15990        while (opti < args.length) {
15991            String opt = args[opti];
15992            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15993                break;
15994            }
15995            opti++;
15996            if ("-a".equals(opt)) {
15997                dumpDetails = true;
15998                dumpFullDetails = true;
15999                dumpDalvik = true;
16000                dumpSwapPss = true;
16001            } else if ("-d".equals(opt)) {
16002                dumpDalvik = true;
16003            } else if ("-c".equals(opt)) {
16004                isCompact = true;
16005            } else if ("-s".equals(opt)) {
16006                dumpDetails = true;
16007                dumpSummaryOnly = true;
16008            } else if ("-S".equals(opt)) {
16009                dumpSwapPss = true;
16010            } else if ("--unreachable".equals(opt)) {
16011                dumpUnreachable = true;
16012            } else if ("--oom".equals(opt)) {
16013                oomOnly = true;
16014            } else if ("--local".equals(opt)) {
16015                localOnly = true;
16016            } else if ("--package".equals(opt)) {
16017                packages = true;
16018            } else if ("--checkin".equals(opt)) {
16019                isCheckinRequest = true;
16020
16021            } else if ("-h".equals(opt)) {
16022                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16023                pw.println("  -a: include all available information for each process.");
16024                pw.println("  -d: include dalvik details.");
16025                pw.println("  -c: dump in a compact machine-parseable representation.");
16026                pw.println("  -s: dump only summary of application memory usage.");
16027                pw.println("  -S: dump also SwapPss.");
16028                pw.println("  --oom: only show processes organized by oom adj.");
16029                pw.println("  --local: only collect details locally, don't call process.");
16030                pw.println("  --package: interpret process arg as package, dumping all");
16031                pw.println("             processes that have loaded that package.");
16032                pw.println("  --checkin: dump data for a checkin");
16033                pw.println("If [process] is specified it can be the name or ");
16034                pw.println("pid of a specific process to dump.");
16035                return;
16036            } else {
16037                pw.println("Unknown argument: " + opt + "; use -h for help");
16038            }
16039        }
16040
16041        long uptime = SystemClock.uptimeMillis();
16042        long realtime = SystemClock.elapsedRealtime();
16043        final long[] tmpLong = new long[1];
16044
16045        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16046        if (procs == null) {
16047            // No Java processes.  Maybe they want to print a native process.
16048            if (args != null && args.length > opti
16049                    && args[opti].charAt(0) != '-') {
16050                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16051                        = new ArrayList<ProcessCpuTracker.Stats>();
16052                updateCpuStatsNow();
16053                int findPid = -1;
16054                try {
16055                    findPid = Integer.parseInt(args[opti]);
16056                } catch (NumberFormatException e) {
16057                }
16058                synchronized (mProcessCpuTracker) {
16059                    final int N = mProcessCpuTracker.countStats();
16060                    for (int i=0; i<N; i++) {
16061                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16062                        if (st.pid == findPid || (st.baseName != null
16063                                && st.baseName.equals(args[opti]))) {
16064                            nativeProcs.add(st);
16065                        }
16066                    }
16067                }
16068                if (nativeProcs.size() > 0) {
16069                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16070                            isCompact);
16071                    Debug.MemoryInfo mi = null;
16072                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16073                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16074                        final int pid = r.pid;
16075                        if (!isCheckinRequest && dumpDetails) {
16076                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16077                        }
16078                        if (mi == null) {
16079                            mi = new Debug.MemoryInfo();
16080                        }
16081                        if (dumpDetails || (!brief && !oomOnly)) {
16082                            Debug.getMemoryInfo(pid, mi);
16083                        } else {
16084                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16085                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16086                        }
16087                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16088                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16089                        if (isCheckinRequest) {
16090                            pw.println();
16091                        }
16092                    }
16093                    return;
16094                }
16095            }
16096            pw.println("No process found for: " + args[opti]);
16097            return;
16098        }
16099
16100        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16101            dumpDetails = true;
16102        }
16103
16104        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16105
16106        String[] innerArgs = new String[args.length-opti];
16107        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16108
16109        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16110        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16111        long nativePss = 0;
16112        long nativeSwapPss = 0;
16113        long dalvikPss = 0;
16114        long dalvikSwapPss = 0;
16115        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16116                EmptyArray.LONG;
16117        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16118                EmptyArray.LONG;
16119        long otherPss = 0;
16120        long otherSwapPss = 0;
16121        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16122        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16123
16124        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16125        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16126        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16127                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16128
16129        long totalPss = 0;
16130        long totalSwapPss = 0;
16131        long cachedPss = 0;
16132        long cachedSwapPss = 0;
16133        boolean hasSwapPss = false;
16134
16135        Debug.MemoryInfo mi = null;
16136        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16137            final ProcessRecord r = procs.get(i);
16138            final IApplicationThread thread;
16139            final int pid;
16140            final int oomAdj;
16141            final boolean hasActivities;
16142            synchronized (this) {
16143                thread = r.thread;
16144                pid = r.pid;
16145                oomAdj = r.getSetAdjWithServices();
16146                hasActivities = r.activities.size() > 0;
16147            }
16148            if (thread != null) {
16149                if (!isCheckinRequest && dumpDetails) {
16150                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16151                }
16152                if (mi == null) {
16153                    mi = new Debug.MemoryInfo();
16154                }
16155                if (dumpDetails || (!brief && !oomOnly)) {
16156                    Debug.getMemoryInfo(pid, mi);
16157                    hasSwapPss = mi.hasSwappedOutPss;
16158                } else {
16159                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16160                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16161                }
16162                if (dumpDetails) {
16163                    if (localOnly) {
16164                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16165                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16166                        if (isCheckinRequest) {
16167                            pw.println();
16168                        }
16169                    } else {
16170                        try {
16171                            pw.flush();
16172                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16173                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16174                        } catch (RemoteException e) {
16175                            if (!isCheckinRequest) {
16176                                pw.println("Got RemoteException!");
16177                                pw.flush();
16178                            }
16179                        }
16180                    }
16181                }
16182
16183                final long myTotalPss = mi.getTotalPss();
16184                final long myTotalUss = mi.getTotalUss();
16185                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16186
16187                synchronized (this) {
16188                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16189                        // Record this for posterity if the process has been stable.
16190                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16191                    }
16192                }
16193
16194                if (!isCheckinRequest && mi != null) {
16195                    totalPss += myTotalPss;
16196                    totalSwapPss += myTotalSwapPss;
16197                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16198                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16199                            myTotalSwapPss, pid, hasActivities);
16200                    procMems.add(pssItem);
16201                    procMemsMap.put(pid, pssItem);
16202
16203                    nativePss += mi.nativePss;
16204                    nativeSwapPss += mi.nativeSwappedOutPss;
16205                    dalvikPss += mi.dalvikPss;
16206                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16207                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16208                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16209                        dalvikSubitemSwapPss[j] +=
16210                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16211                    }
16212                    otherPss += mi.otherPss;
16213                    otherSwapPss += mi.otherSwappedOutPss;
16214                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16215                        long mem = mi.getOtherPss(j);
16216                        miscPss[j] += mem;
16217                        otherPss -= mem;
16218                        mem = mi.getOtherSwappedOutPss(j);
16219                        miscSwapPss[j] += mem;
16220                        otherSwapPss -= mem;
16221                    }
16222
16223                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16224                        cachedPss += myTotalPss;
16225                        cachedSwapPss += myTotalSwapPss;
16226                    }
16227
16228                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16229                        if (oomIndex == (oomPss.length - 1)
16230                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16231                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16232                            oomPss[oomIndex] += myTotalPss;
16233                            oomSwapPss[oomIndex] += myTotalSwapPss;
16234                            if (oomProcs[oomIndex] == null) {
16235                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16236                            }
16237                            oomProcs[oomIndex].add(pssItem);
16238                            break;
16239                        }
16240                    }
16241                }
16242            }
16243        }
16244
16245        long nativeProcTotalPss = 0;
16246
16247        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16248            // If we are showing aggregations, also look for native processes to
16249            // include so that our aggregations are more accurate.
16250            updateCpuStatsNow();
16251            mi = null;
16252            synchronized (mProcessCpuTracker) {
16253                final int N = mProcessCpuTracker.countStats();
16254                for (int i=0; i<N; i++) {
16255                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16256                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16257                        if (mi == null) {
16258                            mi = new Debug.MemoryInfo();
16259                        }
16260                        if (!brief && !oomOnly) {
16261                            Debug.getMemoryInfo(st.pid, mi);
16262                        } else {
16263                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16264                            mi.nativePrivateDirty = (int)tmpLong[0];
16265                        }
16266
16267                        final long myTotalPss = mi.getTotalPss();
16268                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16269                        totalPss += myTotalPss;
16270                        nativeProcTotalPss += myTotalPss;
16271
16272                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16273                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16274                        procMems.add(pssItem);
16275
16276                        nativePss += mi.nativePss;
16277                        nativeSwapPss += mi.nativeSwappedOutPss;
16278                        dalvikPss += mi.dalvikPss;
16279                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16280                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16281                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16282                            dalvikSubitemSwapPss[j] +=
16283                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16284                        }
16285                        otherPss += mi.otherPss;
16286                        otherSwapPss += mi.otherSwappedOutPss;
16287                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16288                            long mem = mi.getOtherPss(j);
16289                            miscPss[j] += mem;
16290                            otherPss -= mem;
16291                            mem = mi.getOtherSwappedOutPss(j);
16292                            miscSwapPss[j] += mem;
16293                            otherSwapPss -= mem;
16294                        }
16295                        oomPss[0] += myTotalPss;
16296                        oomSwapPss[0] += myTotalSwapPss;
16297                        if (oomProcs[0] == null) {
16298                            oomProcs[0] = new ArrayList<MemItem>();
16299                        }
16300                        oomProcs[0].add(pssItem);
16301                    }
16302                }
16303            }
16304
16305            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16306
16307            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16308            final MemItem dalvikItem =
16309                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16310            if (dalvikSubitemPss.length > 0) {
16311                dalvikItem.subitems = new ArrayList<MemItem>();
16312                for (int j=0; j<dalvikSubitemPss.length; j++) {
16313                    final String name = Debug.MemoryInfo.getOtherLabel(
16314                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16315                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16316                                    dalvikSubitemSwapPss[j], j));
16317                }
16318            }
16319            catMems.add(dalvikItem);
16320            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16321            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16322                String label = Debug.MemoryInfo.getOtherLabel(j);
16323                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16324            }
16325
16326            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16327            for (int j=0; j<oomPss.length; j++) {
16328                if (oomPss[j] != 0) {
16329                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16330                            : DUMP_MEM_OOM_LABEL[j];
16331                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16332                            DUMP_MEM_OOM_ADJ[j]);
16333                    item.subitems = oomProcs[j];
16334                    oomMems.add(item);
16335                }
16336            }
16337
16338            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16339            if (!brief && !oomOnly && !isCompact) {
16340                pw.println();
16341                pw.println("Total PSS by process:");
16342                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16343                pw.println();
16344            }
16345            if (!isCompact) {
16346                pw.println("Total PSS by OOM adjustment:");
16347            }
16348            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16349            if (!brief && !oomOnly) {
16350                PrintWriter out = categoryPw != null ? categoryPw : pw;
16351                if (!isCompact) {
16352                    out.println();
16353                    out.println("Total PSS by category:");
16354                }
16355                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16356            }
16357            if (!isCompact) {
16358                pw.println();
16359            }
16360            MemInfoReader memInfo = new MemInfoReader();
16361            memInfo.readMemInfo();
16362            if (nativeProcTotalPss > 0) {
16363                synchronized (this) {
16364                    final long cachedKb = memInfo.getCachedSizeKb();
16365                    final long freeKb = memInfo.getFreeSizeKb();
16366                    final long zramKb = memInfo.getZramTotalSizeKb();
16367                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16368                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16369                            kernelKb*1024, nativeProcTotalPss*1024);
16370                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16371                            nativeProcTotalPss);
16372                }
16373            }
16374            if (!brief) {
16375                if (!isCompact) {
16376                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16377                    pw.print(" (status ");
16378                    switch (mLastMemoryLevel) {
16379                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16380                            pw.println("normal)");
16381                            break;
16382                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16383                            pw.println("moderate)");
16384                            break;
16385                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16386                            pw.println("low)");
16387                            break;
16388                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16389                            pw.println("critical)");
16390                            break;
16391                        default:
16392                            pw.print(mLastMemoryLevel);
16393                            pw.println(")");
16394                            break;
16395                    }
16396                    pw.print(" Free RAM: ");
16397                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16398                            + memInfo.getFreeSizeKb()));
16399                    pw.print(" (");
16400                    pw.print(stringifyKBSize(cachedPss));
16401                    pw.print(" cached pss + ");
16402                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16403                    pw.print(" cached kernel + ");
16404                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16405                    pw.println(" free)");
16406                } else {
16407                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16408                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16409                            + memInfo.getFreeSizeKb()); pw.print(",");
16410                    pw.println(totalPss - cachedPss);
16411                }
16412            }
16413            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16414                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16415                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16416            if (!isCompact) {
16417                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16418                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16419                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16420                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16421                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16422            } else {
16423                pw.print("lostram,"); pw.println(lostRAM);
16424            }
16425            if (!brief) {
16426                if (memInfo.getZramTotalSizeKb() != 0) {
16427                    if (!isCompact) {
16428                        pw.print("     ZRAM: ");
16429                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16430                                pw.print(" physical used for ");
16431                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16432                                        - memInfo.getSwapFreeSizeKb()));
16433                                pw.print(" in swap (");
16434                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16435                                pw.println(" total swap)");
16436                    } else {
16437                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16438                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16439                                pw.println(memInfo.getSwapFreeSizeKb());
16440                    }
16441                }
16442                final long[] ksm = getKsmInfo();
16443                if (!isCompact) {
16444                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16445                            || ksm[KSM_VOLATILE] != 0) {
16446                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16447                                pw.print(" saved from shared ");
16448                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16449                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16450                                pw.print(" unshared; ");
16451                                pw.print(stringifyKBSize(
16452                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16453                    }
16454                    pw.print("   Tuning: ");
16455                    pw.print(ActivityManager.staticGetMemoryClass());
16456                    pw.print(" (large ");
16457                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16458                    pw.print("), oom ");
16459                    pw.print(stringifySize(
16460                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16461                    pw.print(", restore limit ");
16462                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16463                    if (ActivityManager.isLowRamDeviceStatic()) {
16464                        pw.print(" (low-ram)");
16465                    }
16466                    if (ActivityManager.isHighEndGfx()) {
16467                        pw.print(" (high-end-gfx)");
16468                    }
16469                    pw.println();
16470                } else {
16471                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16472                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16473                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16474                    pw.print("tuning,");
16475                    pw.print(ActivityManager.staticGetMemoryClass());
16476                    pw.print(',');
16477                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16478                    pw.print(',');
16479                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16480                    if (ActivityManager.isLowRamDeviceStatic()) {
16481                        pw.print(",low-ram");
16482                    }
16483                    if (ActivityManager.isHighEndGfx()) {
16484                        pw.print(",high-end-gfx");
16485                    }
16486                    pw.println();
16487                }
16488            }
16489        }
16490    }
16491
16492    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16493            long memtrack, String name) {
16494        sb.append("  ");
16495        sb.append(ProcessList.makeOomAdjString(oomAdj));
16496        sb.append(' ');
16497        sb.append(ProcessList.makeProcStateString(procState));
16498        sb.append(' ');
16499        ProcessList.appendRamKb(sb, pss);
16500        sb.append(": ");
16501        sb.append(name);
16502        if (memtrack > 0) {
16503            sb.append(" (");
16504            sb.append(stringifyKBSize(memtrack));
16505            sb.append(" memtrack)");
16506        }
16507    }
16508
16509    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16510        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16511        sb.append(" (pid ");
16512        sb.append(mi.pid);
16513        sb.append(") ");
16514        sb.append(mi.adjType);
16515        sb.append('\n');
16516        if (mi.adjReason != null) {
16517            sb.append("                      ");
16518            sb.append(mi.adjReason);
16519            sb.append('\n');
16520        }
16521    }
16522
16523    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16524        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16525        for (int i=0, N=memInfos.size(); i<N; i++) {
16526            ProcessMemInfo mi = memInfos.get(i);
16527            infoMap.put(mi.pid, mi);
16528        }
16529        updateCpuStatsNow();
16530        long[] memtrackTmp = new long[1];
16531        final List<ProcessCpuTracker.Stats> stats;
16532        // Get a list of Stats that have vsize > 0
16533        synchronized (mProcessCpuTracker) {
16534            stats = mProcessCpuTracker.getStats((st) -> {
16535                return st.vsize > 0;
16536            });
16537        }
16538        final int statsCount = stats.size();
16539        for (int i = 0; i < statsCount; i++) {
16540            ProcessCpuTracker.Stats st = stats.get(i);
16541            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16542            if (pss > 0) {
16543                if (infoMap.indexOfKey(st.pid) < 0) {
16544                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16545                            ProcessList.NATIVE_ADJ, -1, "native", null);
16546                    mi.pss = pss;
16547                    mi.memtrack = memtrackTmp[0];
16548                    memInfos.add(mi);
16549                }
16550            }
16551        }
16552
16553        long totalPss = 0;
16554        long totalMemtrack = 0;
16555        for (int i=0, N=memInfos.size(); i<N; i++) {
16556            ProcessMemInfo mi = memInfos.get(i);
16557            if (mi.pss == 0) {
16558                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16559                mi.memtrack = memtrackTmp[0];
16560            }
16561            totalPss += mi.pss;
16562            totalMemtrack += mi.memtrack;
16563        }
16564        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16565            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16566                if (lhs.oomAdj != rhs.oomAdj) {
16567                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16568                }
16569                if (lhs.pss != rhs.pss) {
16570                    return lhs.pss < rhs.pss ? 1 : -1;
16571                }
16572                return 0;
16573            }
16574        });
16575
16576        StringBuilder tag = new StringBuilder(128);
16577        StringBuilder stack = new StringBuilder(128);
16578        tag.append("Low on memory -- ");
16579        appendMemBucket(tag, totalPss, "total", false);
16580        appendMemBucket(stack, totalPss, "total", true);
16581
16582        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16583        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16584        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16585
16586        boolean firstLine = true;
16587        int lastOomAdj = Integer.MIN_VALUE;
16588        long extraNativeRam = 0;
16589        long extraNativeMemtrack = 0;
16590        long cachedPss = 0;
16591        for (int i=0, N=memInfos.size(); i<N; i++) {
16592            ProcessMemInfo mi = memInfos.get(i);
16593
16594            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16595                cachedPss += mi.pss;
16596            }
16597
16598            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16599                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16600                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16601                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16602                if (lastOomAdj != mi.oomAdj) {
16603                    lastOomAdj = mi.oomAdj;
16604                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16605                        tag.append(" / ");
16606                    }
16607                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16608                        if (firstLine) {
16609                            stack.append(":");
16610                            firstLine = false;
16611                        }
16612                        stack.append("\n\t at ");
16613                    } else {
16614                        stack.append("$");
16615                    }
16616                } else {
16617                    tag.append(" ");
16618                    stack.append("$");
16619                }
16620                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16621                    appendMemBucket(tag, mi.pss, mi.name, false);
16622                }
16623                appendMemBucket(stack, mi.pss, mi.name, true);
16624                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16625                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16626                    stack.append("(");
16627                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16628                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16629                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16630                            stack.append(":");
16631                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16632                        }
16633                    }
16634                    stack.append(")");
16635                }
16636            }
16637
16638            appendMemInfo(fullNativeBuilder, mi);
16639            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16640                // The short form only has native processes that are >= 512K.
16641                if (mi.pss >= 512) {
16642                    appendMemInfo(shortNativeBuilder, mi);
16643                } else {
16644                    extraNativeRam += mi.pss;
16645                    extraNativeMemtrack += mi.memtrack;
16646                }
16647            } else {
16648                // Short form has all other details, but if we have collected RAM
16649                // from smaller native processes let's dump a summary of that.
16650                if (extraNativeRam > 0) {
16651                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16652                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16653                    shortNativeBuilder.append('\n');
16654                    extraNativeRam = 0;
16655                }
16656                appendMemInfo(fullJavaBuilder, mi);
16657            }
16658        }
16659
16660        fullJavaBuilder.append("           ");
16661        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16662        fullJavaBuilder.append(": TOTAL");
16663        if (totalMemtrack > 0) {
16664            fullJavaBuilder.append(" (");
16665            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16666            fullJavaBuilder.append(" memtrack)");
16667        } else {
16668        }
16669        fullJavaBuilder.append("\n");
16670
16671        MemInfoReader memInfo = new MemInfoReader();
16672        memInfo.readMemInfo();
16673        final long[] infos = memInfo.getRawInfo();
16674
16675        StringBuilder memInfoBuilder = new StringBuilder(1024);
16676        Debug.getMemInfo(infos);
16677        memInfoBuilder.append("  MemInfo: ");
16678        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16679        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16680        memInfoBuilder.append(stringifyKBSize(
16681                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16682        memInfoBuilder.append(stringifyKBSize(
16683                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16684        memInfoBuilder.append(stringifyKBSize(
16685                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16686        memInfoBuilder.append("           ");
16687        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16688        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16689        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16690        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16691        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16692            memInfoBuilder.append("  ZRAM: ");
16693            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16694            memInfoBuilder.append(" RAM, ");
16695            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16696            memInfoBuilder.append(" swap total, ");
16697            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16698            memInfoBuilder.append(" swap free\n");
16699        }
16700        final long[] ksm = getKsmInfo();
16701        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16702                || ksm[KSM_VOLATILE] != 0) {
16703            memInfoBuilder.append("  KSM: ");
16704            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16705            memInfoBuilder.append(" saved from shared ");
16706            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16707            memInfoBuilder.append("\n       ");
16708            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16709            memInfoBuilder.append(" unshared; ");
16710            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16711            memInfoBuilder.append(" volatile\n");
16712        }
16713        memInfoBuilder.append("  Free RAM: ");
16714        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16715                + memInfo.getFreeSizeKb()));
16716        memInfoBuilder.append("\n");
16717        memInfoBuilder.append("  Used RAM: ");
16718        memInfoBuilder.append(stringifyKBSize(
16719                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16720        memInfoBuilder.append("\n");
16721        memInfoBuilder.append("  Lost RAM: ");
16722        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16723                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16724                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16725        memInfoBuilder.append("\n");
16726        Slog.i(TAG, "Low on memory:");
16727        Slog.i(TAG, shortNativeBuilder.toString());
16728        Slog.i(TAG, fullJavaBuilder.toString());
16729        Slog.i(TAG, memInfoBuilder.toString());
16730
16731        StringBuilder dropBuilder = new StringBuilder(1024);
16732        /*
16733        StringWriter oomSw = new StringWriter();
16734        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16735        StringWriter catSw = new StringWriter();
16736        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16737        String[] emptyArgs = new String[] { };
16738        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16739        oomPw.flush();
16740        String oomString = oomSw.toString();
16741        */
16742        dropBuilder.append("Low on memory:");
16743        dropBuilder.append(stack);
16744        dropBuilder.append('\n');
16745        dropBuilder.append(fullNativeBuilder);
16746        dropBuilder.append(fullJavaBuilder);
16747        dropBuilder.append('\n');
16748        dropBuilder.append(memInfoBuilder);
16749        dropBuilder.append('\n');
16750        /*
16751        dropBuilder.append(oomString);
16752        dropBuilder.append('\n');
16753        */
16754        StringWriter catSw = new StringWriter();
16755        synchronized (ActivityManagerService.this) {
16756            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16757            String[] emptyArgs = new String[] { };
16758            catPw.println();
16759            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16760            catPw.println();
16761            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16762                    false, null).dumpLocked();
16763            catPw.println();
16764            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16765            catPw.flush();
16766        }
16767        dropBuilder.append(catSw.toString());
16768        addErrorToDropBox("lowmem", null, "system_server", null,
16769                null, tag.toString(), dropBuilder.toString(), null, null);
16770        //Slog.i(TAG, "Sent to dropbox:");
16771        //Slog.i(TAG, dropBuilder.toString());
16772        synchronized (ActivityManagerService.this) {
16773            long now = SystemClock.uptimeMillis();
16774            if (mLastMemUsageReportTime < now) {
16775                mLastMemUsageReportTime = now;
16776            }
16777        }
16778    }
16779
16780    /**
16781     * Searches array of arguments for the specified string
16782     * @param args array of argument strings
16783     * @param value value to search for
16784     * @return true if the value is contained in the array
16785     */
16786    private static boolean scanArgs(String[] args, String value) {
16787        if (args != null) {
16788            for (String arg : args) {
16789                if (value.equals(arg)) {
16790                    return true;
16791                }
16792            }
16793        }
16794        return false;
16795    }
16796
16797    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16798            ContentProviderRecord cpr, boolean always) {
16799        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16800
16801        if (!inLaunching || always) {
16802            synchronized (cpr) {
16803                cpr.launchingApp = null;
16804                cpr.notifyAll();
16805            }
16806            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16807            String names[] = cpr.info.authority.split(";");
16808            for (int j = 0; j < names.length; j++) {
16809                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16810            }
16811        }
16812
16813        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16814            ContentProviderConnection conn = cpr.connections.get(i);
16815            if (conn.waiting) {
16816                // If this connection is waiting for the provider, then we don't
16817                // need to mess with its process unless we are always removing
16818                // or for some reason the provider is not currently launching.
16819                if (inLaunching && !always) {
16820                    continue;
16821                }
16822            }
16823            ProcessRecord capp = conn.client;
16824            conn.dead = true;
16825            if (conn.stableCount > 0) {
16826                if (!capp.persistent && capp.thread != null
16827                        && capp.pid != 0
16828                        && capp.pid != MY_PID) {
16829                    capp.kill("depends on provider "
16830                            + cpr.name.flattenToShortString()
16831                            + " in dying proc " + (proc != null ? proc.processName : "??")
16832                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16833                }
16834            } else if (capp.thread != null && conn.provider.provider != null) {
16835                try {
16836                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16837                } catch (RemoteException e) {
16838                }
16839                // In the protocol here, we don't expect the client to correctly
16840                // clean up this connection, we'll just remove it.
16841                cpr.connections.remove(i);
16842                if (conn.client.conProviders.remove(conn)) {
16843                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16844                }
16845            }
16846        }
16847
16848        if (inLaunching && always) {
16849            mLaunchingProviders.remove(cpr);
16850        }
16851        return inLaunching;
16852    }
16853
16854    /**
16855     * Main code for cleaning up a process when it has gone away.  This is
16856     * called both as a result of the process dying, or directly when stopping
16857     * a process when running in single process mode.
16858     *
16859     * @return Returns true if the given process has been restarted, so the
16860     * app that was passed in must remain on the process lists.
16861     */
16862    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16863            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16864        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16865        if (index >= 0) {
16866            removeLruProcessLocked(app);
16867            ProcessList.remove(app.pid);
16868        }
16869
16870        mProcessesToGc.remove(app);
16871        mPendingPssProcesses.remove(app);
16872
16873        // Dismiss any open dialogs.
16874        if (app.crashDialog != null && !app.forceCrashReport) {
16875            app.crashDialog.dismiss();
16876            app.crashDialog = null;
16877        }
16878        if (app.anrDialog != null) {
16879            app.anrDialog.dismiss();
16880            app.anrDialog = null;
16881        }
16882        if (app.waitDialog != null) {
16883            app.waitDialog.dismiss();
16884            app.waitDialog = null;
16885        }
16886
16887        app.crashing = false;
16888        app.notResponding = false;
16889
16890        app.resetPackageList(mProcessStats);
16891        app.unlinkDeathRecipient();
16892        app.makeInactive(mProcessStats);
16893        app.waitingToKill = null;
16894        app.forcingToForeground = null;
16895        updateProcessForegroundLocked(app, false, false);
16896        app.foregroundActivities = false;
16897        app.hasShownUi = false;
16898        app.treatLikeActivity = false;
16899        app.hasAboveClient = false;
16900        app.hasClientActivities = false;
16901
16902        mServices.killServicesLocked(app, allowRestart);
16903
16904        boolean restart = false;
16905
16906        // Remove published content providers.
16907        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16908            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16909            final boolean always = app.bad || !allowRestart;
16910            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16911            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16912                // We left the provider in the launching list, need to
16913                // restart it.
16914                restart = true;
16915            }
16916
16917            cpr.provider = null;
16918            cpr.proc = null;
16919        }
16920        app.pubProviders.clear();
16921
16922        // Take care of any launching providers waiting for this process.
16923        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16924            restart = true;
16925        }
16926
16927        // Unregister from connected content providers.
16928        if (!app.conProviders.isEmpty()) {
16929            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16930                ContentProviderConnection conn = app.conProviders.get(i);
16931                conn.provider.connections.remove(conn);
16932                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16933                        conn.provider.name);
16934            }
16935            app.conProviders.clear();
16936        }
16937
16938        // At this point there may be remaining entries in mLaunchingProviders
16939        // where we were the only one waiting, so they are no longer of use.
16940        // Look for these and clean up if found.
16941        // XXX Commented out for now.  Trying to figure out a way to reproduce
16942        // the actual situation to identify what is actually going on.
16943        if (false) {
16944            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16945                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16946                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16947                    synchronized (cpr) {
16948                        cpr.launchingApp = null;
16949                        cpr.notifyAll();
16950                    }
16951                }
16952            }
16953        }
16954
16955        skipCurrentReceiverLocked(app);
16956
16957        // Unregister any receivers.
16958        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16959            removeReceiverLocked(app.receivers.valueAt(i));
16960        }
16961        app.receivers.clear();
16962
16963        // If the app is undergoing backup, tell the backup manager about it
16964        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16965            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16966                    + mBackupTarget.appInfo + " died during backup");
16967            try {
16968                IBackupManager bm = IBackupManager.Stub.asInterface(
16969                        ServiceManager.getService(Context.BACKUP_SERVICE));
16970                bm.agentDisconnected(app.info.packageName);
16971            } catch (RemoteException e) {
16972                // can't happen; backup manager is local
16973            }
16974        }
16975
16976        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16977            ProcessChangeItem item = mPendingProcessChanges.get(i);
16978            if (item.pid == app.pid) {
16979                mPendingProcessChanges.remove(i);
16980                mAvailProcessChanges.add(item);
16981            }
16982        }
16983        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16984                null).sendToTarget();
16985
16986        // If the caller is restarting this app, then leave it in its
16987        // current lists and let the caller take care of it.
16988        if (restarting) {
16989            return false;
16990        }
16991
16992        if (!app.persistent || app.isolated) {
16993            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16994                    "Removing non-persistent process during cleanup: " + app);
16995            if (!replacingPid) {
16996                removeProcessNameLocked(app.processName, app.uid);
16997            }
16998            if (mHeavyWeightProcess == app) {
16999                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17000                        mHeavyWeightProcess.userId, 0));
17001                mHeavyWeightProcess = null;
17002            }
17003        } else if (!app.removed) {
17004            // This app is persistent, so we need to keep its record around.
17005            // If it is not already on the pending app list, add it there
17006            // and start a new process for it.
17007            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17008                mPersistentStartingProcesses.add(app);
17009                restart = true;
17010            }
17011        }
17012        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17013                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17014        mProcessesOnHold.remove(app);
17015
17016        if (app == mHomeProcess) {
17017            mHomeProcess = null;
17018        }
17019        if (app == mPreviousProcess) {
17020            mPreviousProcess = null;
17021        }
17022
17023        if (restart && !app.isolated) {
17024            // We have components that still need to be running in the
17025            // process, so re-launch it.
17026            if (index < 0) {
17027                ProcessList.remove(app.pid);
17028            }
17029            addProcessNameLocked(app);
17030            startProcessLocked(app, "restart", app.processName);
17031            return true;
17032        } else if (app.pid > 0 && app.pid != MY_PID) {
17033            // Goodbye!
17034            boolean removed;
17035            synchronized (mPidsSelfLocked) {
17036                mPidsSelfLocked.remove(app.pid);
17037                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17038            }
17039            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17040            if (app.isolated) {
17041                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17042            }
17043            app.setPid(0);
17044        }
17045        return false;
17046    }
17047
17048    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17049        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17050            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17051            if (cpr.launchingApp == app) {
17052                return true;
17053            }
17054        }
17055        return false;
17056    }
17057
17058    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17059        // Look through the content providers we are waiting to have launched,
17060        // and if any run in this process then either schedule a restart of
17061        // the process or kill the client waiting for it if this process has
17062        // gone bad.
17063        boolean restart = false;
17064        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17065            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17066            if (cpr.launchingApp == app) {
17067                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17068                    restart = true;
17069                } else {
17070                    removeDyingProviderLocked(app, cpr, true);
17071                }
17072            }
17073        }
17074        return restart;
17075    }
17076
17077    // =========================================================
17078    // SERVICES
17079    // =========================================================
17080
17081    @Override
17082    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17083            int flags) {
17084        enforceNotIsolatedCaller("getServices");
17085        synchronized (this) {
17086            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17087        }
17088    }
17089
17090    @Override
17091    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17092        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17093        synchronized (this) {
17094            return mServices.getRunningServiceControlPanelLocked(name);
17095        }
17096    }
17097
17098    @Override
17099    public ComponentName startService(IApplicationThread caller, Intent service,
17100            String resolvedType, String callingPackage, int userId)
17101            throws TransactionTooLargeException {
17102        enforceNotIsolatedCaller("startService");
17103        // Refuse possible leaked file descriptors
17104        if (service != null && service.hasFileDescriptors() == true) {
17105            throw new IllegalArgumentException("File descriptors passed in Intent");
17106        }
17107
17108        if (callingPackage == null) {
17109            throw new IllegalArgumentException("callingPackage cannot be null");
17110        }
17111
17112        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17113                "startService: " + service + " type=" + resolvedType);
17114        synchronized(this) {
17115            final int callingPid = Binder.getCallingPid();
17116            final int callingUid = Binder.getCallingUid();
17117            final long origId = Binder.clearCallingIdentity();
17118            ComponentName res = mServices.startServiceLocked(caller, service,
17119                    resolvedType, callingPid, callingUid, callingPackage, userId);
17120            Binder.restoreCallingIdentity(origId);
17121            return res;
17122        }
17123    }
17124
17125    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17126            String callingPackage, int userId)
17127            throws TransactionTooLargeException {
17128        synchronized(this) {
17129            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17130                    "startServiceInPackage: " + service + " type=" + resolvedType);
17131            final long origId = Binder.clearCallingIdentity();
17132            ComponentName res = mServices.startServiceLocked(null, service,
17133                    resolvedType, -1, uid, callingPackage, userId);
17134            Binder.restoreCallingIdentity(origId);
17135            return res;
17136        }
17137    }
17138
17139    @Override
17140    public int stopService(IApplicationThread caller, Intent service,
17141            String resolvedType, int userId) {
17142        enforceNotIsolatedCaller("stopService");
17143        // Refuse possible leaked file descriptors
17144        if (service != null && service.hasFileDescriptors() == true) {
17145            throw new IllegalArgumentException("File descriptors passed in Intent");
17146        }
17147
17148        synchronized(this) {
17149            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17150        }
17151    }
17152
17153    @Override
17154    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17155        enforceNotIsolatedCaller("peekService");
17156        // Refuse possible leaked file descriptors
17157        if (service != null && service.hasFileDescriptors() == true) {
17158            throw new IllegalArgumentException("File descriptors passed in Intent");
17159        }
17160
17161        if (callingPackage == null) {
17162            throw new IllegalArgumentException("callingPackage cannot be null");
17163        }
17164
17165        synchronized(this) {
17166            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17167        }
17168    }
17169
17170    @Override
17171    public boolean stopServiceToken(ComponentName className, IBinder token,
17172            int startId) {
17173        synchronized(this) {
17174            return mServices.stopServiceTokenLocked(className, token, startId);
17175        }
17176    }
17177
17178    @Override
17179    public void setServiceForeground(ComponentName className, IBinder token,
17180            int id, Notification notification, int flags) {
17181        synchronized(this) {
17182            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17183        }
17184    }
17185
17186    @Override
17187    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17188            boolean requireFull, String name, String callerPackage) {
17189        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17190                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17191    }
17192
17193    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17194            String className, int flags) {
17195        boolean result = false;
17196        // For apps that don't have pre-defined UIDs, check for permission
17197        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17198            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17199                if (ActivityManager.checkUidPermission(
17200                        INTERACT_ACROSS_USERS,
17201                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17202                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17203                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17204                            + " requests FLAG_SINGLE_USER, but app does not hold "
17205                            + INTERACT_ACROSS_USERS;
17206                    Slog.w(TAG, msg);
17207                    throw new SecurityException(msg);
17208                }
17209                // Permission passed
17210                result = true;
17211            }
17212        } else if ("system".equals(componentProcessName)) {
17213            result = true;
17214        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17215            // Phone app and persistent apps are allowed to export singleuser providers.
17216            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17217                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17218        }
17219        if (DEBUG_MU) Slog.v(TAG_MU,
17220                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17221                + Integer.toHexString(flags) + ") = " + result);
17222        return result;
17223    }
17224
17225    /**
17226     * Checks to see if the caller is in the same app as the singleton
17227     * component, or the component is in a special app. It allows special apps
17228     * to export singleton components but prevents exporting singleton
17229     * components for regular apps.
17230     */
17231    boolean isValidSingletonCall(int callingUid, int componentUid) {
17232        int componentAppId = UserHandle.getAppId(componentUid);
17233        return UserHandle.isSameApp(callingUid, componentUid)
17234                || componentAppId == Process.SYSTEM_UID
17235                || componentAppId == Process.PHONE_UID
17236                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17237                        == PackageManager.PERMISSION_GRANTED;
17238    }
17239
17240    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17241            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17242            int userId) throws TransactionTooLargeException {
17243        enforceNotIsolatedCaller("bindService");
17244
17245        // Refuse possible leaked file descriptors
17246        if (service != null && service.hasFileDescriptors() == true) {
17247            throw new IllegalArgumentException("File descriptors passed in Intent");
17248        }
17249
17250        if (callingPackage == null) {
17251            throw new IllegalArgumentException("callingPackage cannot be null");
17252        }
17253
17254        synchronized(this) {
17255            return mServices.bindServiceLocked(caller, token, service,
17256                    resolvedType, connection, flags, callingPackage, userId);
17257        }
17258    }
17259
17260    public boolean unbindService(IServiceConnection connection) {
17261        synchronized (this) {
17262            return mServices.unbindServiceLocked(connection);
17263        }
17264    }
17265
17266    public void publishService(IBinder token, Intent intent, IBinder service) {
17267        // Refuse possible leaked file descriptors
17268        if (intent != null && intent.hasFileDescriptors() == true) {
17269            throw new IllegalArgumentException("File descriptors passed in Intent");
17270        }
17271
17272        synchronized(this) {
17273            if (!(token instanceof ServiceRecord)) {
17274                throw new IllegalArgumentException("Invalid service token");
17275            }
17276            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17277        }
17278    }
17279
17280    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17281        // Refuse possible leaked file descriptors
17282        if (intent != null && intent.hasFileDescriptors() == true) {
17283            throw new IllegalArgumentException("File descriptors passed in Intent");
17284        }
17285
17286        synchronized(this) {
17287            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17288        }
17289    }
17290
17291    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17292        synchronized(this) {
17293            if (!(token instanceof ServiceRecord)) {
17294                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17295                throw new IllegalArgumentException("Invalid service token");
17296            }
17297            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17298        }
17299    }
17300
17301    // =========================================================
17302    // BACKUP AND RESTORE
17303    // =========================================================
17304
17305    // Cause the target app to be launched if necessary and its backup agent
17306    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17307    // activity manager to announce its creation.
17308    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17309        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17310        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17311
17312        IPackageManager pm = AppGlobals.getPackageManager();
17313        ApplicationInfo app = null;
17314        try {
17315            app = pm.getApplicationInfo(packageName, 0, userId);
17316        } catch (RemoteException e) {
17317            // can't happen; package manager is process-local
17318        }
17319        if (app == null) {
17320            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17321            return false;
17322        }
17323
17324        synchronized(this) {
17325            // !!! TODO: currently no check here that we're already bound
17326            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17327            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17328            synchronized (stats) {
17329                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17330            }
17331
17332            // Backup agent is now in use, its package can't be stopped.
17333            try {
17334                AppGlobals.getPackageManager().setPackageStoppedState(
17335                        app.packageName, false, UserHandle.getUserId(app.uid));
17336            } catch (RemoteException e) {
17337            } catch (IllegalArgumentException e) {
17338                Slog.w(TAG, "Failed trying to unstop package "
17339                        + app.packageName + ": " + e);
17340            }
17341
17342            BackupRecord r = new BackupRecord(ss, app, backupMode);
17343            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17344                    ? new ComponentName(app.packageName, app.backupAgentName)
17345                    : new ComponentName("android", "FullBackupAgent");
17346            // startProcessLocked() returns existing proc's record if it's already running
17347            ProcessRecord proc = startProcessLocked(app.processName, app,
17348                    false, 0, "backup", hostingName, false, false, false);
17349            if (proc == null) {
17350                Slog.e(TAG, "Unable to start backup agent process " + r);
17351                return false;
17352            }
17353
17354            // If the app is a regular app (uid >= 10000) and not the system server or phone
17355            // process, etc, then mark it as being in full backup so that certain calls to the
17356            // process can be blocked. This is not reset to false anywhere because we kill the
17357            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17358            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17359                proc.inFullBackup = true;
17360            }
17361            r.app = proc;
17362            mBackupTarget = r;
17363            mBackupAppName = app.packageName;
17364
17365            // Try not to kill the process during backup
17366            updateOomAdjLocked(proc);
17367
17368            // If the process is already attached, schedule the creation of the backup agent now.
17369            // If it is not yet live, this will be done when it attaches to the framework.
17370            if (proc.thread != null) {
17371                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17372                try {
17373                    proc.thread.scheduleCreateBackupAgent(app,
17374                            compatibilityInfoForPackageLocked(app), backupMode);
17375                } catch (RemoteException e) {
17376                    // Will time out on the backup manager side
17377                }
17378            } else {
17379                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17380            }
17381            // Invariants: at this point, the target app process exists and the application
17382            // is either already running or in the process of coming up.  mBackupTarget and
17383            // mBackupAppName describe the app, so that when it binds back to the AM we
17384            // know that it's scheduled for a backup-agent operation.
17385        }
17386
17387        return true;
17388    }
17389
17390    @Override
17391    public void clearPendingBackup() {
17392        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17393        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17394
17395        synchronized (this) {
17396            mBackupTarget = null;
17397            mBackupAppName = null;
17398        }
17399    }
17400
17401    // A backup agent has just come up
17402    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17403        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17404                + " = " + agent);
17405
17406        synchronized(this) {
17407            if (!agentPackageName.equals(mBackupAppName)) {
17408                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17409                return;
17410            }
17411        }
17412
17413        long oldIdent = Binder.clearCallingIdentity();
17414        try {
17415            IBackupManager bm = IBackupManager.Stub.asInterface(
17416                    ServiceManager.getService(Context.BACKUP_SERVICE));
17417            bm.agentConnected(agentPackageName, agent);
17418        } catch (RemoteException e) {
17419            // can't happen; the backup manager service is local
17420        } catch (Exception e) {
17421            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17422            e.printStackTrace();
17423        } finally {
17424            Binder.restoreCallingIdentity(oldIdent);
17425        }
17426    }
17427
17428    // done with this agent
17429    public void unbindBackupAgent(ApplicationInfo appInfo) {
17430        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17431        if (appInfo == null) {
17432            Slog.w(TAG, "unbind backup agent for null app");
17433            return;
17434        }
17435
17436        synchronized(this) {
17437            try {
17438                if (mBackupAppName == null) {
17439                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17440                    return;
17441                }
17442
17443                if (!mBackupAppName.equals(appInfo.packageName)) {
17444                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17445                    return;
17446                }
17447
17448                // Not backing this app up any more; reset its OOM adjustment
17449                final ProcessRecord proc = mBackupTarget.app;
17450                updateOomAdjLocked(proc);
17451
17452                // If the app crashed during backup, 'thread' will be null here
17453                if (proc.thread != null) {
17454                    try {
17455                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17456                                compatibilityInfoForPackageLocked(appInfo));
17457                    } catch (Exception e) {
17458                        Slog.e(TAG, "Exception when unbinding backup agent:");
17459                        e.printStackTrace();
17460                    }
17461                }
17462            } finally {
17463                mBackupTarget = null;
17464                mBackupAppName = null;
17465            }
17466        }
17467    }
17468    // =========================================================
17469    // BROADCASTS
17470    // =========================================================
17471
17472    boolean isPendingBroadcastProcessLocked(int pid) {
17473        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17474                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17475    }
17476
17477    void skipPendingBroadcastLocked(int pid) {
17478            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17479            for (BroadcastQueue queue : mBroadcastQueues) {
17480                queue.skipPendingBroadcastLocked(pid);
17481            }
17482    }
17483
17484    // The app just attached; send any pending broadcasts that it should receive
17485    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17486        boolean didSomething = false;
17487        for (BroadcastQueue queue : mBroadcastQueues) {
17488            didSomething |= queue.sendPendingBroadcastsLocked(app);
17489        }
17490        return didSomething;
17491    }
17492
17493    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17494            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17495        enforceNotIsolatedCaller("registerReceiver");
17496        ArrayList<Intent> stickyIntents = null;
17497        ProcessRecord callerApp = null;
17498        int callingUid;
17499        int callingPid;
17500        synchronized(this) {
17501            if (caller != null) {
17502                callerApp = getRecordForAppLocked(caller);
17503                if (callerApp == null) {
17504                    throw new SecurityException(
17505                            "Unable to find app for caller " + caller
17506                            + " (pid=" + Binder.getCallingPid()
17507                            + ") when registering receiver " + receiver);
17508                }
17509                if (callerApp.info.uid != Process.SYSTEM_UID &&
17510                        !callerApp.pkgList.containsKey(callerPackage) &&
17511                        !"android".equals(callerPackage)) {
17512                    throw new SecurityException("Given caller package " + callerPackage
17513                            + " is not running in process " + callerApp);
17514                }
17515                callingUid = callerApp.info.uid;
17516                callingPid = callerApp.pid;
17517            } else {
17518                callerPackage = null;
17519                callingUid = Binder.getCallingUid();
17520                callingPid = Binder.getCallingPid();
17521            }
17522
17523            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17524                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17525
17526            Iterator<String> actions = filter.actionsIterator();
17527            if (actions == null) {
17528                ArrayList<String> noAction = new ArrayList<String>(1);
17529                noAction.add(null);
17530                actions = noAction.iterator();
17531            }
17532
17533            // Collect stickies of users
17534            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17535            while (actions.hasNext()) {
17536                String action = actions.next();
17537                for (int id : userIds) {
17538                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17539                    if (stickies != null) {
17540                        ArrayList<Intent> intents = stickies.get(action);
17541                        if (intents != null) {
17542                            if (stickyIntents == null) {
17543                                stickyIntents = new ArrayList<Intent>();
17544                            }
17545                            stickyIntents.addAll(intents);
17546                        }
17547                    }
17548                }
17549            }
17550        }
17551
17552        ArrayList<Intent> allSticky = null;
17553        if (stickyIntents != null) {
17554            final ContentResolver resolver = mContext.getContentResolver();
17555            // Look for any matching sticky broadcasts...
17556            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17557                Intent intent = stickyIntents.get(i);
17558                // If intent has scheme "content", it will need to acccess
17559                // provider that needs to lock mProviderMap in ActivityThread
17560                // and also it may need to wait application response, so we
17561                // cannot lock ActivityManagerService here.
17562                if (filter.match(resolver, intent, true, TAG) >= 0) {
17563                    if (allSticky == null) {
17564                        allSticky = new ArrayList<Intent>();
17565                    }
17566                    allSticky.add(intent);
17567                }
17568            }
17569        }
17570
17571        // The first sticky in the list is returned directly back to the client.
17572        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17573        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17574        if (receiver == null) {
17575            return sticky;
17576        }
17577
17578        synchronized (this) {
17579            if (callerApp != null && (callerApp.thread == null
17580                    || callerApp.thread.asBinder() != caller.asBinder())) {
17581                // Original caller already died
17582                return null;
17583            }
17584            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17585            if (rl == null) {
17586                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17587                        userId, receiver);
17588                if (rl.app != null) {
17589                    rl.app.receivers.add(rl);
17590                } else {
17591                    try {
17592                        receiver.asBinder().linkToDeath(rl, 0);
17593                    } catch (RemoteException e) {
17594                        return sticky;
17595                    }
17596                    rl.linkedToDeath = true;
17597                }
17598                mRegisteredReceivers.put(receiver.asBinder(), rl);
17599            } else if (rl.uid != callingUid) {
17600                throw new IllegalArgumentException(
17601                        "Receiver requested to register for uid " + callingUid
17602                        + " was previously registered for uid " + rl.uid);
17603            } else if (rl.pid != callingPid) {
17604                throw new IllegalArgumentException(
17605                        "Receiver requested to register for pid " + callingPid
17606                        + " was previously registered for pid " + rl.pid);
17607            } else if (rl.userId != userId) {
17608                throw new IllegalArgumentException(
17609                        "Receiver requested to register for user " + userId
17610                        + " was previously registered for user " + rl.userId);
17611            }
17612            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17613                    permission, callingUid, userId);
17614            rl.add(bf);
17615            if (!bf.debugCheck()) {
17616                Slog.w(TAG, "==> For Dynamic broadcast");
17617            }
17618            mReceiverResolver.addFilter(bf);
17619
17620            // Enqueue broadcasts for all existing stickies that match
17621            // this filter.
17622            if (allSticky != null) {
17623                ArrayList receivers = new ArrayList();
17624                receivers.add(bf);
17625
17626                final int stickyCount = allSticky.size();
17627                for (int i = 0; i < stickyCount; i++) {
17628                    Intent intent = allSticky.get(i);
17629                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17630                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17631                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17632                            null, 0, null, null, false, true, true, -1);
17633                    queue.enqueueParallelBroadcastLocked(r);
17634                    queue.scheduleBroadcastsLocked();
17635                }
17636            }
17637
17638            return sticky;
17639        }
17640    }
17641
17642    public void unregisterReceiver(IIntentReceiver receiver) {
17643        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17644
17645        final long origId = Binder.clearCallingIdentity();
17646        try {
17647            boolean doTrim = false;
17648
17649            synchronized(this) {
17650                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17651                if (rl != null) {
17652                    final BroadcastRecord r = rl.curBroadcast;
17653                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17654                        final boolean doNext = r.queue.finishReceiverLocked(
17655                                r, r.resultCode, r.resultData, r.resultExtras,
17656                                r.resultAbort, false);
17657                        if (doNext) {
17658                            doTrim = true;
17659                            r.queue.processNextBroadcast(false);
17660                        }
17661                    }
17662
17663                    if (rl.app != null) {
17664                        rl.app.receivers.remove(rl);
17665                    }
17666                    removeReceiverLocked(rl);
17667                    if (rl.linkedToDeath) {
17668                        rl.linkedToDeath = false;
17669                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17670                    }
17671                }
17672            }
17673
17674            // If we actually concluded any broadcasts, we might now be able
17675            // to trim the recipients' apps from our working set
17676            if (doTrim) {
17677                trimApplications();
17678                return;
17679            }
17680
17681        } finally {
17682            Binder.restoreCallingIdentity(origId);
17683        }
17684    }
17685
17686    void removeReceiverLocked(ReceiverList rl) {
17687        mRegisteredReceivers.remove(rl.receiver.asBinder());
17688        for (int i = rl.size() - 1; i >= 0; i--) {
17689            mReceiverResolver.removeFilter(rl.get(i));
17690        }
17691    }
17692
17693    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17694        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17695            ProcessRecord r = mLruProcesses.get(i);
17696            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17697                try {
17698                    r.thread.dispatchPackageBroadcast(cmd, packages);
17699                } catch (RemoteException ex) {
17700                }
17701            }
17702        }
17703    }
17704
17705    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17706            int callingUid, int[] users) {
17707        // TODO: come back and remove this assumption to triage all broadcasts
17708        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17709
17710        List<ResolveInfo> receivers = null;
17711        try {
17712            HashSet<ComponentName> singleUserReceivers = null;
17713            boolean scannedFirstReceivers = false;
17714            for (int user : users) {
17715                // Skip users that have Shell restrictions, with exception of always permitted
17716                // Shell broadcasts
17717                if (callingUid == Process.SHELL_UID
17718                        && mUserController.hasUserRestriction(
17719                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17720                        && !isPermittedShellBroadcast(intent)) {
17721                    continue;
17722                }
17723                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17724                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17725                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17726                    // If this is not the system user, we need to check for
17727                    // any receivers that should be filtered out.
17728                    for (int i=0; i<newReceivers.size(); i++) {
17729                        ResolveInfo ri = newReceivers.get(i);
17730                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17731                            newReceivers.remove(i);
17732                            i--;
17733                        }
17734                    }
17735                }
17736                if (newReceivers != null && newReceivers.size() == 0) {
17737                    newReceivers = null;
17738                }
17739                if (receivers == null) {
17740                    receivers = newReceivers;
17741                } else if (newReceivers != null) {
17742                    // We need to concatenate the additional receivers
17743                    // found with what we have do far.  This would be easy,
17744                    // but we also need to de-dup any receivers that are
17745                    // singleUser.
17746                    if (!scannedFirstReceivers) {
17747                        // Collect any single user receivers we had already retrieved.
17748                        scannedFirstReceivers = true;
17749                        for (int i=0; i<receivers.size(); i++) {
17750                            ResolveInfo ri = receivers.get(i);
17751                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17752                                ComponentName cn = new ComponentName(
17753                                        ri.activityInfo.packageName, ri.activityInfo.name);
17754                                if (singleUserReceivers == null) {
17755                                    singleUserReceivers = new HashSet<ComponentName>();
17756                                }
17757                                singleUserReceivers.add(cn);
17758                            }
17759                        }
17760                    }
17761                    // Add the new results to the existing results, tracking
17762                    // and de-dupping single user receivers.
17763                    for (int i=0; i<newReceivers.size(); i++) {
17764                        ResolveInfo ri = newReceivers.get(i);
17765                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17766                            ComponentName cn = new ComponentName(
17767                                    ri.activityInfo.packageName, ri.activityInfo.name);
17768                            if (singleUserReceivers == null) {
17769                                singleUserReceivers = new HashSet<ComponentName>();
17770                            }
17771                            if (!singleUserReceivers.contains(cn)) {
17772                                singleUserReceivers.add(cn);
17773                                receivers.add(ri);
17774                            }
17775                        } else {
17776                            receivers.add(ri);
17777                        }
17778                    }
17779                }
17780            }
17781        } catch (RemoteException ex) {
17782            // pm is in same process, this will never happen.
17783        }
17784        return receivers;
17785    }
17786
17787    private boolean isPermittedShellBroadcast(Intent intent) {
17788        // remote bugreport should always be allowed to be taken
17789        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17790    }
17791
17792    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17793            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17794        final String action = intent.getAction();
17795        if (isProtectedBroadcast
17796                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17797                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17798                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17799                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17800                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17801                || Intent.ACTION_MASTER_CLEAR.equals(action)
17802                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17803                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17804                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17805                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17806                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17807            // Broadcast is either protected, or it's a public action that
17808            // we've relaxed, so it's fine for system internals to send.
17809            return;
17810        }
17811
17812        // This broadcast may be a problem...  but there are often system components that
17813        // want to send an internal broadcast to themselves, which is annoying to have to
17814        // explicitly list each action as a protected broadcast, so we will check for that
17815        // one safe case and allow it: an explicit broadcast, only being received by something
17816        // that has protected itself.
17817        if (receivers != null && receivers.size() > 0
17818                && (intent.getPackage() != null || intent.getComponent() != null)) {
17819            boolean allProtected = true;
17820            for (int i = receivers.size()-1; i >= 0; i--) {
17821                Object target = receivers.get(i);
17822                if (target instanceof ResolveInfo) {
17823                    ResolveInfo ri = (ResolveInfo)target;
17824                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17825                        allProtected = false;
17826                        break;
17827                    }
17828                } else {
17829                    BroadcastFilter bf = (BroadcastFilter)target;
17830                    if (bf.requiredPermission == null) {
17831                        allProtected = false;
17832                        break;
17833                    }
17834                }
17835            }
17836            if (allProtected) {
17837                // All safe!
17838                return;
17839            }
17840        }
17841
17842        // The vast majority of broadcasts sent from system internals
17843        // should be protected to avoid security holes, so yell loudly
17844        // to ensure we examine these cases.
17845        if (callerApp != null) {
17846            Log.wtf(TAG, "Sending non-protected broadcast " + action
17847                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17848                    new Throwable());
17849        } else {
17850            Log.wtf(TAG, "Sending non-protected broadcast " + action
17851                            + " from system uid " + UserHandle.formatUid(callingUid)
17852                            + " pkg " + callerPackage,
17853                    new Throwable());
17854        }
17855    }
17856
17857    final int broadcastIntentLocked(ProcessRecord callerApp,
17858            String callerPackage, Intent intent, String resolvedType,
17859            IIntentReceiver resultTo, int resultCode, String resultData,
17860            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17861            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17862        intent = new Intent(intent);
17863
17864        // By default broadcasts do not go to stopped apps.
17865        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17866
17867        // If we have not finished booting, don't allow this to launch new processes.
17868        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17869            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17870        }
17871
17872        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17873                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17874                + " ordered=" + ordered + " userid=" + userId);
17875        if ((resultTo != null) && !ordered) {
17876            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17877        }
17878
17879        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17880                ALLOW_NON_FULL, "broadcast", callerPackage);
17881
17882        // Make sure that the user who is receiving this broadcast is running.
17883        // If not, we will just skip it. Make an exception for shutdown broadcasts
17884        // and upgrade steps.
17885
17886        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17887            if ((callingUid != Process.SYSTEM_UID
17888                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17889                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17890                Slog.w(TAG, "Skipping broadcast of " + intent
17891                        + ": user " + userId + " is stopped");
17892                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17893            }
17894        }
17895
17896        BroadcastOptions brOptions = null;
17897        if (bOptions != null) {
17898            brOptions = new BroadcastOptions(bOptions);
17899            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17900                // See if the caller is allowed to do this.  Note we are checking against
17901                // the actual real caller (not whoever provided the operation as say a
17902                // PendingIntent), because that who is actually supplied the arguments.
17903                if (checkComponentPermission(
17904                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17905                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17906                        != PackageManager.PERMISSION_GRANTED) {
17907                    String msg = "Permission Denial: " + intent.getAction()
17908                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17909                            + ", uid=" + callingUid + ")"
17910                            + " requires "
17911                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17912                    Slog.w(TAG, msg);
17913                    throw new SecurityException(msg);
17914                }
17915            }
17916        }
17917
17918        // Verify that protected broadcasts are only being sent by system code,
17919        // and that system code is only sending protected broadcasts.
17920        final String action = intent.getAction();
17921        final boolean isProtectedBroadcast;
17922        try {
17923            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17924        } catch (RemoteException e) {
17925            Slog.w(TAG, "Remote exception", e);
17926            return ActivityManager.BROADCAST_SUCCESS;
17927        }
17928
17929        final boolean isCallerSystem;
17930        switch (UserHandle.getAppId(callingUid)) {
17931            case Process.ROOT_UID:
17932            case Process.SYSTEM_UID:
17933            case Process.PHONE_UID:
17934            case Process.BLUETOOTH_UID:
17935            case Process.NFC_UID:
17936                isCallerSystem = true;
17937                break;
17938            default:
17939                isCallerSystem = (callerApp != null) && callerApp.persistent;
17940                break;
17941        }
17942
17943        // First line security check before anything else: stop non-system apps from
17944        // sending protected broadcasts.
17945        if (!isCallerSystem) {
17946            if (isProtectedBroadcast) {
17947                String msg = "Permission Denial: not allowed to send broadcast "
17948                        + action + " from pid="
17949                        + callingPid + ", uid=" + callingUid;
17950                Slog.w(TAG, msg);
17951                throw new SecurityException(msg);
17952
17953            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17954                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17955                // Special case for compatibility: we don't want apps to send this,
17956                // but historically it has not been protected and apps may be using it
17957                // to poke their own app widget.  So, instead of making it protected,
17958                // just limit it to the caller.
17959                if (callerPackage == null) {
17960                    String msg = "Permission Denial: not allowed to send broadcast "
17961                            + action + " from unknown caller.";
17962                    Slog.w(TAG, msg);
17963                    throw new SecurityException(msg);
17964                } else if (intent.getComponent() != null) {
17965                    // They are good enough to send to an explicit component...  verify
17966                    // it is being sent to the calling app.
17967                    if (!intent.getComponent().getPackageName().equals(
17968                            callerPackage)) {
17969                        String msg = "Permission Denial: not allowed to send broadcast "
17970                                + action + " to "
17971                                + intent.getComponent().getPackageName() + " from "
17972                                + callerPackage;
17973                        Slog.w(TAG, msg);
17974                        throw new SecurityException(msg);
17975                    }
17976                } else {
17977                    // Limit broadcast to their own package.
17978                    intent.setPackage(callerPackage);
17979                }
17980            }
17981        }
17982
17983        if (action != null) {
17984            switch (action) {
17985                case Intent.ACTION_UID_REMOVED:
17986                case Intent.ACTION_PACKAGE_REMOVED:
17987                case Intent.ACTION_PACKAGE_CHANGED:
17988                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17989                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17990                case Intent.ACTION_PACKAGES_SUSPENDED:
17991                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17992                    // Handle special intents: if this broadcast is from the package
17993                    // manager about a package being removed, we need to remove all of
17994                    // its activities from the history stack.
17995                    if (checkComponentPermission(
17996                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17997                            callingPid, callingUid, -1, true)
17998                            != PackageManager.PERMISSION_GRANTED) {
17999                        String msg = "Permission Denial: " + intent.getAction()
18000                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18001                                + ", uid=" + callingUid + ")"
18002                                + " requires "
18003                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18004                        Slog.w(TAG, msg);
18005                        throw new SecurityException(msg);
18006                    }
18007                    switch (action) {
18008                        case Intent.ACTION_UID_REMOVED:
18009                            final Bundle intentExtras = intent.getExtras();
18010                            final int uid = intentExtras != null
18011                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18012                            if (uid >= 0) {
18013                                mBatteryStatsService.removeUid(uid);
18014                                mAppOpsService.uidRemoved(uid);
18015                            }
18016                            break;
18017                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18018                            // If resources are unavailable just force stop all those packages
18019                            // and flush the attribute cache as well.
18020                            String list[] =
18021                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18022                            if (list != null && list.length > 0) {
18023                                for (int i = 0; i < list.length; i++) {
18024                                    forceStopPackageLocked(list[i], -1, false, true, true,
18025                                            false, false, userId, "storage unmount");
18026                                }
18027                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18028                                sendPackageBroadcastLocked(
18029                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18030                                        userId);
18031                            }
18032                            break;
18033                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18034                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18035                            break;
18036                        case Intent.ACTION_PACKAGE_REMOVED:
18037                        case Intent.ACTION_PACKAGE_CHANGED:
18038                            Uri data = intent.getData();
18039                            String ssp;
18040                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18041                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18042                                final boolean replacing =
18043                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18044                                final boolean killProcess =
18045                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18046                                final boolean fullUninstall = removed && !replacing;
18047                                if (removed) {
18048                                    if (killProcess) {
18049                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18050                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18051                                                false, true, true, false, fullUninstall, userId,
18052                                                removed ? "pkg removed" : "pkg changed");
18053                                    }
18054                                    final int cmd = killProcess
18055                                            ? IApplicationThread.PACKAGE_REMOVED
18056                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18057                                    sendPackageBroadcastLocked(cmd,
18058                                            new String[] {ssp}, userId);
18059                                    if (fullUninstall) {
18060                                        mAppOpsService.packageRemoved(
18061                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18062
18063                                        // Remove all permissions granted from/to this package
18064                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18065
18066                                        removeTasksByPackageNameLocked(ssp, userId);
18067
18068                                        // Hide the "unsupported display" dialog if necessary.
18069                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18070                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18071                                            mUnsupportedDisplaySizeDialog.dismiss();
18072                                            mUnsupportedDisplaySizeDialog = null;
18073                                        }
18074                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18075                                        mBatteryStatsService.notePackageUninstalled(ssp);
18076                                    }
18077                                } else {
18078                                    if (killProcess) {
18079                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18080                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18081                                                userId, ProcessList.INVALID_ADJ,
18082                                                false, true, true, false, "change " + ssp);
18083                                    }
18084                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18085                                            intent.getStringArrayExtra(
18086                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18087                                }
18088                            }
18089                            break;
18090                        case Intent.ACTION_PACKAGES_SUSPENDED:
18091                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18092                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18093                                    intent.getAction());
18094                            final String[] packageNames = intent.getStringArrayExtra(
18095                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18096                            final int userHandle = intent.getIntExtra(
18097                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18098
18099                            synchronized(ActivityManagerService.this) {
18100                                mRecentTasks.onPackagesSuspendedChanged(
18101                                        packageNames, suspended, userHandle);
18102                            }
18103                            break;
18104                    }
18105                    break;
18106                case Intent.ACTION_PACKAGE_REPLACED:
18107                {
18108                    final Uri data = intent.getData();
18109                    final String ssp;
18110                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18111                        final ApplicationInfo aInfo =
18112                                getPackageManagerInternalLocked().getApplicationInfo(
18113                                        ssp,
18114                                        userId);
18115                        if (aInfo == null) {
18116                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18117                                    + " ssp=" + ssp + " data=" + data);
18118                            return ActivityManager.BROADCAST_SUCCESS;
18119                        }
18120                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18121                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18122                                new String[] {ssp}, userId);
18123                    }
18124                    break;
18125                }
18126                case Intent.ACTION_PACKAGE_ADDED:
18127                {
18128                    // Special case for adding a package: by default turn on compatibility mode.
18129                    Uri data = intent.getData();
18130                    String ssp;
18131                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18132                        final boolean replacing =
18133                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18134                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18135
18136                        try {
18137                            ApplicationInfo ai = AppGlobals.getPackageManager().
18138                                    getApplicationInfo(ssp, 0, 0);
18139                            mBatteryStatsService.notePackageInstalled(ssp,
18140                                    ai != null ? ai.versionCode : 0);
18141                        } catch (RemoteException e) {
18142                        }
18143                    }
18144                    break;
18145                }
18146                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18147                {
18148                    Uri data = intent.getData();
18149                    String ssp;
18150                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18151                        // Hide the "unsupported display" dialog if necessary.
18152                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18153                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18154                            mUnsupportedDisplaySizeDialog.dismiss();
18155                            mUnsupportedDisplaySizeDialog = null;
18156                        }
18157                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18158                    }
18159                    break;
18160                }
18161                case Intent.ACTION_TIMEZONE_CHANGED:
18162                    // If this is the time zone changed action, queue up a message that will reset
18163                    // the timezone of all currently running processes. This message will get
18164                    // queued up before the broadcast happens.
18165                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18166                    break;
18167                case Intent.ACTION_TIME_CHANGED:
18168                    // If the user set the time, let all running processes know.
18169                    final int is24Hour =
18170                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18171                                    : 0;
18172                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18173                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18174                    synchronized (stats) {
18175                        stats.noteCurrentTimeChangedLocked();
18176                    }
18177                    break;
18178                case Intent.ACTION_CLEAR_DNS_CACHE:
18179                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18180                    break;
18181                case Proxy.PROXY_CHANGE_ACTION:
18182                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18183                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18184                    break;
18185                case android.hardware.Camera.ACTION_NEW_PICTURE:
18186                case android.hardware.Camera.ACTION_NEW_VIDEO:
18187                    // These broadcasts are no longer allowed by the system, since they can
18188                    // cause significant thrashing at a crictical point (using the camera).
18189                    // Apps should use JobScehduler to monitor for media provider changes.
18190                    Slog.w(TAG, action + " no longer allowed; dropping from "
18191                            + UserHandle.formatUid(callingUid));
18192                    if (resultTo != null) {
18193                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18194                        try {
18195                            queue.performReceiveLocked(callerApp, resultTo, intent,
18196                                    Activity.RESULT_CANCELED, null, null,
18197                                    false, false, userId);
18198                        } catch (RemoteException e) {
18199                            Slog.w(TAG, "Failure ["
18200                                    + queue.mQueueName + "] sending broadcast result of "
18201                                    + intent, e);
18202
18203                        }
18204                    }
18205                    // Lie; we don't want to crash the app.
18206                    return ActivityManager.BROADCAST_SUCCESS;
18207            }
18208        }
18209
18210        // Add to the sticky list if requested.
18211        if (sticky) {
18212            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18213                    callingPid, callingUid)
18214                    != PackageManager.PERMISSION_GRANTED) {
18215                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18216                        + callingPid + ", uid=" + callingUid
18217                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18218                Slog.w(TAG, msg);
18219                throw new SecurityException(msg);
18220            }
18221            if (requiredPermissions != null && requiredPermissions.length > 0) {
18222                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18223                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18224                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18225            }
18226            if (intent.getComponent() != null) {
18227                throw new SecurityException(
18228                        "Sticky broadcasts can't target a specific component");
18229            }
18230            // We use userId directly here, since the "all" target is maintained
18231            // as a separate set of sticky broadcasts.
18232            if (userId != UserHandle.USER_ALL) {
18233                // But first, if this is not a broadcast to all users, then
18234                // make sure it doesn't conflict with an existing broadcast to
18235                // all users.
18236                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18237                        UserHandle.USER_ALL);
18238                if (stickies != null) {
18239                    ArrayList<Intent> list = stickies.get(intent.getAction());
18240                    if (list != null) {
18241                        int N = list.size();
18242                        int i;
18243                        for (i=0; i<N; i++) {
18244                            if (intent.filterEquals(list.get(i))) {
18245                                throw new IllegalArgumentException(
18246                                        "Sticky broadcast " + intent + " for user "
18247                                        + userId + " conflicts with existing global broadcast");
18248                            }
18249                        }
18250                    }
18251                }
18252            }
18253            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18254            if (stickies == null) {
18255                stickies = new ArrayMap<>();
18256                mStickyBroadcasts.put(userId, stickies);
18257            }
18258            ArrayList<Intent> list = stickies.get(intent.getAction());
18259            if (list == null) {
18260                list = new ArrayList<>();
18261                stickies.put(intent.getAction(), list);
18262            }
18263            final int stickiesCount = list.size();
18264            int i;
18265            for (i = 0; i < stickiesCount; i++) {
18266                if (intent.filterEquals(list.get(i))) {
18267                    // This sticky already exists, replace it.
18268                    list.set(i, new Intent(intent));
18269                    break;
18270                }
18271            }
18272            if (i >= stickiesCount) {
18273                list.add(new Intent(intent));
18274            }
18275        }
18276
18277        int[] users;
18278        if (userId == UserHandle.USER_ALL) {
18279            // Caller wants broadcast to go to all started users.
18280            users = mUserController.getStartedUserArrayLocked();
18281        } else {
18282            // Caller wants broadcast to go to one specific user.
18283            users = new int[] {userId};
18284        }
18285
18286        // Figure out who all will receive this broadcast.
18287        List receivers = null;
18288        List<BroadcastFilter> registeredReceivers = null;
18289        // Need to resolve the intent to interested receivers...
18290        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18291                 == 0) {
18292            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18293        }
18294        if (intent.getComponent() == null) {
18295            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18296                // Query one target user at a time, excluding shell-restricted users
18297                for (int i = 0; i < users.length; i++) {
18298                    if (mUserController.hasUserRestriction(
18299                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18300                        continue;
18301                    }
18302                    List<BroadcastFilter> registeredReceiversForUser =
18303                            mReceiverResolver.queryIntent(intent,
18304                                    resolvedType, false, users[i]);
18305                    if (registeredReceivers == null) {
18306                        registeredReceivers = registeredReceiversForUser;
18307                    } else if (registeredReceiversForUser != null) {
18308                        registeredReceivers.addAll(registeredReceiversForUser);
18309                    }
18310                }
18311            } else {
18312                registeredReceivers = mReceiverResolver.queryIntent(intent,
18313                        resolvedType, false, userId);
18314            }
18315        }
18316
18317        final boolean replacePending =
18318                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18319
18320        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18321                + " replacePending=" + replacePending);
18322
18323        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18324        if (!ordered && NR > 0) {
18325            // If we are not serializing this broadcast, then send the
18326            // registered receivers separately so they don't wait for the
18327            // components to be launched.
18328            if (isCallerSystem) {
18329                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18330                        isProtectedBroadcast, registeredReceivers);
18331            }
18332            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18333            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18334                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18335                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18336                    resultExtras, ordered, sticky, false, userId);
18337            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18338            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18339            if (!replaced) {
18340                queue.enqueueParallelBroadcastLocked(r);
18341                queue.scheduleBroadcastsLocked();
18342            }
18343            registeredReceivers = null;
18344            NR = 0;
18345        }
18346
18347        // Merge into one list.
18348        int ir = 0;
18349        if (receivers != null) {
18350            // A special case for PACKAGE_ADDED: do not allow the package
18351            // being added to see this broadcast.  This prevents them from
18352            // using this as a back door to get run as soon as they are
18353            // installed.  Maybe in the future we want to have a special install
18354            // broadcast or such for apps, but we'd like to deliberately make
18355            // this decision.
18356            String skipPackages[] = null;
18357            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18358                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18359                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18360                Uri data = intent.getData();
18361                if (data != null) {
18362                    String pkgName = data.getSchemeSpecificPart();
18363                    if (pkgName != null) {
18364                        skipPackages = new String[] { pkgName };
18365                    }
18366                }
18367            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18368                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18369            }
18370            if (skipPackages != null && (skipPackages.length > 0)) {
18371                for (String skipPackage : skipPackages) {
18372                    if (skipPackage != null) {
18373                        int NT = receivers.size();
18374                        for (int it=0; it<NT; it++) {
18375                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18376                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18377                                receivers.remove(it);
18378                                it--;
18379                                NT--;
18380                            }
18381                        }
18382                    }
18383                }
18384            }
18385
18386            int NT = receivers != null ? receivers.size() : 0;
18387            int it = 0;
18388            ResolveInfo curt = null;
18389            BroadcastFilter curr = null;
18390            while (it < NT && ir < NR) {
18391                if (curt == null) {
18392                    curt = (ResolveInfo)receivers.get(it);
18393                }
18394                if (curr == null) {
18395                    curr = registeredReceivers.get(ir);
18396                }
18397                if (curr.getPriority() >= curt.priority) {
18398                    // Insert this broadcast record into the final list.
18399                    receivers.add(it, curr);
18400                    ir++;
18401                    curr = null;
18402                    it++;
18403                    NT++;
18404                } else {
18405                    // Skip to the next ResolveInfo in the final list.
18406                    it++;
18407                    curt = null;
18408                }
18409            }
18410        }
18411        while (ir < NR) {
18412            if (receivers == null) {
18413                receivers = new ArrayList();
18414            }
18415            receivers.add(registeredReceivers.get(ir));
18416            ir++;
18417        }
18418
18419        if (isCallerSystem) {
18420            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18421                    isProtectedBroadcast, receivers);
18422        }
18423
18424        if ((receivers != null && receivers.size() > 0)
18425                || resultTo != null) {
18426            BroadcastQueue queue = broadcastQueueForIntent(intent);
18427            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18428                    callerPackage, callingPid, callingUid, resolvedType,
18429                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18430                    resultData, resultExtras, ordered, sticky, false, userId);
18431
18432            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18433                    + ": prev had " + queue.mOrderedBroadcasts.size());
18434            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18435                    "Enqueueing broadcast " + r.intent.getAction());
18436
18437            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18438            if (!replaced) {
18439                queue.enqueueOrderedBroadcastLocked(r);
18440                queue.scheduleBroadcastsLocked();
18441            }
18442        } else {
18443            // There was nobody interested in the broadcast, but we still want to record
18444            // that it happened.
18445            if (intent.getComponent() == null && intent.getPackage() == null
18446                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18447                // This was an implicit broadcast... let's record it for posterity.
18448                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18449            }
18450        }
18451
18452        return ActivityManager.BROADCAST_SUCCESS;
18453    }
18454
18455    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18456            int skipCount, long dispatchTime) {
18457        final long now = SystemClock.elapsedRealtime();
18458        if (mCurBroadcastStats == null ||
18459                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18460            mLastBroadcastStats = mCurBroadcastStats;
18461            if (mLastBroadcastStats != null) {
18462                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18463                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18464            }
18465            mCurBroadcastStats = new BroadcastStats();
18466        }
18467        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18468    }
18469
18470    final Intent verifyBroadcastLocked(Intent intent) {
18471        // Refuse possible leaked file descriptors
18472        if (intent != null && intent.hasFileDescriptors() == true) {
18473            throw new IllegalArgumentException("File descriptors passed in Intent");
18474        }
18475
18476        int flags = intent.getFlags();
18477
18478        if (!mProcessesReady) {
18479            // if the caller really truly claims to know what they're doing, go
18480            // ahead and allow the broadcast without launching any receivers
18481            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18482                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18483            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18484                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18485                        + " before boot completion");
18486                throw new IllegalStateException("Cannot broadcast before boot completed");
18487            }
18488        }
18489
18490        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18491            throw new IllegalArgumentException(
18492                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18493        }
18494
18495        return intent;
18496    }
18497
18498    public final int broadcastIntent(IApplicationThread caller,
18499            Intent intent, String resolvedType, IIntentReceiver resultTo,
18500            int resultCode, String resultData, Bundle resultExtras,
18501            String[] requiredPermissions, int appOp, Bundle bOptions,
18502            boolean serialized, boolean sticky, int userId) {
18503        enforceNotIsolatedCaller("broadcastIntent");
18504        synchronized(this) {
18505            intent = verifyBroadcastLocked(intent);
18506
18507            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18508            final int callingPid = Binder.getCallingPid();
18509            final int callingUid = Binder.getCallingUid();
18510            final long origId = Binder.clearCallingIdentity();
18511            int res = broadcastIntentLocked(callerApp,
18512                    callerApp != null ? callerApp.info.packageName : null,
18513                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18514                    requiredPermissions, appOp, bOptions, serialized, sticky,
18515                    callingPid, callingUid, userId);
18516            Binder.restoreCallingIdentity(origId);
18517            return res;
18518        }
18519    }
18520
18521
18522    int broadcastIntentInPackage(String packageName, int uid,
18523            Intent intent, String resolvedType, IIntentReceiver resultTo,
18524            int resultCode, String resultData, Bundle resultExtras,
18525            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18526            int userId) {
18527        synchronized(this) {
18528            intent = verifyBroadcastLocked(intent);
18529
18530            final long origId = Binder.clearCallingIdentity();
18531            String[] requiredPermissions = requiredPermission == null ? null
18532                    : new String[] {requiredPermission};
18533            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18534                    resultTo, resultCode, resultData, resultExtras,
18535                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18536                    sticky, -1, uid, userId);
18537            Binder.restoreCallingIdentity(origId);
18538            return res;
18539        }
18540    }
18541
18542    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18543        // Refuse possible leaked file descriptors
18544        if (intent != null && intent.hasFileDescriptors() == true) {
18545            throw new IllegalArgumentException("File descriptors passed in Intent");
18546        }
18547
18548        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18549                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18550
18551        synchronized(this) {
18552            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18553                    != PackageManager.PERMISSION_GRANTED) {
18554                String msg = "Permission Denial: unbroadcastIntent() from pid="
18555                        + Binder.getCallingPid()
18556                        + ", uid=" + Binder.getCallingUid()
18557                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18558                Slog.w(TAG, msg);
18559                throw new SecurityException(msg);
18560            }
18561            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18562            if (stickies != null) {
18563                ArrayList<Intent> list = stickies.get(intent.getAction());
18564                if (list != null) {
18565                    int N = list.size();
18566                    int i;
18567                    for (i=0; i<N; i++) {
18568                        if (intent.filterEquals(list.get(i))) {
18569                            list.remove(i);
18570                            break;
18571                        }
18572                    }
18573                    if (list.size() <= 0) {
18574                        stickies.remove(intent.getAction());
18575                    }
18576                }
18577                if (stickies.size() <= 0) {
18578                    mStickyBroadcasts.remove(userId);
18579                }
18580            }
18581        }
18582    }
18583
18584    void backgroundServicesFinishedLocked(int userId) {
18585        for (BroadcastQueue queue : mBroadcastQueues) {
18586            queue.backgroundServicesFinishedLocked(userId);
18587        }
18588    }
18589
18590    public void finishReceiver(IBinder who, int resultCode, String resultData,
18591            Bundle resultExtras, boolean resultAbort, int flags) {
18592        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18593
18594        // Refuse possible leaked file descriptors
18595        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18596            throw new IllegalArgumentException("File descriptors passed in Bundle");
18597        }
18598
18599        final long origId = Binder.clearCallingIdentity();
18600        try {
18601            boolean doNext = false;
18602            BroadcastRecord r;
18603
18604            synchronized(this) {
18605                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18606                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18607                r = queue.getMatchingOrderedReceiver(who);
18608                if (r != null) {
18609                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18610                        resultData, resultExtras, resultAbort, true);
18611                }
18612            }
18613
18614            if (doNext) {
18615                r.queue.processNextBroadcast(false);
18616            }
18617            trimApplications();
18618        } finally {
18619            Binder.restoreCallingIdentity(origId);
18620        }
18621    }
18622
18623    // =========================================================
18624    // INSTRUMENTATION
18625    // =========================================================
18626
18627    public boolean startInstrumentation(ComponentName className,
18628            String profileFile, int flags, Bundle arguments,
18629            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18630            int userId, String abiOverride) {
18631        enforceNotIsolatedCaller("startInstrumentation");
18632        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18633                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18634        // Refuse possible leaked file descriptors
18635        if (arguments != null && arguments.hasFileDescriptors()) {
18636            throw new IllegalArgumentException("File descriptors passed in Bundle");
18637        }
18638
18639        synchronized(this) {
18640            InstrumentationInfo ii = null;
18641            ApplicationInfo ai = null;
18642            try {
18643                ii = mContext.getPackageManager().getInstrumentationInfo(
18644                    className, STOCK_PM_FLAGS);
18645                ai = AppGlobals.getPackageManager().getApplicationInfo(
18646                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18647            } catch (PackageManager.NameNotFoundException e) {
18648            } catch (RemoteException e) {
18649            }
18650            if (ii == null) {
18651                reportStartInstrumentationFailureLocked(watcher, className,
18652                        "Unable to find instrumentation info for: " + className);
18653                return false;
18654            }
18655            if (ai == null) {
18656                reportStartInstrumentationFailureLocked(watcher, className,
18657                        "Unable to find instrumentation target package: " + ii.targetPackage);
18658                return false;
18659            }
18660            if (!ai.hasCode()) {
18661                reportStartInstrumentationFailureLocked(watcher, className,
18662                        "Instrumentation target has no code: " + ii.targetPackage);
18663                return false;
18664            }
18665
18666            int match = mContext.getPackageManager().checkSignatures(
18667                    ii.targetPackage, ii.packageName);
18668            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18669                String msg = "Permission Denial: starting instrumentation "
18670                        + className + " from pid="
18671                        + Binder.getCallingPid()
18672                        + ", uid=" + Binder.getCallingPid()
18673                        + " not allowed because package " + ii.packageName
18674                        + " does not have a signature matching the target "
18675                        + ii.targetPackage;
18676                reportStartInstrumentationFailureLocked(watcher, className, msg);
18677                throw new SecurityException(msg);
18678            }
18679
18680            final long origId = Binder.clearCallingIdentity();
18681            // Instrumentation can kill and relaunch even persistent processes
18682            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18683                    "start instr");
18684            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18685            app.instrumentationClass = className;
18686            app.instrumentationInfo = ai;
18687            app.instrumentationProfileFile = profileFile;
18688            app.instrumentationArguments = arguments;
18689            app.instrumentationWatcher = watcher;
18690            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18691            app.instrumentationResultClass = className;
18692            Binder.restoreCallingIdentity(origId);
18693        }
18694
18695        return true;
18696    }
18697
18698    /**
18699     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18700     * error to the logs, but if somebody is watching, send the report there too.  This enables
18701     * the "am" command to report errors with more information.
18702     *
18703     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18704     * @param cn The component name of the instrumentation.
18705     * @param report The error report.
18706     */
18707    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18708            ComponentName cn, String report) {
18709        Slog.w(TAG, report);
18710        if (watcher != null) {
18711            Bundle results = new Bundle();
18712            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18713            results.putString("Error", report);
18714            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18715        }
18716    }
18717
18718    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18719        if (app.instrumentationWatcher != null) {
18720            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18721                    app.instrumentationClass, resultCode, results);
18722        }
18723
18724        // Can't call out of the system process with a lock held, so post a message.
18725        if (app.instrumentationUiAutomationConnection != null) {
18726            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18727                    app.instrumentationUiAutomationConnection).sendToTarget();
18728        }
18729
18730        app.instrumentationWatcher = null;
18731        app.instrumentationUiAutomationConnection = null;
18732        app.instrumentationClass = null;
18733        app.instrumentationInfo = null;
18734        app.instrumentationProfileFile = null;
18735        app.instrumentationArguments = null;
18736
18737        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18738                "finished inst");
18739    }
18740
18741    public void finishInstrumentation(IApplicationThread target,
18742            int resultCode, Bundle results) {
18743        int userId = UserHandle.getCallingUserId();
18744        // Refuse possible leaked file descriptors
18745        if (results != null && results.hasFileDescriptors()) {
18746            throw new IllegalArgumentException("File descriptors passed in Intent");
18747        }
18748
18749        synchronized(this) {
18750            ProcessRecord app = getRecordForAppLocked(target);
18751            if (app == null) {
18752                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18753                return;
18754            }
18755            final long origId = Binder.clearCallingIdentity();
18756            finishInstrumentationLocked(app, resultCode, results);
18757            Binder.restoreCallingIdentity(origId);
18758        }
18759    }
18760
18761    // =========================================================
18762    // CONFIGURATION
18763    // =========================================================
18764
18765    public ConfigurationInfo getDeviceConfigurationInfo() {
18766        ConfigurationInfo config = new ConfigurationInfo();
18767        synchronized (this) {
18768            config.reqTouchScreen = mConfiguration.touchscreen;
18769            config.reqKeyboardType = mConfiguration.keyboard;
18770            config.reqNavigation = mConfiguration.navigation;
18771            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18772                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18773                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18774            }
18775            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18776                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18777                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18778            }
18779            config.reqGlEsVersion = GL_ES_VERSION;
18780        }
18781        return config;
18782    }
18783
18784    ActivityStack getFocusedStack() {
18785        return mStackSupervisor.getFocusedStack();
18786    }
18787
18788    @Override
18789    public int getFocusedStackId() throws RemoteException {
18790        ActivityStack focusedStack = getFocusedStack();
18791        if (focusedStack != null) {
18792            return focusedStack.getStackId();
18793        }
18794        return -1;
18795    }
18796
18797    public Configuration getConfiguration() {
18798        Configuration ci;
18799        synchronized(this) {
18800            ci = new Configuration(mConfiguration);
18801            ci.userSetLocale = false;
18802        }
18803        return ci;
18804    }
18805
18806    @Override
18807    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18808        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18809        synchronized (this) {
18810            mSuppressResizeConfigChanges = suppress;
18811        }
18812    }
18813
18814    @Override
18815    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18816        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18817        if (fromStackId == HOME_STACK_ID) {
18818            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18819        }
18820        synchronized (this) {
18821            final long origId = Binder.clearCallingIdentity();
18822            try {
18823                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18824            } finally {
18825                Binder.restoreCallingIdentity(origId);
18826            }
18827        }
18828    }
18829
18830    @Override
18831    public void updatePersistentConfiguration(Configuration values) {
18832        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18833                "updateConfiguration()");
18834        enforceWriteSettingsPermission("updateConfiguration()");
18835        if (values == null) {
18836            throw new NullPointerException("Configuration must not be null");
18837        }
18838
18839        int userId = UserHandle.getCallingUserId();
18840
18841        synchronized(this) {
18842            updatePersistentConfigurationLocked(values, userId);
18843        }
18844    }
18845
18846    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18847        final long origId = Binder.clearCallingIdentity();
18848        try {
18849            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18850        } finally {
18851            Binder.restoreCallingIdentity(origId);
18852        }
18853    }
18854
18855    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18856        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18857                FONT_SCALE, 1.0f, userId);
18858        if (mConfiguration.fontScale != scaleFactor) {
18859            final Configuration configuration = mWindowManager.computeNewConfiguration();
18860            configuration.fontScale = scaleFactor;
18861            synchronized (this) {
18862                updatePersistentConfigurationLocked(configuration, userId);
18863            }
18864        }
18865    }
18866
18867    private void enforceWriteSettingsPermission(String func) {
18868        int uid = Binder.getCallingUid();
18869        if (uid == Process.ROOT_UID) {
18870            return;
18871        }
18872
18873        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18874                Settings.getPackageNameForUid(mContext, uid), false)) {
18875            return;
18876        }
18877
18878        String msg = "Permission Denial: " + func + " from pid="
18879                + Binder.getCallingPid()
18880                + ", uid=" + uid
18881                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18882        Slog.w(TAG, msg);
18883        throw new SecurityException(msg);
18884    }
18885
18886    public void updateConfiguration(Configuration values) {
18887        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18888                "updateConfiguration()");
18889
18890        synchronized(this) {
18891            if (values == null && mWindowManager != null) {
18892                // sentinel: fetch the current configuration from the window manager
18893                values = mWindowManager.computeNewConfiguration();
18894            }
18895
18896            if (mWindowManager != null) {
18897                mProcessList.applyDisplaySize(mWindowManager);
18898            }
18899
18900            final long origId = Binder.clearCallingIdentity();
18901            if (values != null) {
18902                Settings.System.clearConfiguration(values);
18903            }
18904            updateConfigurationLocked(values, null, false);
18905            Binder.restoreCallingIdentity(origId);
18906        }
18907    }
18908
18909    void updateUserConfigurationLocked() {
18910        Configuration configuration = new Configuration(mConfiguration);
18911        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18912                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18913        updateConfigurationLocked(configuration, null, false);
18914    }
18915
18916    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18917            boolean initLocale) {
18918        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18919    }
18920
18921    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18922            boolean initLocale, boolean deferResume) {
18923        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18924        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18925                UserHandle.USER_NULL, deferResume);
18926    }
18927
18928    // To cache the list of supported system locales
18929    private String[] mSupportedSystemLocales = null;
18930
18931    /**
18932     * Do either or both things: (1) change the current configuration, and (2)
18933     * make sure the given activity is running with the (now) current
18934     * configuration.  Returns true if the activity has been left running, or
18935     * false if <var>starting</var> is being destroyed to match the new
18936     * configuration.
18937     *
18938     * @param userId is only used when persistent parameter is set to true to persist configuration
18939     *               for that particular user
18940     */
18941    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18942            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18943        int changes = 0;
18944
18945        if (mWindowManager != null) {
18946            mWindowManager.deferSurfaceLayout();
18947        }
18948        if (values != null) {
18949            Configuration newConfig = new Configuration(mConfiguration);
18950            changes = newConfig.updateFrom(values);
18951            if (changes != 0) {
18952                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18953                        "Updating configuration to: " + values);
18954
18955                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18956
18957                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18958                    final LocaleList locales = values.getLocales();
18959                    int bestLocaleIndex = 0;
18960                    if (locales.size() > 1) {
18961                        if (mSupportedSystemLocales == null) {
18962                            mSupportedSystemLocales =
18963                                    Resources.getSystem().getAssets().getLocales();
18964                        }
18965                        bestLocaleIndex = Math.max(0,
18966                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18967                    }
18968                    SystemProperties.set("persist.sys.locale",
18969                            locales.get(bestLocaleIndex).toLanguageTag());
18970                    LocaleList.setDefault(locales, bestLocaleIndex);
18971                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18972                            locales.get(bestLocaleIndex)));
18973                }
18974
18975                mConfigurationSeq++;
18976                if (mConfigurationSeq <= 0) {
18977                    mConfigurationSeq = 1;
18978                }
18979                newConfig.seq = mConfigurationSeq;
18980                mConfiguration = newConfig;
18981                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18982                mUsageStatsService.reportConfigurationChange(newConfig,
18983                        mUserController.getCurrentUserIdLocked());
18984                //mUsageStatsService.noteStartConfig(newConfig);
18985
18986                final Configuration configCopy = new Configuration(mConfiguration);
18987
18988                // TODO: If our config changes, should we auto dismiss any currently
18989                // showing dialogs?
18990                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18991
18992                AttributeCache ac = AttributeCache.instance();
18993                if (ac != null) {
18994                    ac.updateConfiguration(configCopy);
18995                }
18996
18997                // Make sure all resources in our process are updated
18998                // right now, so that anyone who is going to retrieve
18999                // resource values after we return will be sure to get
19000                // the new ones.  This is especially important during
19001                // boot, where the first config change needs to guarantee
19002                // all resources have that config before following boot
19003                // code is executed.
19004                mSystemThread.applyConfigurationToResources(configCopy);
19005
19006                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19007                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19008                    msg.obj = new Configuration(configCopy);
19009                    msg.arg1 = userId;
19010                    mHandler.sendMessage(msg);
19011                }
19012
19013                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19014                if (isDensityChange) {
19015                    // Reset the unsupported display size dialog.
19016                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19017
19018                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19019                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19020                }
19021
19022                for (int i=mLruProcesses.size()-1; i>=0; i--) {
19023                    ProcessRecord app = mLruProcesses.get(i);
19024                    try {
19025                        if (app.thread != null) {
19026                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19027                                    + app.processName + " new config " + mConfiguration);
19028                            app.thread.scheduleConfigurationChanged(configCopy);
19029                        }
19030                    } catch (Exception e) {
19031                    }
19032                }
19033                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19034                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19035                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
19036                        | Intent.FLAG_RECEIVER_FOREGROUND);
19037                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19038                        null, AppOpsManager.OP_NONE, null, false, false,
19039                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19040                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19041                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19042                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19043	            if (initLocale || !mProcessesReady) {
19044                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19045                    }
19046                    broadcastIntentLocked(null, null, intent,
19047                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19048                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19049                }
19050            }
19051            // Update the configuration with WM first and check if any of the stacks need to be
19052            // resized due to the configuration change. If so, resize the stacks now and do any
19053            // relaunches if necessary. This way we don't need to relaunch again below in
19054            // ensureActivityConfigurationLocked().
19055            if (mWindowManager != null) {
19056                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19057                if (resizedStacks != null) {
19058                    for (int stackId : resizedStacks) {
19059                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19060                        mStackSupervisor.resizeStackLocked(
19061                                stackId, newBounds, null, null, false, false, deferResume);
19062                    }
19063                }
19064            }
19065        }
19066
19067        boolean kept = true;
19068        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19069        // mainStack is null during startup.
19070        if (mainStack != null) {
19071            if (changes != 0 && starting == null) {
19072                // If the configuration changed, and the caller is not already
19073                // in the process of starting an activity, then find the top
19074                // activity to check if its configuration needs to change.
19075                starting = mainStack.topRunningActivityLocked();
19076            }
19077
19078            if (starting != null) {
19079                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19080                // And we need to make sure at this point that all other activities
19081                // are made visible with the correct configuration.
19082                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19083                        !PRESERVE_WINDOWS);
19084            }
19085        }
19086        if (mWindowManager != null) {
19087            mWindowManager.continueSurfaceLayout();
19088        }
19089        return kept;
19090    }
19091
19092    /**
19093     * Decide based on the configuration whether we should shouw the ANR,
19094     * crash, etc dialogs.  The idea is that if there is no affordence to
19095     * press the on-screen buttons, or the user experience would be more
19096     * greatly impacted than the crash itself, we shouldn't show the dialog.
19097     *
19098     * A thought: SystemUI might also want to get told about this, the Power
19099     * dialog / global actions also might want different behaviors.
19100     */
19101    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19102        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19103                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19104                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19105        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19106        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19107                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19108        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19109    }
19110
19111    @Override
19112    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19113        synchronized (this) {
19114            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19115            if (srec != null) {
19116                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19117            }
19118        }
19119        return false;
19120    }
19121
19122    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19123            Intent resultData) {
19124
19125        synchronized (this) {
19126            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19127            if (r != null) {
19128                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19129            }
19130            return false;
19131        }
19132    }
19133
19134    public int getLaunchedFromUid(IBinder activityToken) {
19135        ActivityRecord srec;
19136        synchronized (this) {
19137            srec = ActivityRecord.forTokenLocked(activityToken);
19138        }
19139        if (srec == null) {
19140            return -1;
19141        }
19142        return srec.launchedFromUid;
19143    }
19144
19145    public String getLaunchedFromPackage(IBinder activityToken) {
19146        ActivityRecord srec;
19147        synchronized (this) {
19148            srec = ActivityRecord.forTokenLocked(activityToken);
19149        }
19150        if (srec == null) {
19151            return null;
19152        }
19153        return srec.launchedFromPackage;
19154    }
19155
19156    // =========================================================
19157    // LIFETIME MANAGEMENT
19158    // =========================================================
19159
19160    // Returns which broadcast queue the app is the current [or imminent] receiver
19161    // on, or 'null' if the app is not an active broadcast recipient.
19162    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19163        BroadcastRecord r = app.curReceiver;
19164        if (r != null) {
19165            return r.queue;
19166        }
19167
19168        // It's not the current receiver, but it might be starting up to become one
19169        synchronized (this) {
19170            for (BroadcastQueue queue : mBroadcastQueues) {
19171                r = queue.mPendingBroadcast;
19172                if (r != null && r.curApp == app) {
19173                    // found it; report which queue it's in
19174                    return queue;
19175                }
19176            }
19177        }
19178
19179        return null;
19180    }
19181
19182    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19183            int targetUid, ComponentName targetComponent, String targetProcess) {
19184        if (!mTrackingAssociations) {
19185            return null;
19186        }
19187        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19188                = mAssociations.get(targetUid);
19189        if (components == null) {
19190            components = new ArrayMap<>();
19191            mAssociations.put(targetUid, components);
19192        }
19193        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19194        if (sourceUids == null) {
19195            sourceUids = new SparseArray<>();
19196            components.put(targetComponent, sourceUids);
19197        }
19198        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19199        if (sourceProcesses == null) {
19200            sourceProcesses = new ArrayMap<>();
19201            sourceUids.put(sourceUid, sourceProcesses);
19202        }
19203        Association ass = sourceProcesses.get(sourceProcess);
19204        if (ass == null) {
19205            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19206                    targetProcess);
19207            sourceProcesses.put(sourceProcess, ass);
19208        }
19209        ass.mCount++;
19210        ass.mNesting++;
19211        if (ass.mNesting == 1) {
19212            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19213            ass.mLastState = sourceState;
19214        }
19215        return ass;
19216    }
19217
19218    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19219            ComponentName targetComponent) {
19220        if (!mTrackingAssociations) {
19221            return;
19222        }
19223        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19224                = mAssociations.get(targetUid);
19225        if (components == null) {
19226            return;
19227        }
19228        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19229        if (sourceUids == null) {
19230            return;
19231        }
19232        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19233        if (sourceProcesses == null) {
19234            return;
19235        }
19236        Association ass = sourceProcesses.get(sourceProcess);
19237        if (ass == null || ass.mNesting <= 0) {
19238            return;
19239        }
19240        ass.mNesting--;
19241        if (ass.mNesting == 0) {
19242            long uptime = SystemClock.uptimeMillis();
19243            ass.mTime += uptime - ass.mStartTime;
19244            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19245                    += uptime - ass.mLastStateUptime;
19246            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19247        }
19248    }
19249
19250    private void noteUidProcessState(final int uid, final int state) {
19251        mBatteryStatsService.noteUidProcessState(uid, state);
19252        if (mTrackingAssociations) {
19253            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19254                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19255                        = mAssociations.valueAt(i1);
19256                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19257                    SparseArray<ArrayMap<String, Association>> sourceUids
19258                            = targetComponents.valueAt(i2);
19259                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19260                    if (sourceProcesses != null) {
19261                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19262                            Association ass = sourceProcesses.valueAt(i4);
19263                            if (ass.mNesting >= 1) {
19264                                // currently associated
19265                                long uptime = SystemClock.uptimeMillis();
19266                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19267                                        += uptime - ass.mLastStateUptime;
19268                                ass.mLastState = state;
19269                                ass.mLastStateUptime = uptime;
19270                            }
19271                        }
19272                    }
19273                }
19274            }
19275        }
19276    }
19277
19278    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19279            boolean doingAll, long now) {
19280        if (mAdjSeq == app.adjSeq) {
19281            // This adjustment has already been computed.
19282            return app.curRawAdj;
19283        }
19284
19285        if (app.thread == null) {
19286            app.adjSeq = mAdjSeq;
19287            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19288            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19289            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19290        }
19291
19292        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19293        app.adjSource = null;
19294        app.adjTarget = null;
19295        app.empty = false;
19296        app.cached = false;
19297
19298        final int activitiesSize = app.activities.size();
19299
19300        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19301            // The max adjustment doesn't allow this app to be anything
19302            // below foreground, so it is not worth doing work for it.
19303            app.adjType = "fixed";
19304            app.adjSeq = mAdjSeq;
19305            app.curRawAdj = app.maxAdj;
19306            app.foregroundActivities = false;
19307            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19308            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19309            // System processes can do UI, and when they do we want to have
19310            // them trim their memory after the user leaves the UI.  To
19311            // facilitate this, here we need to determine whether or not it
19312            // is currently showing UI.
19313            app.systemNoUi = true;
19314            if (app == TOP_APP) {
19315                app.systemNoUi = false;
19316                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19317                app.adjType = "pers-top-activity";
19318            } else if (app.hasTopUi) {
19319                app.systemNoUi = false;
19320                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19321                app.adjType = "pers-top-ui";
19322            } else if (activitiesSize > 0) {
19323                for (int j = 0; j < activitiesSize; j++) {
19324                    final ActivityRecord r = app.activities.get(j);
19325                    if (r.visible) {
19326                        app.systemNoUi = false;
19327                    }
19328                }
19329            }
19330            if (!app.systemNoUi) {
19331                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19332            }
19333            return (app.curAdj=app.maxAdj);
19334        }
19335
19336        app.systemNoUi = false;
19337
19338        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19339
19340        // Determine the importance of the process, starting with most
19341        // important to least, and assign an appropriate OOM adjustment.
19342        int adj;
19343        int schedGroup;
19344        int procState;
19345        boolean foregroundActivities = false;
19346        BroadcastQueue queue;
19347        if (app == TOP_APP) {
19348            // The last app on the list is the foreground app.
19349            adj = ProcessList.FOREGROUND_APP_ADJ;
19350            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19351            app.adjType = "top-activity";
19352            foregroundActivities = true;
19353            procState = PROCESS_STATE_CUR_TOP;
19354        } else if (app.instrumentationClass != null) {
19355            // Don't want to kill running instrumentation.
19356            adj = ProcessList.FOREGROUND_APP_ADJ;
19357            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19358            app.adjType = "instrumentation";
19359            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19360        } else if ((queue = isReceivingBroadcast(app)) != null) {
19361            // An app that is currently receiving a broadcast also
19362            // counts as being in the foreground for OOM killer purposes.
19363            // It's placed in a sched group based on the nature of the
19364            // broadcast as reflected by which queue it's active in.
19365            adj = ProcessList.FOREGROUND_APP_ADJ;
19366            schedGroup = (queue == mFgBroadcastQueue)
19367                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19368            app.adjType = "broadcast";
19369            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19370        } else if (app.executingServices.size() > 0) {
19371            // An app that is currently executing a service callback also
19372            // counts as being in the foreground.
19373            adj = ProcessList.FOREGROUND_APP_ADJ;
19374            schedGroup = app.execServicesFg ?
19375                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19376            app.adjType = "exec-service";
19377            procState = ActivityManager.PROCESS_STATE_SERVICE;
19378            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19379        } else {
19380            // As far as we know the process is empty.  We may change our mind later.
19381            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19382            // At this point we don't actually know the adjustment.  Use the cached adj
19383            // value that the caller wants us to.
19384            adj = cachedAdj;
19385            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19386            app.cached = true;
19387            app.empty = true;
19388            app.adjType = "cch-empty";
19389        }
19390
19391        // Examine all activities if not already foreground.
19392        if (!foregroundActivities && activitiesSize > 0) {
19393            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19394            for (int j = 0; j < activitiesSize; j++) {
19395                final ActivityRecord r = app.activities.get(j);
19396                if (r.app != app) {
19397                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19398                            + " instead of expected " + app);
19399                    if (r.app == null || (r.app.uid == app.uid)) {
19400                        // Only fix things up when they look sane
19401                        r.app = app;
19402                    } else {
19403                        continue;
19404                    }
19405                }
19406                if (r.visible) {
19407                    // App has a visible activity; only upgrade adjustment.
19408                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19409                        adj = ProcessList.VISIBLE_APP_ADJ;
19410                        app.adjType = "visible";
19411                    }
19412                    if (procState > PROCESS_STATE_CUR_TOP) {
19413                        procState = PROCESS_STATE_CUR_TOP;
19414                    }
19415                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19416                    app.cached = false;
19417                    app.empty = false;
19418                    foregroundActivities = true;
19419                    if (r.task != null && minLayer > 0) {
19420                        final int layer = r.task.mLayerRank;
19421                        if (layer >= 0 && minLayer > layer) {
19422                            minLayer = layer;
19423                        }
19424                    }
19425                    break;
19426                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19427                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19428                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19429                        app.adjType = "pausing";
19430                    }
19431                    if (procState > PROCESS_STATE_CUR_TOP) {
19432                        procState = PROCESS_STATE_CUR_TOP;
19433                    }
19434                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19435                    app.cached = false;
19436                    app.empty = false;
19437                    foregroundActivities = true;
19438                } else if (r.state == ActivityState.STOPPING) {
19439                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19440                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19441                        app.adjType = "stopping";
19442                    }
19443                    // For the process state, we will at this point consider the
19444                    // process to be cached.  It will be cached either as an activity
19445                    // or empty depending on whether the activity is finishing.  We do
19446                    // this so that we can treat the process as cached for purposes of
19447                    // memory trimming (determing current memory level, trim command to
19448                    // send to process) since there can be an arbitrary number of stopping
19449                    // processes and they should soon all go into the cached state.
19450                    if (!r.finishing) {
19451                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19452                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19453                        }
19454                    }
19455                    app.cached = false;
19456                    app.empty = false;
19457                    foregroundActivities = true;
19458                } else {
19459                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19460                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19461                        app.adjType = "cch-act";
19462                    }
19463                }
19464            }
19465            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19466                adj += minLayer;
19467            }
19468        }
19469
19470        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19471                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19472            if (app.foregroundServices) {
19473                // The user is aware of this app, so make it visible.
19474                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19475                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19476                app.cached = false;
19477                app.adjType = "fg-service";
19478                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19479            } else if (app.forcingToForeground != null) {
19480                // The user is aware of this app, so make it visible.
19481                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19482                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19483                app.cached = false;
19484                app.adjType = "force-fg";
19485                app.adjSource = app.forcingToForeground;
19486                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19487            }
19488        }
19489
19490        if (app == mHeavyWeightProcess) {
19491            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19492                // We don't want to kill the current heavy-weight process.
19493                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19494                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19495                app.cached = false;
19496                app.adjType = "heavy";
19497            }
19498            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19499                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19500            }
19501        }
19502
19503        if (app == mHomeProcess) {
19504            if (adj > ProcessList.HOME_APP_ADJ) {
19505                // This process is hosting what we currently consider to be the
19506                // home app, so we don't want to let it go into the background.
19507                adj = ProcessList.HOME_APP_ADJ;
19508                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19509                app.cached = false;
19510                app.adjType = "home";
19511            }
19512            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19513                procState = ActivityManager.PROCESS_STATE_HOME;
19514            }
19515        }
19516
19517        if (app == mPreviousProcess && app.activities.size() > 0) {
19518            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19519                // This was the previous process that showed UI to the user.
19520                // We want to try to keep it around more aggressively, to give
19521                // a good experience around switching between two apps.
19522                adj = ProcessList.PREVIOUS_APP_ADJ;
19523                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19524                app.cached = false;
19525                app.adjType = "previous";
19526            }
19527            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19528                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19529            }
19530        }
19531
19532        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19533                + " reason=" + app.adjType);
19534
19535        // By default, we use the computed adjustment.  It may be changed if
19536        // there are applications dependent on our services or providers, but
19537        // this gives us a baseline and makes sure we don't get into an
19538        // infinite recursion.
19539        app.adjSeq = mAdjSeq;
19540        app.curRawAdj = adj;
19541        app.hasStartedServices = false;
19542
19543        if (mBackupTarget != null && app == mBackupTarget.app) {
19544            // If possible we want to avoid killing apps while they're being backed up
19545            if (adj > ProcessList.BACKUP_APP_ADJ) {
19546                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19547                adj = ProcessList.BACKUP_APP_ADJ;
19548                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19549                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19550                }
19551                app.adjType = "backup";
19552                app.cached = false;
19553            }
19554            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19555                procState = ActivityManager.PROCESS_STATE_BACKUP;
19556            }
19557        }
19558
19559        boolean mayBeTop = false;
19560
19561        for (int is = app.services.size()-1;
19562                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19563                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19564                        || procState > ActivityManager.PROCESS_STATE_TOP);
19565                is--) {
19566            ServiceRecord s = app.services.valueAt(is);
19567            if (s.startRequested) {
19568                app.hasStartedServices = true;
19569                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19570                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19571                }
19572                if (app.hasShownUi && app != mHomeProcess) {
19573                    // If this process has shown some UI, let it immediately
19574                    // go to the LRU list because it may be pretty heavy with
19575                    // UI stuff.  We'll tag it with a label just to help
19576                    // debug and understand what is going on.
19577                    if (adj > ProcessList.SERVICE_ADJ) {
19578                        app.adjType = "cch-started-ui-services";
19579                    }
19580                } else {
19581                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19582                        // This service has seen some activity within
19583                        // recent memory, so we will keep its process ahead
19584                        // of the background processes.
19585                        if (adj > ProcessList.SERVICE_ADJ) {
19586                            adj = ProcessList.SERVICE_ADJ;
19587                            app.adjType = "started-services";
19588                            app.cached = false;
19589                        }
19590                    }
19591                    // If we have let the service slide into the background
19592                    // state, still have some text describing what it is doing
19593                    // even though the service no longer has an impact.
19594                    if (adj > ProcessList.SERVICE_ADJ) {
19595                        app.adjType = "cch-started-services";
19596                    }
19597                }
19598            }
19599
19600            for (int conni = s.connections.size()-1;
19601                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19602                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19603                            || procState > ActivityManager.PROCESS_STATE_TOP);
19604                    conni--) {
19605                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19606                for (int i = 0;
19607                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19608                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19609                                || procState > ActivityManager.PROCESS_STATE_TOP);
19610                        i++) {
19611                    // XXX should compute this based on the max of
19612                    // all connected clients.
19613                    ConnectionRecord cr = clist.get(i);
19614                    if (cr.binding.client == app) {
19615                        // Binding to ourself is not interesting.
19616                        continue;
19617                    }
19618
19619                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19620                        ProcessRecord client = cr.binding.client;
19621                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19622                                TOP_APP, doingAll, now);
19623                        int clientProcState = client.curProcState;
19624                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19625                            // If the other app is cached for any reason, for purposes here
19626                            // we are going to consider it empty.  The specific cached state
19627                            // doesn't propagate except under certain conditions.
19628                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19629                        }
19630                        String adjType = null;
19631                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19632                            // Not doing bind OOM management, so treat
19633                            // this guy more like a started service.
19634                            if (app.hasShownUi && app != mHomeProcess) {
19635                                // If this process has shown some UI, let it immediately
19636                                // go to the LRU list because it may be pretty heavy with
19637                                // UI stuff.  We'll tag it with a label just to help
19638                                // debug and understand what is going on.
19639                                if (adj > clientAdj) {
19640                                    adjType = "cch-bound-ui-services";
19641                                }
19642                                app.cached = false;
19643                                clientAdj = adj;
19644                                clientProcState = procState;
19645                            } else {
19646                                if (now >= (s.lastActivity
19647                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19648                                    // This service has not seen activity within
19649                                    // recent memory, so allow it to drop to the
19650                                    // LRU list if there is no other reason to keep
19651                                    // it around.  We'll also tag it with a label just
19652                                    // to help debug and undertand what is going on.
19653                                    if (adj > clientAdj) {
19654                                        adjType = "cch-bound-services";
19655                                    }
19656                                    clientAdj = adj;
19657                                }
19658                            }
19659                        }
19660                        if (adj > clientAdj) {
19661                            // If this process has recently shown UI, and
19662                            // the process that is binding to it is less
19663                            // important than being visible, then we don't
19664                            // care about the binding as much as we care
19665                            // about letting this process get into the LRU
19666                            // list to be killed and restarted if needed for
19667                            // memory.
19668                            if (app.hasShownUi && app != mHomeProcess
19669                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19670                                adjType = "cch-bound-ui-services";
19671                            } else {
19672                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19673                                        |Context.BIND_IMPORTANT)) != 0) {
19674                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19675                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19676                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19677                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19678                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19679                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19680                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19681                                    adj = clientAdj;
19682                                } else {
19683                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19684                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19685                                    }
19686                                }
19687                                if (!client.cached) {
19688                                    app.cached = false;
19689                                }
19690                                adjType = "service";
19691                            }
19692                        }
19693                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19694                            // This will treat important bound services identically to
19695                            // the top app, which may behave differently than generic
19696                            // foreground work.
19697                            if (client.curSchedGroup > schedGroup) {
19698                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19699                                    schedGroup = client.curSchedGroup;
19700                                } else {
19701                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19702                                }
19703                            }
19704                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19705                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19706                                    // Special handling of clients who are in the top state.
19707                                    // We *may* want to consider this process to be in the
19708                                    // top state as well, but only if there is not another
19709                                    // reason for it to be running.  Being on the top is a
19710                                    // special state, meaning you are specifically running
19711                                    // for the current top app.  If the process is already
19712                                    // running in the background for some other reason, it
19713                                    // is more important to continue considering it to be
19714                                    // in the background state.
19715                                    mayBeTop = true;
19716                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19717                                } else {
19718                                    // Special handling for above-top states (persistent
19719                                    // processes).  These should not bring the current process
19720                                    // into the top state, since they are not on top.  Instead
19721                                    // give them the best state after that.
19722                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19723                                        clientProcState =
19724                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19725                                    } else if (mWakefulness
19726                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19727                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19728                                                    != 0) {
19729                                        clientProcState =
19730                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19731                                    } else {
19732                                        clientProcState =
19733                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19734                                    }
19735                                }
19736                            }
19737                        } else {
19738                            if (clientProcState <
19739                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19740                                clientProcState =
19741                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19742                            }
19743                        }
19744                        if (procState > clientProcState) {
19745                            procState = clientProcState;
19746                        }
19747                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19748                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19749                            app.pendingUiClean = true;
19750                        }
19751                        if (adjType != null) {
19752                            app.adjType = adjType;
19753                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19754                                    .REASON_SERVICE_IN_USE;
19755                            app.adjSource = cr.binding.client;
19756                            app.adjSourceProcState = clientProcState;
19757                            app.adjTarget = s.name;
19758                        }
19759                    }
19760                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19761                        app.treatLikeActivity = true;
19762                    }
19763                    final ActivityRecord a = cr.activity;
19764                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19765                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19766                            (a.visible || a.state == ActivityState.RESUMED ||
19767                             a.state == ActivityState.PAUSING)) {
19768                            adj = ProcessList.FOREGROUND_APP_ADJ;
19769                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19770                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19771                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19772                                } else {
19773                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19774                                }
19775                            }
19776                            app.cached = false;
19777                            app.adjType = "service";
19778                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19779                                    .REASON_SERVICE_IN_USE;
19780                            app.adjSource = a;
19781                            app.adjSourceProcState = procState;
19782                            app.adjTarget = s.name;
19783                        }
19784                    }
19785                }
19786            }
19787        }
19788
19789        for (int provi = app.pubProviders.size()-1;
19790                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19791                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19792                        || procState > ActivityManager.PROCESS_STATE_TOP);
19793                provi--) {
19794            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19795            for (int i = cpr.connections.size()-1;
19796                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19797                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19798                            || procState > ActivityManager.PROCESS_STATE_TOP);
19799                    i--) {
19800                ContentProviderConnection conn = cpr.connections.get(i);
19801                ProcessRecord client = conn.client;
19802                if (client == app) {
19803                    // Being our own client is not interesting.
19804                    continue;
19805                }
19806                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19807                int clientProcState = client.curProcState;
19808                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19809                    // If the other app is cached for any reason, for purposes here
19810                    // we are going to consider it empty.
19811                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19812                }
19813                if (adj > clientAdj) {
19814                    if (app.hasShownUi && app != mHomeProcess
19815                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19816                        app.adjType = "cch-ui-provider";
19817                    } else {
19818                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19819                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19820                        app.adjType = "provider";
19821                    }
19822                    app.cached &= client.cached;
19823                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19824                            .REASON_PROVIDER_IN_USE;
19825                    app.adjSource = client;
19826                    app.adjSourceProcState = clientProcState;
19827                    app.adjTarget = cpr.name;
19828                }
19829                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19830                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19831                        // Special handling of clients who are in the top state.
19832                        // We *may* want to consider this process to be in the
19833                        // top state as well, but only if there is not another
19834                        // reason for it to be running.  Being on the top is a
19835                        // special state, meaning you are specifically running
19836                        // for the current top app.  If the process is already
19837                        // running in the background for some other reason, it
19838                        // is more important to continue considering it to be
19839                        // in the background state.
19840                        mayBeTop = true;
19841                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19842                    } else {
19843                        // Special handling for above-top states (persistent
19844                        // processes).  These should not bring the current process
19845                        // into the top state, since they are not on top.  Instead
19846                        // give them the best state after that.
19847                        clientProcState =
19848                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19849                    }
19850                }
19851                if (procState > clientProcState) {
19852                    procState = clientProcState;
19853                }
19854                if (client.curSchedGroup > schedGroup) {
19855                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19856                }
19857            }
19858            // If the provider has external (non-framework) process
19859            // dependencies, ensure that its adjustment is at least
19860            // FOREGROUND_APP_ADJ.
19861            if (cpr.hasExternalProcessHandles()) {
19862                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19863                    adj = ProcessList.FOREGROUND_APP_ADJ;
19864                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19865                    app.cached = false;
19866                    app.adjType = "provider";
19867                    app.adjTarget = cpr.name;
19868                }
19869                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19870                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19871                }
19872            }
19873        }
19874
19875        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19876            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19877                adj = ProcessList.PREVIOUS_APP_ADJ;
19878                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19879                app.cached = false;
19880                app.adjType = "provider";
19881            }
19882            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19883                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19884            }
19885        }
19886
19887        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19888            // A client of one of our services or providers is in the top state.  We
19889            // *may* want to be in the top state, but not if we are already running in
19890            // the background for some other reason.  For the decision here, we are going
19891            // to pick out a few specific states that we want to remain in when a client
19892            // is top (states that tend to be longer-term) and otherwise allow it to go
19893            // to the top state.
19894            switch (procState) {
19895                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19896                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19897                case ActivityManager.PROCESS_STATE_SERVICE:
19898                    // These all are longer-term states, so pull them up to the top
19899                    // of the background states, but not all the way to the top state.
19900                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19901                    break;
19902                default:
19903                    // Otherwise, top is a better choice, so take it.
19904                    procState = ActivityManager.PROCESS_STATE_TOP;
19905                    break;
19906            }
19907        }
19908
19909        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19910            if (app.hasClientActivities) {
19911                // This is a cached process, but with client activities.  Mark it so.
19912                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19913                app.adjType = "cch-client-act";
19914            } else if (app.treatLikeActivity) {
19915                // This is a cached process, but somebody wants us to treat it like it has
19916                // an activity, okay!
19917                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19918                app.adjType = "cch-as-act";
19919            }
19920        }
19921
19922        if (adj == ProcessList.SERVICE_ADJ) {
19923            if (doingAll) {
19924                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19925                mNewNumServiceProcs++;
19926                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19927                if (!app.serviceb) {
19928                    // This service isn't far enough down on the LRU list to
19929                    // normally be a B service, but if we are low on RAM and it
19930                    // is large we want to force it down since we would prefer to
19931                    // keep launcher over it.
19932                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19933                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19934                        app.serviceHighRam = true;
19935                        app.serviceb = true;
19936                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19937                    } else {
19938                        mNewNumAServiceProcs++;
19939                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19940                    }
19941                } else {
19942                    app.serviceHighRam = false;
19943                }
19944            }
19945            if (app.serviceb) {
19946                adj = ProcessList.SERVICE_B_ADJ;
19947            }
19948        }
19949
19950        app.curRawAdj = adj;
19951
19952        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19953        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19954        if (adj > app.maxAdj) {
19955            adj = app.maxAdj;
19956            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19957                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19958            }
19959        }
19960
19961        // Do final modification to adj.  Everything we do between here and applying
19962        // the final setAdj must be done in this function, because we will also use
19963        // it when computing the final cached adj later.  Note that we don't need to
19964        // worry about this for max adj above, since max adj will always be used to
19965        // keep it out of the cached vaues.
19966        app.curAdj = app.modifyRawOomAdj(adj);
19967        app.curSchedGroup = schedGroup;
19968        app.curProcState = procState;
19969        app.foregroundActivities = foregroundActivities;
19970
19971        return app.curRawAdj;
19972    }
19973
19974    /**
19975     * Record new PSS sample for a process.
19976     */
19977    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19978            long now) {
19979        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19980                swapPss * 1024);
19981        proc.lastPssTime = now;
19982        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19983        if (DEBUG_PSS) Slog.d(TAG_PSS,
19984                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19985                + " state=" + ProcessList.makeProcStateString(procState));
19986        if (proc.initialIdlePss == 0) {
19987            proc.initialIdlePss = pss;
19988        }
19989        proc.lastPss = pss;
19990        proc.lastSwapPss = swapPss;
19991        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19992            proc.lastCachedPss = pss;
19993            proc.lastCachedSwapPss = swapPss;
19994        }
19995
19996        final SparseArray<Pair<Long, String>> watchUids
19997                = mMemWatchProcesses.getMap().get(proc.processName);
19998        Long check = null;
19999        if (watchUids != null) {
20000            Pair<Long, String> val = watchUids.get(proc.uid);
20001            if (val == null) {
20002                val = watchUids.get(0);
20003            }
20004            if (val != null) {
20005                check = val.first;
20006            }
20007        }
20008        if (check != null) {
20009            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20010                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20011                if (!isDebuggable) {
20012                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20013                        isDebuggable = true;
20014                    }
20015                }
20016                if (isDebuggable) {
20017                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20018                    final ProcessRecord myProc = proc;
20019                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20020                    mMemWatchDumpProcName = proc.processName;
20021                    mMemWatchDumpFile = heapdumpFile.toString();
20022                    mMemWatchDumpPid = proc.pid;
20023                    mMemWatchDumpUid = proc.uid;
20024                    BackgroundThread.getHandler().post(new Runnable() {
20025                        @Override
20026                        public void run() {
20027                            revokeUriPermission(ActivityThread.currentActivityThread()
20028                                            .getApplicationThread(),
20029                                    DumpHeapActivity.JAVA_URI,
20030                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20031                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20032                                    UserHandle.myUserId());
20033                            ParcelFileDescriptor fd = null;
20034                            try {
20035                                heapdumpFile.delete();
20036                                fd = ParcelFileDescriptor.open(heapdumpFile,
20037                                        ParcelFileDescriptor.MODE_CREATE |
20038                                                ParcelFileDescriptor.MODE_TRUNCATE |
20039                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20040                                                ParcelFileDescriptor.MODE_APPEND);
20041                                IApplicationThread thread = myProc.thread;
20042                                if (thread != null) {
20043                                    try {
20044                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20045                                                "Requesting dump heap from "
20046                                                + myProc + " to " + heapdumpFile);
20047                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20048                                    } catch (RemoteException e) {
20049                                    }
20050                                }
20051                            } catch (FileNotFoundException e) {
20052                                e.printStackTrace();
20053                            } finally {
20054                                if (fd != null) {
20055                                    try {
20056                                        fd.close();
20057                                    } catch (IOException e) {
20058                                    }
20059                                }
20060                            }
20061                        }
20062                    });
20063                } else {
20064                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20065                            + ", but debugging not enabled");
20066                }
20067            }
20068        }
20069    }
20070
20071    /**
20072     * Schedule PSS collection of a process.
20073     */
20074    void requestPssLocked(ProcessRecord proc, int procState) {
20075        if (mPendingPssProcesses.contains(proc)) {
20076            return;
20077        }
20078        if (mPendingPssProcesses.size() == 0) {
20079            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20080        }
20081        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20082        proc.pssProcState = procState;
20083        mPendingPssProcesses.add(proc);
20084    }
20085
20086    /**
20087     * Schedule PSS collection of all processes.
20088     */
20089    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20090        if (!always) {
20091            if (now < (mLastFullPssTime +
20092                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20093                return;
20094            }
20095        }
20096        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20097        mLastFullPssTime = now;
20098        mFullPssPending = true;
20099        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20100        mPendingPssProcesses.clear();
20101        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20102            ProcessRecord app = mLruProcesses.get(i);
20103            if (app.thread == null
20104                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20105                continue;
20106            }
20107            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20108                app.pssProcState = app.setProcState;
20109                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20110                        mTestPssMode, isSleepingLocked(), now);
20111                mPendingPssProcesses.add(app);
20112            }
20113        }
20114        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20115    }
20116
20117    public void setTestPssMode(boolean enabled) {
20118        synchronized (this) {
20119            mTestPssMode = enabled;
20120            if (enabled) {
20121                // Whenever we enable the mode, we want to take a snapshot all of current
20122                // process mem use.
20123                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20124            }
20125        }
20126    }
20127
20128    /**
20129     * Ask a given process to GC right now.
20130     */
20131    final void performAppGcLocked(ProcessRecord app) {
20132        try {
20133            app.lastRequestedGc = SystemClock.uptimeMillis();
20134            if (app.thread != null) {
20135                if (app.reportLowMemory) {
20136                    app.reportLowMemory = false;
20137                    app.thread.scheduleLowMemory();
20138                } else {
20139                    app.thread.processInBackground();
20140                }
20141            }
20142        } catch (Exception e) {
20143            // whatever.
20144        }
20145    }
20146
20147    /**
20148     * Returns true if things are idle enough to perform GCs.
20149     */
20150    private final boolean canGcNowLocked() {
20151        boolean processingBroadcasts = false;
20152        for (BroadcastQueue q : mBroadcastQueues) {
20153            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20154                processingBroadcasts = true;
20155            }
20156        }
20157        return !processingBroadcasts
20158                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20159    }
20160
20161    /**
20162     * Perform GCs on all processes that are waiting for it, but only
20163     * if things are idle.
20164     */
20165    final void performAppGcsLocked() {
20166        final int N = mProcessesToGc.size();
20167        if (N <= 0) {
20168            return;
20169        }
20170        if (canGcNowLocked()) {
20171            while (mProcessesToGc.size() > 0) {
20172                ProcessRecord proc = mProcessesToGc.remove(0);
20173                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20174                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20175                            <= SystemClock.uptimeMillis()) {
20176                        // To avoid spamming the system, we will GC processes one
20177                        // at a time, waiting a few seconds between each.
20178                        performAppGcLocked(proc);
20179                        scheduleAppGcsLocked();
20180                        return;
20181                    } else {
20182                        // It hasn't been long enough since we last GCed this
20183                        // process...  put it in the list to wait for its time.
20184                        addProcessToGcListLocked(proc);
20185                        break;
20186                    }
20187                }
20188            }
20189
20190            scheduleAppGcsLocked();
20191        }
20192    }
20193
20194    /**
20195     * If all looks good, perform GCs on all processes waiting for them.
20196     */
20197    final void performAppGcsIfAppropriateLocked() {
20198        if (canGcNowLocked()) {
20199            performAppGcsLocked();
20200            return;
20201        }
20202        // Still not idle, wait some more.
20203        scheduleAppGcsLocked();
20204    }
20205
20206    /**
20207     * Schedule the execution of all pending app GCs.
20208     */
20209    final void scheduleAppGcsLocked() {
20210        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20211
20212        if (mProcessesToGc.size() > 0) {
20213            // Schedule a GC for the time to the next process.
20214            ProcessRecord proc = mProcessesToGc.get(0);
20215            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20216
20217            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20218            long now = SystemClock.uptimeMillis();
20219            if (when < (now+GC_TIMEOUT)) {
20220                when = now + GC_TIMEOUT;
20221            }
20222            mHandler.sendMessageAtTime(msg, when);
20223        }
20224    }
20225
20226    /**
20227     * Add a process to the array of processes waiting to be GCed.  Keeps the
20228     * list in sorted order by the last GC time.  The process can't already be
20229     * on the list.
20230     */
20231    final void addProcessToGcListLocked(ProcessRecord proc) {
20232        boolean added = false;
20233        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20234            if (mProcessesToGc.get(i).lastRequestedGc <
20235                    proc.lastRequestedGc) {
20236                added = true;
20237                mProcessesToGc.add(i+1, proc);
20238                break;
20239            }
20240        }
20241        if (!added) {
20242            mProcessesToGc.add(0, proc);
20243        }
20244    }
20245
20246    /**
20247     * Set up to ask a process to GC itself.  This will either do it
20248     * immediately, or put it on the list of processes to gc the next
20249     * time things are idle.
20250     */
20251    final void scheduleAppGcLocked(ProcessRecord app) {
20252        long now = SystemClock.uptimeMillis();
20253        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20254            return;
20255        }
20256        if (!mProcessesToGc.contains(app)) {
20257            addProcessToGcListLocked(app);
20258            scheduleAppGcsLocked();
20259        }
20260    }
20261
20262    final void checkExcessivePowerUsageLocked(boolean doKills) {
20263        updateCpuStatsNow();
20264
20265        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20266        boolean doWakeKills = doKills;
20267        boolean doCpuKills = doKills;
20268        if (mLastPowerCheckRealtime == 0) {
20269            doWakeKills = false;
20270        }
20271        if (mLastPowerCheckUptime == 0) {
20272            doCpuKills = false;
20273        }
20274        if (stats.isScreenOn()) {
20275            doWakeKills = false;
20276        }
20277        final long curRealtime = SystemClock.elapsedRealtime();
20278        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20279        final long curUptime = SystemClock.uptimeMillis();
20280        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20281        mLastPowerCheckRealtime = curRealtime;
20282        mLastPowerCheckUptime = curUptime;
20283        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20284            doWakeKills = false;
20285        }
20286        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20287            doCpuKills = false;
20288        }
20289        int i = mLruProcesses.size();
20290        while (i > 0) {
20291            i--;
20292            ProcessRecord app = mLruProcesses.get(i);
20293            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20294                long wtime;
20295                synchronized (stats) {
20296                    wtime = stats.getProcessWakeTime(app.info.uid,
20297                            app.pid, curRealtime);
20298                }
20299                long wtimeUsed = wtime - app.lastWakeTime;
20300                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20301                if (DEBUG_POWER) {
20302                    StringBuilder sb = new StringBuilder(128);
20303                    sb.append("Wake for ");
20304                    app.toShortString(sb);
20305                    sb.append(": over ");
20306                    TimeUtils.formatDuration(realtimeSince, sb);
20307                    sb.append(" used ");
20308                    TimeUtils.formatDuration(wtimeUsed, sb);
20309                    sb.append(" (");
20310                    sb.append((wtimeUsed*100)/realtimeSince);
20311                    sb.append("%)");
20312                    Slog.i(TAG_POWER, sb.toString());
20313                    sb.setLength(0);
20314                    sb.append("CPU for ");
20315                    app.toShortString(sb);
20316                    sb.append(": over ");
20317                    TimeUtils.formatDuration(uptimeSince, sb);
20318                    sb.append(" used ");
20319                    TimeUtils.formatDuration(cputimeUsed, sb);
20320                    sb.append(" (");
20321                    sb.append((cputimeUsed*100)/uptimeSince);
20322                    sb.append("%)");
20323                    Slog.i(TAG_POWER, sb.toString());
20324                }
20325                // If a process has held a wake lock for more
20326                // than 50% of the time during this period,
20327                // that sounds bad.  Kill!
20328                if (doWakeKills && realtimeSince > 0
20329                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20330                    synchronized (stats) {
20331                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20332                                realtimeSince, wtimeUsed);
20333                    }
20334                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20335                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20336                } else if (doCpuKills && uptimeSince > 0
20337                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20338                    synchronized (stats) {
20339                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20340                                uptimeSince, cputimeUsed);
20341                    }
20342                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20343                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20344                } else {
20345                    app.lastWakeTime = wtime;
20346                    app.lastCpuTime = app.curCpuTime;
20347                }
20348            }
20349        }
20350    }
20351
20352    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20353            long nowElapsed) {
20354        boolean success = true;
20355
20356        if (app.curRawAdj != app.setRawAdj) {
20357            app.setRawAdj = app.curRawAdj;
20358        }
20359
20360        int changes = 0;
20361
20362        if (app.curAdj != app.setAdj) {
20363            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20364            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20365                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20366                    + app.adjType);
20367            app.setAdj = app.curAdj;
20368            app.verifiedAdj = ProcessList.INVALID_ADJ;
20369        }
20370
20371        if (app.setSchedGroup != app.curSchedGroup) {
20372            int oldSchedGroup = app.setSchedGroup;
20373            app.setSchedGroup = app.curSchedGroup;
20374            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20375                    "Setting sched group of " + app.processName
20376                    + " to " + app.curSchedGroup);
20377            if (app.waitingToKill != null && app.curReceiver == null
20378                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20379                app.kill(app.waitingToKill, true);
20380                success = false;
20381            } else {
20382                int processGroup;
20383                switch (app.curSchedGroup) {
20384                    case ProcessList.SCHED_GROUP_BACKGROUND:
20385                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20386                        break;
20387                    case ProcessList.SCHED_GROUP_TOP_APP:
20388                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20389                        processGroup = Process.THREAD_GROUP_TOP_APP;
20390                        break;
20391                    default:
20392                        processGroup = Process.THREAD_GROUP_DEFAULT;
20393                        break;
20394                }
20395                long oldId = Binder.clearCallingIdentity();
20396                try {
20397                    Process.setProcessGroup(app.pid, processGroup);
20398                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20399                        // do nothing if we already switched to RT
20400                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20401                            // Switch VR thread for app to SCHED_FIFO
20402                            if (mInVrMode && app.vrThreadTid != 0) {
20403                                try {
20404                                    Process.setThreadScheduler(app.vrThreadTid,
20405                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20406                                } catch (IllegalArgumentException e) {
20407                                    // thread died, ignore
20408                                }
20409                            }
20410                            if (mUseFifoUiScheduling) {
20411                                // Switch UI pipeline for app to SCHED_FIFO
20412                                app.savedPriority = Process.getThreadPriority(app.pid);
20413                                try {
20414                                    Process.setThreadScheduler(app.pid,
20415                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20416                                } catch (IllegalArgumentException e) {
20417                                    // thread died, ignore
20418                                }
20419                                if (app.renderThreadTid != 0) {
20420                                    try {
20421                                        Process.setThreadScheduler(app.renderThreadTid,
20422                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20423                                    } catch (IllegalArgumentException e) {
20424                                        // thread died, ignore
20425                                    }
20426                                    if (DEBUG_OOM_ADJ) {
20427                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20428                                            app.renderThreadTid + ") to FIFO");
20429                                    }
20430                                } else {
20431                                    if (DEBUG_OOM_ADJ) {
20432                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20433                                    }
20434                                }
20435                            } else {
20436                                // Boost priority for top app UI and render threads
20437                                Process.setThreadPriority(app.pid, -10);
20438                                if (app.renderThreadTid != 0) {
20439                                    try {
20440                                        Process.setThreadPriority(app.renderThreadTid, -10);
20441                                    } catch (IllegalArgumentException e) {
20442                                        // thread died, ignore
20443                                    }
20444                                }
20445                            }
20446                        }
20447                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20448                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20449                        // Reset VR thread to SCHED_OTHER
20450                        // Safe to do even if we're not in VR mode
20451                        if (app.vrThreadTid != 0) {
20452                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20453                        }
20454                        if (mUseFifoUiScheduling) {
20455                            // Reset UI pipeline to SCHED_OTHER
20456                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20457                            Process.setThreadPriority(app.pid, app.savedPriority);
20458                            if (app.renderThreadTid != 0) {
20459                                Process.setThreadScheduler(app.renderThreadTid,
20460                                    Process.SCHED_OTHER, 0);
20461                                Process.setThreadPriority(app.renderThreadTid, -4);
20462                            }
20463                        } else {
20464                            // Reset priority for top app UI and render threads
20465                            Process.setThreadPriority(app.pid, 0);
20466                            if (app.renderThreadTid != 0) {
20467                                Process.setThreadPriority(app.renderThreadTid, 0);
20468                            }
20469                        }
20470                    }
20471                } catch (Exception e) {
20472                    Slog.w(TAG, "Failed setting process group of " + app.pid
20473                            + " to " + app.curSchedGroup);
20474                    e.printStackTrace();
20475                } finally {
20476                    Binder.restoreCallingIdentity(oldId);
20477                }
20478            }
20479        }
20480        if (app.repForegroundActivities != app.foregroundActivities) {
20481            app.repForegroundActivities = app.foregroundActivities;
20482            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20483        }
20484        if (app.repProcState != app.curProcState) {
20485            app.repProcState = app.curProcState;
20486            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20487            if (app.thread != null) {
20488                try {
20489                    if (false) {
20490                        //RuntimeException h = new RuntimeException("here");
20491                        Slog.i(TAG, "Sending new process state " + app.repProcState
20492                                + " to " + app /*, h*/);
20493                    }
20494                    app.thread.setProcessState(app.repProcState);
20495                } catch (RemoteException e) {
20496                }
20497            }
20498        }
20499        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20500                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20501            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20502                // Experimental code to more aggressively collect pss while
20503                // running test...  the problem is that this tends to collect
20504                // the data right when a process is transitioning between process
20505                // states, which well tend to give noisy data.
20506                long start = SystemClock.uptimeMillis();
20507                long pss = Debug.getPss(app.pid, mTmpLong, null);
20508                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20509                mPendingPssProcesses.remove(app);
20510                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20511                        + " to " + app.curProcState + ": "
20512                        + (SystemClock.uptimeMillis()-start) + "ms");
20513            }
20514            app.lastStateTime = now;
20515            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20516                    mTestPssMode, isSleepingLocked(), now);
20517            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20518                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20519                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20520                    + (app.nextPssTime-now) + ": " + app);
20521        } else {
20522            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20523                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20524                    mTestPssMode)))) {
20525                requestPssLocked(app, app.setProcState);
20526                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20527                        mTestPssMode, isSleepingLocked(), now);
20528            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20529                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20530        }
20531        if (app.setProcState != app.curProcState) {
20532            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20533                    "Proc state change of " + app.processName
20534                            + " to " + app.curProcState);
20535            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20536            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20537            if (setImportant && !curImportant) {
20538                // This app is no longer something we consider important enough to allow to
20539                // use arbitrary amounts of battery power.  Note
20540                // its current wake lock time to later know to kill it if
20541                // it is not behaving well.
20542                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20543                synchronized (stats) {
20544                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20545                            app.pid, nowElapsed);
20546                }
20547                app.lastCpuTime = app.curCpuTime;
20548
20549            }
20550            // Inform UsageStats of important process state change
20551            // Must be called before updating setProcState
20552            maybeUpdateUsageStatsLocked(app, nowElapsed);
20553
20554            app.setProcState = app.curProcState;
20555            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20556                app.notCachedSinceIdle = false;
20557            }
20558            if (!doingAll) {
20559                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20560            } else {
20561                app.procStateChanged = true;
20562            }
20563        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20564                > USAGE_STATS_INTERACTION_INTERVAL) {
20565            // For apps that sit around for a long time in the interactive state, we need
20566            // to report this at least once a day so they don't go idle.
20567            maybeUpdateUsageStatsLocked(app, nowElapsed);
20568        }
20569
20570        if (changes != 0) {
20571            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20572                    "Changes in " + app + ": " + changes);
20573            int i = mPendingProcessChanges.size()-1;
20574            ProcessChangeItem item = null;
20575            while (i >= 0) {
20576                item = mPendingProcessChanges.get(i);
20577                if (item.pid == app.pid) {
20578                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20579                            "Re-using existing item: " + item);
20580                    break;
20581                }
20582                i--;
20583            }
20584            if (i < 0) {
20585                // No existing item in pending changes; need a new one.
20586                final int NA = mAvailProcessChanges.size();
20587                if (NA > 0) {
20588                    item = mAvailProcessChanges.remove(NA-1);
20589                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20590                            "Retrieving available item: " + item);
20591                } else {
20592                    item = new ProcessChangeItem();
20593                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20594                            "Allocating new item: " + item);
20595                }
20596                item.changes = 0;
20597                item.pid = app.pid;
20598                item.uid = app.info.uid;
20599                if (mPendingProcessChanges.size() == 0) {
20600                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20601                            "*** Enqueueing dispatch processes changed!");
20602                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20603                }
20604                mPendingProcessChanges.add(item);
20605            }
20606            item.changes |= changes;
20607            item.processState = app.repProcState;
20608            item.foregroundActivities = app.repForegroundActivities;
20609            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20610                    "Item " + Integer.toHexString(System.identityHashCode(item))
20611                    + " " + app.toShortString() + ": changes=" + item.changes
20612                    + " procState=" + item.processState
20613                    + " foreground=" + item.foregroundActivities
20614                    + " type=" + app.adjType + " source=" + app.adjSource
20615                    + " target=" + app.adjTarget);
20616        }
20617
20618        return success;
20619    }
20620
20621    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20622        final UidRecord.ChangeItem pendingChange;
20623        if (uidRec == null || uidRec.pendingChange == null) {
20624            if (mPendingUidChanges.size() == 0) {
20625                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20626                        "*** Enqueueing dispatch uid changed!");
20627                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20628            }
20629            final int NA = mAvailUidChanges.size();
20630            if (NA > 0) {
20631                pendingChange = mAvailUidChanges.remove(NA-1);
20632                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20633                        "Retrieving available item: " + pendingChange);
20634            } else {
20635                pendingChange = new UidRecord.ChangeItem();
20636                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20637                        "Allocating new item: " + pendingChange);
20638            }
20639            if (uidRec != null) {
20640                uidRec.pendingChange = pendingChange;
20641                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20642                    // If this uid is going away, and we haven't yet reported it is gone,
20643                    // then do so now.
20644                    change = UidRecord.CHANGE_GONE_IDLE;
20645                }
20646            } else if (uid < 0) {
20647                throw new IllegalArgumentException("No UidRecord or uid");
20648            }
20649            pendingChange.uidRecord = uidRec;
20650            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20651            mPendingUidChanges.add(pendingChange);
20652        } else {
20653            pendingChange = uidRec.pendingChange;
20654            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20655                change = UidRecord.CHANGE_GONE_IDLE;
20656            }
20657        }
20658        pendingChange.change = change;
20659        pendingChange.processState = uidRec != null
20660                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20661    }
20662
20663    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20664            String authority) {
20665        if (app == null) return;
20666        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20667            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20668            if (userState == null) return;
20669            final long now = SystemClock.elapsedRealtime();
20670            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20671            if (lastReported == null || lastReported < now - 60 * 1000L) {
20672                if (mSystemReady) {
20673                    // Cannot touch the user stats if not system ready
20674                    mUsageStatsService.reportContentProviderUsage(
20675                            authority, providerPkgName, app.userId);
20676                }
20677                userState.mProviderLastReportedFg.put(authority, now);
20678            }
20679        }
20680    }
20681
20682    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20683        if (DEBUG_USAGE_STATS) {
20684            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20685                    + "] state changes: old = " + app.setProcState + ", new = "
20686                    + app.curProcState);
20687        }
20688        if (mUsageStatsService == null) {
20689            return;
20690        }
20691        boolean isInteraction;
20692        // To avoid some abuse patterns, we are going to be careful about what we consider
20693        // to be an app interaction.  Being the top activity doesn't count while the display
20694        // is sleeping, nor do short foreground services.
20695        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20696            isInteraction = true;
20697            app.fgInteractionTime = 0;
20698        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20699            if (app.fgInteractionTime == 0) {
20700                app.fgInteractionTime = nowElapsed;
20701                isInteraction = false;
20702            } else {
20703                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20704            }
20705        } else {
20706            // If the app was being forced to the foreground, by say a Toast, then
20707            // no need to treat it as an interaction
20708            isInteraction = app.forcingToForeground == null
20709                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20710            app.fgInteractionTime = 0;
20711        }
20712        if (isInteraction && (!app.reportedInteraction
20713                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20714            app.interactionEventTime = nowElapsed;
20715            String[] packages = app.getPackageList();
20716            if (packages != null) {
20717                for (int i = 0; i < packages.length; i++) {
20718                    mUsageStatsService.reportEvent(packages[i], app.userId,
20719                            UsageEvents.Event.SYSTEM_INTERACTION);
20720                }
20721            }
20722        }
20723        app.reportedInteraction = isInteraction;
20724        if (!isInteraction) {
20725            app.interactionEventTime = 0;
20726        }
20727    }
20728
20729    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20730        if (proc.thread != null) {
20731            if (proc.baseProcessTracker != null) {
20732                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20733            }
20734        }
20735    }
20736
20737    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20738            ProcessRecord TOP_APP, boolean doingAll, long now) {
20739        if (app.thread == null) {
20740            return false;
20741        }
20742
20743        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20744
20745        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20746    }
20747
20748    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20749            boolean oomAdj) {
20750        if (isForeground != proc.foregroundServices) {
20751            proc.foregroundServices = isForeground;
20752            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20753                    proc.info.uid);
20754            if (isForeground) {
20755                if (curProcs == null) {
20756                    curProcs = new ArrayList<ProcessRecord>();
20757                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20758                }
20759                if (!curProcs.contains(proc)) {
20760                    curProcs.add(proc);
20761                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20762                            proc.info.packageName, proc.info.uid);
20763                }
20764            } else {
20765                if (curProcs != null) {
20766                    if (curProcs.remove(proc)) {
20767                        mBatteryStatsService.noteEvent(
20768                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20769                                proc.info.packageName, proc.info.uid);
20770                        if (curProcs.size() <= 0) {
20771                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20772                        }
20773                    }
20774                }
20775            }
20776            if (oomAdj) {
20777                updateOomAdjLocked();
20778            }
20779        }
20780    }
20781
20782    private final ActivityRecord resumedAppLocked() {
20783        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20784        String pkg;
20785        int uid;
20786        if (act != null) {
20787            pkg = act.packageName;
20788            uid = act.info.applicationInfo.uid;
20789        } else {
20790            pkg = null;
20791            uid = -1;
20792        }
20793        // Has the UID or resumed package name changed?
20794        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20795                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20796            if (mCurResumedPackage != null) {
20797                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20798                        mCurResumedPackage, mCurResumedUid);
20799            }
20800            mCurResumedPackage = pkg;
20801            mCurResumedUid = uid;
20802            if (mCurResumedPackage != null) {
20803                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20804                        mCurResumedPackage, mCurResumedUid);
20805            }
20806        }
20807        return act;
20808    }
20809
20810    final boolean updateOomAdjLocked(ProcessRecord app) {
20811        final ActivityRecord TOP_ACT = resumedAppLocked();
20812        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20813        final boolean wasCached = app.cached;
20814
20815        mAdjSeq++;
20816
20817        // This is the desired cached adjusment we want to tell it to use.
20818        // If our app is currently cached, we know it, and that is it.  Otherwise,
20819        // we don't know it yet, and it needs to now be cached we will then
20820        // need to do a complete oom adj.
20821        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20822                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20823        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20824                SystemClock.uptimeMillis());
20825        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20826            // Changed to/from cached state, so apps after it in the LRU
20827            // list may also be changed.
20828            updateOomAdjLocked();
20829        }
20830        return success;
20831    }
20832
20833    final void updateOomAdjLocked() {
20834        final ActivityRecord TOP_ACT = resumedAppLocked();
20835        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20836        final long now = SystemClock.uptimeMillis();
20837        final long nowElapsed = SystemClock.elapsedRealtime();
20838        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20839        final int N = mLruProcesses.size();
20840
20841        if (false) {
20842            RuntimeException e = new RuntimeException();
20843            e.fillInStackTrace();
20844            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20845        }
20846
20847        // Reset state in all uid records.
20848        for (int i=mActiveUids.size()-1; i>=0; i--) {
20849            final UidRecord uidRec = mActiveUids.valueAt(i);
20850            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20851                    "Starting update of " + uidRec);
20852            uidRec.reset();
20853        }
20854
20855        mStackSupervisor.rankTaskLayersIfNeeded();
20856
20857        mAdjSeq++;
20858        mNewNumServiceProcs = 0;
20859        mNewNumAServiceProcs = 0;
20860
20861        final int emptyProcessLimit;
20862        final int cachedProcessLimit;
20863        if (mProcessLimit <= 0) {
20864            emptyProcessLimit = cachedProcessLimit = 0;
20865        } else if (mProcessLimit == 1) {
20866            emptyProcessLimit = 1;
20867            cachedProcessLimit = 0;
20868        } else {
20869            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20870            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20871        }
20872
20873        // Let's determine how many processes we have running vs.
20874        // how many slots we have for background processes; we may want
20875        // to put multiple processes in a slot of there are enough of
20876        // them.
20877        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20878                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20879        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20880        if (numEmptyProcs > cachedProcessLimit) {
20881            // If there are more empty processes than our limit on cached
20882            // processes, then use the cached process limit for the factor.
20883            // This ensures that the really old empty processes get pushed
20884            // down to the bottom, so if we are running low on memory we will
20885            // have a better chance at keeping around more cached processes
20886            // instead of a gazillion empty processes.
20887            numEmptyProcs = cachedProcessLimit;
20888        }
20889        int emptyFactor = numEmptyProcs/numSlots;
20890        if (emptyFactor < 1) emptyFactor = 1;
20891        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20892        if (cachedFactor < 1) cachedFactor = 1;
20893        int stepCached = 0;
20894        int stepEmpty = 0;
20895        int numCached = 0;
20896        int numEmpty = 0;
20897        int numTrimming = 0;
20898
20899        mNumNonCachedProcs = 0;
20900        mNumCachedHiddenProcs = 0;
20901
20902        // First update the OOM adjustment for each of the
20903        // application processes based on their current state.
20904        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20905        int nextCachedAdj = curCachedAdj+1;
20906        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20907        int nextEmptyAdj = curEmptyAdj+2;
20908        for (int i=N-1; i>=0; i--) {
20909            ProcessRecord app = mLruProcesses.get(i);
20910            if (!app.killedByAm && app.thread != null) {
20911                app.procStateChanged = false;
20912                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20913
20914                // If we haven't yet assigned the final cached adj
20915                // to the process, do that now.
20916                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20917                    switch (app.curProcState) {
20918                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20919                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20920                            // This process is a cached process holding activities...
20921                            // assign it the next cached value for that type, and then
20922                            // step that cached level.
20923                            app.curRawAdj = curCachedAdj;
20924                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20925                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20926                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20927                                    + ")");
20928                            if (curCachedAdj != nextCachedAdj) {
20929                                stepCached++;
20930                                if (stepCached >= cachedFactor) {
20931                                    stepCached = 0;
20932                                    curCachedAdj = nextCachedAdj;
20933                                    nextCachedAdj += 2;
20934                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20935                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20936                                    }
20937                                }
20938                            }
20939                            break;
20940                        default:
20941                            // For everything else, assign next empty cached process
20942                            // level and bump that up.  Note that this means that
20943                            // long-running services that have dropped down to the
20944                            // cached level will be treated as empty (since their process
20945                            // state is still as a service), which is what we want.
20946                            app.curRawAdj = curEmptyAdj;
20947                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20948                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20949                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20950                                    + ")");
20951                            if (curEmptyAdj != nextEmptyAdj) {
20952                                stepEmpty++;
20953                                if (stepEmpty >= emptyFactor) {
20954                                    stepEmpty = 0;
20955                                    curEmptyAdj = nextEmptyAdj;
20956                                    nextEmptyAdj += 2;
20957                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20958                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20959                                    }
20960                                }
20961                            }
20962                            break;
20963                    }
20964                }
20965
20966                applyOomAdjLocked(app, true, now, nowElapsed);
20967
20968                // Count the number of process types.
20969                switch (app.curProcState) {
20970                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20971                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20972                        mNumCachedHiddenProcs++;
20973                        numCached++;
20974                        if (numCached > cachedProcessLimit) {
20975                            app.kill("cached #" + numCached, true);
20976                        }
20977                        break;
20978                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20979                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20980                                && app.lastActivityTime < oldTime) {
20981                            app.kill("empty for "
20982                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20983                                    / 1000) + "s", true);
20984                        } else {
20985                            numEmpty++;
20986                            if (numEmpty > emptyProcessLimit) {
20987                                app.kill("empty #" + numEmpty, true);
20988                            }
20989                        }
20990                        break;
20991                    default:
20992                        mNumNonCachedProcs++;
20993                        break;
20994                }
20995
20996                if (app.isolated && app.services.size() <= 0) {
20997                    // If this is an isolated process, and there are no
20998                    // services running in it, then the process is no longer
20999                    // needed.  We agressively kill these because we can by
21000                    // definition not re-use the same process again, and it is
21001                    // good to avoid having whatever code was running in them
21002                    // left sitting around after no longer needed.
21003                    app.kill("isolated not needed", true);
21004                } else {
21005                    // Keeping this process, update its uid.
21006                    final UidRecord uidRec = app.uidRecord;
21007                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
21008                        uidRec.curProcState = app.curProcState;
21009                    }
21010                }
21011
21012                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21013                        && !app.killedByAm) {
21014                    numTrimming++;
21015                }
21016            }
21017        }
21018
21019        mNumServiceProcs = mNewNumServiceProcs;
21020
21021        // Now determine the memory trimming level of background processes.
21022        // Unfortunately we need to start at the back of the list to do this
21023        // properly.  We only do this if the number of background apps we
21024        // are managing to keep around is less than half the maximum we desire;
21025        // if we are keeping a good number around, we'll let them use whatever
21026        // memory they want.
21027        final int numCachedAndEmpty = numCached + numEmpty;
21028        int memFactor;
21029        if (numCached <= ProcessList.TRIM_CACHED_APPS
21030                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21031            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21032                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21033            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21034                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21035            } else {
21036                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21037            }
21038        } else {
21039            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21040        }
21041        // We always allow the memory level to go up (better).  We only allow it to go
21042        // down if we are in a state where that is allowed, *and* the total number of processes
21043        // has gone down since last time.
21044        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21045                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21046                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21047        if (memFactor > mLastMemoryLevel) {
21048            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21049                memFactor = mLastMemoryLevel;
21050                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21051            }
21052        }
21053        if (memFactor != mLastMemoryLevel) {
21054            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21055        }
21056        mLastMemoryLevel = memFactor;
21057        mLastNumProcesses = mLruProcesses.size();
21058        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21059        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21060        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21061            if (mLowRamStartTime == 0) {
21062                mLowRamStartTime = now;
21063            }
21064            int step = 0;
21065            int fgTrimLevel;
21066            switch (memFactor) {
21067                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21068                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21069                    break;
21070                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21071                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21072                    break;
21073                default:
21074                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21075                    break;
21076            }
21077            int factor = numTrimming/3;
21078            int minFactor = 2;
21079            if (mHomeProcess != null) minFactor++;
21080            if (mPreviousProcess != null) minFactor++;
21081            if (factor < minFactor) factor = minFactor;
21082            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21083            for (int i=N-1; i>=0; i--) {
21084                ProcessRecord app = mLruProcesses.get(i);
21085                if (allChanged || app.procStateChanged) {
21086                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21087                    app.procStateChanged = false;
21088                }
21089                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21090                        && !app.killedByAm) {
21091                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21092                        try {
21093                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21094                                    "Trimming memory of " + app.processName + " to " + curLevel);
21095                            app.thread.scheduleTrimMemory(curLevel);
21096                        } catch (RemoteException e) {
21097                        }
21098                        if (false) {
21099                            // For now we won't do this; our memory trimming seems
21100                            // to be good enough at this point that destroying
21101                            // activities causes more harm than good.
21102                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21103                                    && app != mHomeProcess && app != mPreviousProcess) {
21104                                // Need to do this on its own message because the stack may not
21105                                // be in a consistent state at this point.
21106                                // For these apps we will also finish their activities
21107                                // to help them free memory.
21108                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21109                            }
21110                        }
21111                    }
21112                    app.trimMemoryLevel = curLevel;
21113                    step++;
21114                    if (step >= factor) {
21115                        step = 0;
21116                        switch (curLevel) {
21117                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21118                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21119                                break;
21120                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21121                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21122                                break;
21123                        }
21124                    }
21125                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21126                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21127                            && app.thread != null) {
21128                        try {
21129                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21130                                    "Trimming memory of heavy-weight " + app.processName
21131                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21132                            app.thread.scheduleTrimMemory(
21133                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21134                        } catch (RemoteException e) {
21135                        }
21136                    }
21137                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21138                } else {
21139                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21140                            || app.systemNoUi) && app.pendingUiClean) {
21141                        // If this application is now in the background and it
21142                        // had done UI, then give it the special trim level to
21143                        // have it free UI resources.
21144                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21145                        if (app.trimMemoryLevel < level && app.thread != null) {
21146                            try {
21147                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21148                                        "Trimming memory of bg-ui " + app.processName
21149                                        + " to " + level);
21150                                app.thread.scheduleTrimMemory(level);
21151                            } catch (RemoteException e) {
21152                            }
21153                        }
21154                        app.pendingUiClean = false;
21155                    }
21156                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21157                        try {
21158                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21159                                    "Trimming memory of fg " + app.processName
21160                                    + " to " + fgTrimLevel);
21161                            app.thread.scheduleTrimMemory(fgTrimLevel);
21162                        } catch (RemoteException e) {
21163                        }
21164                    }
21165                    app.trimMemoryLevel = fgTrimLevel;
21166                }
21167            }
21168        } else {
21169            if (mLowRamStartTime != 0) {
21170                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21171                mLowRamStartTime = 0;
21172            }
21173            for (int i=N-1; i>=0; i--) {
21174                ProcessRecord app = mLruProcesses.get(i);
21175                if (allChanged || app.procStateChanged) {
21176                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21177                    app.procStateChanged = false;
21178                }
21179                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21180                        || app.systemNoUi) && app.pendingUiClean) {
21181                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21182                            && app.thread != null) {
21183                        try {
21184                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21185                                    "Trimming memory of ui hidden " + app.processName
21186                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21187                            app.thread.scheduleTrimMemory(
21188                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21189                        } catch (RemoteException e) {
21190                        }
21191                    }
21192                    app.pendingUiClean = false;
21193                }
21194                app.trimMemoryLevel = 0;
21195            }
21196        }
21197
21198        if (mAlwaysFinishActivities) {
21199            // Need to do this on its own message because the stack may not
21200            // be in a consistent state at this point.
21201            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21202        }
21203
21204        if (allChanged) {
21205            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21206        }
21207
21208        // Update from any uid changes.
21209        for (int i=mActiveUids.size()-1; i>=0; i--) {
21210            final UidRecord uidRec = mActiveUids.valueAt(i);
21211            int uidChange = UidRecord.CHANGE_PROCSTATE;
21212            if (uidRec.setProcState != uidRec.curProcState) {
21213                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21214                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21215                        + " to " + uidRec.curProcState);
21216                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21217                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21218                        uidRec.lastBackgroundTime = nowElapsed;
21219                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21220                            // Note: the background settle time is in elapsed realtime, while
21221                            // the handler time base is uptime.  All this means is that we may
21222                            // stop background uids later than we had intended, but that only
21223                            // happens because the device was sleeping so we are okay anyway.
21224                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21225                        }
21226                    }
21227                } else {
21228                    if (uidRec.idle) {
21229                        uidChange = UidRecord.CHANGE_ACTIVE;
21230                        uidRec.idle = false;
21231                    }
21232                    uidRec.lastBackgroundTime = 0;
21233                }
21234                uidRec.setProcState = uidRec.curProcState;
21235                enqueueUidChangeLocked(uidRec, -1, uidChange);
21236                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21237            }
21238        }
21239
21240        if (mProcessStats.shouldWriteNowLocked(now)) {
21241            mHandler.post(new Runnable() {
21242                @Override public void run() {
21243                    synchronized (ActivityManagerService.this) {
21244                        mProcessStats.writeStateAsyncLocked();
21245                    }
21246                }
21247            });
21248        }
21249
21250        if (DEBUG_OOM_ADJ) {
21251            final long duration = SystemClock.uptimeMillis() - now;
21252            if (false) {
21253                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21254                        new RuntimeException("here").fillInStackTrace());
21255            } else {
21256                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21257            }
21258        }
21259    }
21260
21261    final void idleUids() {
21262        synchronized (this) {
21263            final long nowElapsed = SystemClock.elapsedRealtime();
21264            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21265            long nextTime = 0;
21266            for (int i=mActiveUids.size()-1; i>=0; i--) {
21267                final UidRecord uidRec = mActiveUids.valueAt(i);
21268                final long bgTime = uidRec.lastBackgroundTime;
21269                if (bgTime > 0 && !uidRec.idle) {
21270                    if (bgTime <= maxBgTime) {
21271                        uidRec.idle = true;
21272                        doStopUidLocked(uidRec.uid, uidRec);
21273                    } else {
21274                        if (nextTime == 0 || nextTime > bgTime) {
21275                            nextTime = bgTime;
21276                        }
21277                    }
21278                }
21279            }
21280            if (nextTime > 0) {
21281                mHandler.removeMessages(IDLE_UIDS_MSG);
21282                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21283                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21284            }
21285        }
21286    }
21287
21288    final void runInBackgroundDisabled(int uid) {
21289        synchronized (this) {
21290            UidRecord uidRec = mActiveUids.get(uid);
21291            if (uidRec != null) {
21292                // This uid is actually running...  should it be considered background now?
21293                if (uidRec.idle) {
21294                    doStopUidLocked(uidRec.uid, uidRec);
21295                }
21296            } else {
21297                // This uid isn't actually running...  still send a report about it being "stopped".
21298                doStopUidLocked(uid, null);
21299            }
21300        }
21301    }
21302
21303    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21304        mServices.stopInBackgroundLocked(uid);
21305        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21306    }
21307
21308    final void trimApplications() {
21309        synchronized (this) {
21310            int i;
21311
21312            // First remove any unused application processes whose package
21313            // has been removed.
21314            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21315                final ProcessRecord app = mRemovedProcesses.get(i);
21316                if (app.activities.size() == 0
21317                        && app.curReceiver == null && app.services.size() == 0) {
21318                    Slog.i(
21319                        TAG, "Exiting empty application process "
21320                        + app.toShortString() + " ("
21321                        + (app.thread != null ? app.thread.asBinder() : null)
21322                        + ")\n");
21323                    if (app.pid > 0 && app.pid != MY_PID) {
21324                        app.kill("empty", false);
21325                    } else {
21326                        try {
21327                            app.thread.scheduleExit();
21328                        } catch (Exception e) {
21329                            // Ignore exceptions.
21330                        }
21331                    }
21332                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21333                    mRemovedProcesses.remove(i);
21334
21335                    if (app.persistent) {
21336                        addAppLocked(app.info, false, null /* ABI override */);
21337                    }
21338                }
21339            }
21340
21341            // Now update the oom adj for all processes.
21342            updateOomAdjLocked();
21343        }
21344    }
21345
21346    /** This method sends the specified signal to each of the persistent apps */
21347    public void signalPersistentProcesses(int sig) throws RemoteException {
21348        if (sig != Process.SIGNAL_USR1) {
21349            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21350        }
21351
21352        synchronized (this) {
21353            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21354                    != PackageManager.PERMISSION_GRANTED) {
21355                throw new SecurityException("Requires permission "
21356                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21357            }
21358
21359            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21360                ProcessRecord r = mLruProcesses.get(i);
21361                if (r.thread != null && r.persistent) {
21362                    Process.sendSignal(r.pid, sig);
21363                }
21364            }
21365        }
21366    }
21367
21368    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21369        if (proc == null || proc == mProfileProc) {
21370            proc = mProfileProc;
21371            profileType = mProfileType;
21372            clearProfilerLocked();
21373        }
21374        if (proc == null) {
21375            return;
21376        }
21377        try {
21378            proc.thread.profilerControl(false, null, profileType);
21379        } catch (RemoteException e) {
21380            throw new IllegalStateException("Process disappeared");
21381        }
21382    }
21383
21384    private void clearProfilerLocked() {
21385        if (mProfileFd != null) {
21386            try {
21387                mProfileFd.close();
21388            } catch (IOException e) {
21389            }
21390        }
21391        mProfileApp = null;
21392        mProfileProc = null;
21393        mProfileFile = null;
21394        mProfileType = 0;
21395        mAutoStopProfiler = false;
21396        mSamplingInterval = 0;
21397    }
21398
21399    public boolean profileControl(String process, int userId, boolean start,
21400            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21401
21402        try {
21403            synchronized (this) {
21404                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21405                // its own permission.
21406                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21407                        != PackageManager.PERMISSION_GRANTED) {
21408                    throw new SecurityException("Requires permission "
21409                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21410                }
21411
21412                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21413                    throw new IllegalArgumentException("null profile info or fd");
21414                }
21415
21416                ProcessRecord proc = null;
21417                if (process != null) {
21418                    proc = findProcessLocked(process, userId, "profileControl");
21419                }
21420
21421                if (start && (proc == null || proc.thread == null)) {
21422                    throw new IllegalArgumentException("Unknown process: " + process);
21423                }
21424
21425                if (start) {
21426                    stopProfilerLocked(null, 0);
21427                    setProfileApp(proc.info, proc.processName, profilerInfo);
21428                    mProfileProc = proc;
21429                    mProfileType = profileType;
21430                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21431                    try {
21432                        fd = fd.dup();
21433                    } catch (IOException e) {
21434                        fd = null;
21435                    }
21436                    profilerInfo.profileFd = fd;
21437                    proc.thread.profilerControl(start, profilerInfo, profileType);
21438                    fd = null;
21439                    mProfileFd = null;
21440                } else {
21441                    stopProfilerLocked(proc, profileType);
21442                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21443                        try {
21444                            profilerInfo.profileFd.close();
21445                        } catch (IOException e) {
21446                        }
21447                    }
21448                }
21449
21450                return true;
21451            }
21452        } catch (RemoteException e) {
21453            throw new IllegalStateException("Process disappeared");
21454        } finally {
21455            if (profilerInfo != null && profilerInfo.profileFd != null) {
21456                try {
21457                    profilerInfo.profileFd.close();
21458                } catch (IOException e) {
21459                }
21460            }
21461        }
21462    }
21463
21464    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21465        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21466                userId, true, ALLOW_FULL_ONLY, callName, null);
21467        ProcessRecord proc = null;
21468        try {
21469            int pid = Integer.parseInt(process);
21470            synchronized (mPidsSelfLocked) {
21471                proc = mPidsSelfLocked.get(pid);
21472            }
21473        } catch (NumberFormatException e) {
21474        }
21475
21476        if (proc == null) {
21477            ArrayMap<String, SparseArray<ProcessRecord>> all
21478                    = mProcessNames.getMap();
21479            SparseArray<ProcessRecord> procs = all.get(process);
21480            if (procs != null && procs.size() > 0) {
21481                proc = procs.valueAt(0);
21482                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21483                    for (int i=1; i<procs.size(); i++) {
21484                        ProcessRecord thisProc = procs.valueAt(i);
21485                        if (thisProc.userId == userId) {
21486                            proc = thisProc;
21487                            break;
21488                        }
21489                    }
21490                }
21491            }
21492        }
21493
21494        return proc;
21495    }
21496
21497    public boolean dumpHeap(String process, int userId, boolean managed,
21498            String path, ParcelFileDescriptor fd) throws RemoteException {
21499
21500        try {
21501            synchronized (this) {
21502                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21503                // its own permission (same as profileControl).
21504                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21505                        != PackageManager.PERMISSION_GRANTED) {
21506                    throw new SecurityException("Requires permission "
21507                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21508                }
21509
21510                if (fd == null) {
21511                    throw new IllegalArgumentException("null fd");
21512                }
21513
21514                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21515                if (proc == null || proc.thread == null) {
21516                    throw new IllegalArgumentException("Unknown process: " + process);
21517                }
21518
21519                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21520                if (!isDebuggable) {
21521                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21522                        throw new SecurityException("Process not debuggable: " + proc);
21523                    }
21524                }
21525
21526                proc.thread.dumpHeap(managed, path, fd);
21527                fd = null;
21528                return true;
21529            }
21530        } catch (RemoteException e) {
21531            throw new IllegalStateException("Process disappeared");
21532        } finally {
21533            if (fd != null) {
21534                try {
21535                    fd.close();
21536                } catch (IOException e) {
21537                }
21538            }
21539        }
21540    }
21541
21542    @Override
21543    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21544            String reportPackage) {
21545        if (processName != null) {
21546            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21547                    "setDumpHeapDebugLimit()");
21548        } else {
21549            synchronized (mPidsSelfLocked) {
21550                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21551                if (proc == null) {
21552                    throw new SecurityException("No process found for calling pid "
21553                            + Binder.getCallingPid());
21554                }
21555                if (!Build.IS_DEBUGGABLE
21556                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21557                    throw new SecurityException("Not running a debuggable build");
21558                }
21559                processName = proc.processName;
21560                uid = proc.uid;
21561                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21562                    throw new SecurityException("Package " + reportPackage + " is not running in "
21563                            + proc);
21564                }
21565            }
21566        }
21567        synchronized (this) {
21568            if (maxMemSize > 0) {
21569                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21570            } else {
21571                if (uid != 0) {
21572                    mMemWatchProcesses.remove(processName, uid);
21573                } else {
21574                    mMemWatchProcesses.getMap().remove(processName);
21575                }
21576            }
21577        }
21578    }
21579
21580    @Override
21581    public void dumpHeapFinished(String path) {
21582        synchronized (this) {
21583            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21584                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21585                        + " does not match last pid " + mMemWatchDumpPid);
21586                return;
21587            }
21588            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21589                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21590                        + " does not match last path " + mMemWatchDumpFile);
21591                return;
21592            }
21593            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21594            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21595        }
21596    }
21597
21598    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21599    public void monitor() {
21600        synchronized (this) { }
21601    }
21602
21603    void onCoreSettingsChange(Bundle settings) {
21604        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21605            ProcessRecord processRecord = mLruProcesses.get(i);
21606            try {
21607                if (processRecord.thread != null) {
21608                    processRecord.thread.setCoreSettings(settings);
21609                }
21610            } catch (RemoteException re) {
21611                /* ignore */
21612            }
21613        }
21614    }
21615
21616    // Multi-user methods
21617
21618    /**
21619     * Start user, if its not already running, but don't bring it to foreground.
21620     */
21621    @Override
21622    public boolean startUserInBackground(final int userId) {
21623        return mUserController.startUser(userId, /* foreground */ false);
21624    }
21625
21626    @Override
21627    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21628        return mUserController.unlockUser(userId, token, secret, listener);
21629    }
21630
21631    @Override
21632    public boolean switchUser(final int targetUserId) {
21633        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21634        UserInfo currentUserInfo;
21635        UserInfo targetUserInfo;
21636        synchronized (this) {
21637            int currentUserId = mUserController.getCurrentUserIdLocked();
21638            currentUserInfo = mUserController.getUserInfo(currentUserId);
21639            targetUserInfo = mUserController.getUserInfo(targetUserId);
21640            if (targetUserInfo == null) {
21641                Slog.w(TAG, "No user info for user #" + targetUserId);
21642                return false;
21643            }
21644            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21645                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21646                        + " when device is in demo mode");
21647                return false;
21648            }
21649            if (!targetUserInfo.supportsSwitchTo()) {
21650                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21651                return false;
21652            }
21653            if (targetUserInfo.isManagedProfile()) {
21654                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21655                return false;
21656            }
21657            mUserController.setTargetUserIdLocked(targetUserId);
21658        }
21659        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21660        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21661        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21662        return true;
21663    }
21664
21665    void scheduleStartProfilesLocked() {
21666        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21667            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21668                    DateUtils.SECOND_IN_MILLIS);
21669        }
21670    }
21671
21672    @Override
21673    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21674        return mUserController.stopUser(userId, force, callback);
21675    }
21676
21677    @Override
21678    public UserInfo getCurrentUser() {
21679        return mUserController.getCurrentUser();
21680    }
21681
21682    @Override
21683    public boolean isUserRunning(int userId, int flags) {
21684        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21685                && checkCallingPermission(INTERACT_ACROSS_USERS)
21686                    != PackageManager.PERMISSION_GRANTED) {
21687            String msg = "Permission Denial: isUserRunning() from pid="
21688                    + Binder.getCallingPid()
21689                    + ", uid=" + Binder.getCallingUid()
21690                    + " requires " + INTERACT_ACROSS_USERS;
21691            Slog.w(TAG, msg);
21692            throw new SecurityException(msg);
21693        }
21694        synchronized (this) {
21695            return mUserController.isUserRunningLocked(userId, flags);
21696        }
21697    }
21698
21699    @Override
21700    public int[] getRunningUserIds() {
21701        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21702                != PackageManager.PERMISSION_GRANTED) {
21703            String msg = "Permission Denial: isUserRunning() from pid="
21704                    + Binder.getCallingPid()
21705                    + ", uid=" + Binder.getCallingUid()
21706                    + " requires " + INTERACT_ACROSS_USERS;
21707            Slog.w(TAG, msg);
21708            throw new SecurityException(msg);
21709        }
21710        synchronized (this) {
21711            return mUserController.getStartedUserArrayLocked();
21712        }
21713    }
21714
21715    @Override
21716    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21717        mUserController.registerUserSwitchObserver(observer, name);
21718    }
21719
21720    @Override
21721    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21722        mUserController.unregisterUserSwitchObserver(observer);
21723    }
21724
21725    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21726        if (info == null) return null;
21727        ApplicationInfo newInfo = new ApplicationInfo(info);
21728        newInfo.initForUser(userId);
21729        return newInfo;
21730    }
21731
21732    public boolean isUserStopped(int userId) {
21733        synchronized (this) {
21734            return mUserController.getStartedUserStateLocked(userId) == null;
21735        }
21736    }
21737
21738    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21739        if (aInfo == null
21740                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21741            return aInfo;
21742        }
21743
21744        ActivityInfo info = new ActivityInfo(aInfo);
21745        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21746        return info;
21747    }
21748
21749    private boolean processSanityChecksLocked(ProcessRecord process) {
21750        if (process == null || process.thread == null) {
21751            return false;
21752        }
21753
21754        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21755        if (!isDebuggable) {
21756            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21757                return false;
21758            }
21759        }
21760
21761        return true;
21762    }
21763
21764    public boolean startBinderTracking() throws RemoteException {
21765        synchronized (this) {
21766            mBinderTransactionTrackingEnabled = true;
21767            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21768            // permission (same as profileControl).
21769            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21770                    != PackageManager.PERMISSION_GRANTED) {
21771                throw new SecurityException("Requires permission "
21772                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21773            }
21774
21775            for (int i = 0; i < mLruProcesses.size(); i++) {
21776                ProcessRecord process = mLruProcesses.get(i);
21777                if (!processSanityChecksLocked(process)) {
21778                    continue;
21779                }
21780                try {
21781                    process.thread.startBinderTracking();
21782                } catch (RemoteException e) {
21783                    Log.v(TAG, "Process disappared");
21784                }
21785            }
21786            return true;
21787        }
21788    }
21789
21790    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21791        try {
21792            synchronized (this) {
21793                mBinderTransactionTrackingEnabled = false;
21794                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21795                // permission (same as profileControl).
21796                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21797                        != PackageManager.PERMISSION_GRANTED) {
21798                    throw new SecurityException("Requires permission "
21799                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21800                }
21801
21802                if (fd == null) {
21803                    throw new IllegalArgumentException("null fd");
21804                }
21805
21806                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21807                pw.println("Binder transaction traces for all processes.\n");
21808                for (ProcessRecord process : mLruProcesses) {
21809                    if (!processSanityChecksLocked(process)) {
21810                        continue;
21811                    }
21812
21813                    pw.println("Traces for process: " + process.processName);
21814                    pw.flush();
21815                    try {
21816                        TransferPipe tp = new TransferPipe();
21817                        try {
21818                            process.thread.stopBinderTrackingAndDump(
21819                                    tp.getWriteFd().getFileDescriptor());
21820                            tp.go(fd.getFileDescriptor());
21821                        } finally {
21822                            tp.kill();
21823                        }
21824                    } catch (IOException e) {
21825                        pw.println("Failure while dumping IPC traces from " + process +
21826                                ".  Exception: " + e);
21827                        pw.flush();
21828                    } catch (RemoteException e) {
21829                        pw.println("Got a RemoteException while dumping IPC traces from " +
21830                                process + ".  Exception: " + e);
21831                        pw.flush();
21832                    }
21833                }
21834                fd = null;
21835                return true;
21836            }
21837        } finally {
21838            if (fd != null) {
21839                try {
21840                    fd.close();
21841                } catch (IOException e) {
21842                }
21843            }
21844        }
21845    }
21846
21847    private final class LocalService extends ActivityManagerInternal {
21848        @Override
21849        public void onWakefulnessChanged(int wakefulness) {
21850            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21851        }
21852
21853        @Override
21854        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21855                String processName, String abiOverride, int uid, Runnable crashHandler) {
21856            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21857                    processName, abiOverride, uid, crashHandler);
21858        }
21859
21860        @Override
21861        public SleepToken acquireSleepToken(String tag) {
21862            Preconditions.checkNotNull(tag);
21863
21864            ComponentName requestedVrService = null;
21865            ComponentName callingVrActivity = null;
21866            int userId = -1;
21867            synchronized (ActivityManagerService.this) {
21868                if (mFocusedActivity != null) {
21869                    requestedVrService = mFocusedActivity.requestedVrComponent;
21870                    callingVrActivity = mFocusedActivity.info.getComponentName();
21871                    userId = mFocusedActivity.userId;
21872                }
21873            }
21874
21875            if (requestedVrService != null) {
21876                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21877            }
21878
21879            synchronized (ActivityManagerService.this) {
21880                SleepTokenImpl token = new SleepTokenImpl(tag);
21881                mSleepTokens.add(token);
21882                updateSleepIfNeededLocked();
21883                return token;
21884            }
21885        }
21886
21887        @Override
21888        public ComponentName getHomeActivityForUser(int userId) {
21889            synchronized (ActivityManagerService.this) {
21890                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21891                return homeActivity == null ? null : homeActivity.realActivity;
21892            }
21893        }
21894
21895        @Override
21896        public void onUserRemoved(int userId) {
21897            synchronized (ActivityManagerService.this) {
21898                ActivityManagerService.this.onUserStoppedLocked(userId);
21899            }
21900        }
21901
21902        @Override
21903        public void onLocalVoiceInteractionStarted(IBinder activity,
21904                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21905            synchronized (ActivityManagerService.this) {
21906                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21907                        voiceSession, voiceInteractor);
21908            }
21909        }
21910
21911        @Override
21912        public void notifyStartingWindowDrawn() {
21913            synchronized (ActivityManagerService.this) {
21914                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21915            }
21916        }
21917
21918        @Override
21919        public void notifyAppTransitionStarting(int reason) {
21920            synchronized (ActivityManagerService.this) {
21921                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21922            }
21923        }
21924
21925        @Override
21926        public void notifyAppTransitionFinished() {
21927            synchronized (ActivityManagerService.this) {
21928                mStackSupervisor.notifyAppTransitionDone();
21929            }
21930        }
21931
21932        @Override
21933        public void notifyAppTransitionCancelled() {
21934            synchronized (ActivityManagerService.this) {
21935                mStackSupervisor.notifyAppTransitionDone();
21936            }
21937        }
21938
21939        @Override
21940        public List<IBinder> getTopVisibleActivities() {
21941            synchronized (ActivityManagerService.this) {
21942                return mStackSupervisor.getTopVisibleActivities();
21943            }
21944        }
21945
21946        @Override
21947        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21948            synchronized (ActivityManagerService.this) {
21949                mStackSupervisor.setDockedStackMinimized(minimized);
21950            }
21951        }
21952
21953        @Override
21954        public void killForegroundAppsForUser(int userHandle) {
21955            synchronized (ActivityManagerService.this) {
21956                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21957                final int NP = mProcessNames.getMap().size();
21958                for (int ip = 0; ip < NP; ip++) {
21959                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21960                    final int NA = apps.size();
21961                    for (int ia = 0; ia < NA; ia++) {
21962                        final ProcessRecord app = apps.valueAt(ia);
21963                        if (app.persistent) {
21964                            // We don't kill persistent processes.
21965                            continue;
21966                        }
21967                        if (app.removed) {
21968                            procs.add(app);
21969                        } else if (app.userId == userHandle && app.foregroundActivities) {
21970                            app.removed = true;
21971                            procs.add(app);
21972                        }
21973                    }
21974                }
21975
21976                final int N = procs.size();
21977                for (int i = 0; i < N; i++) {
21978                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21979                }
21980            }
21981        }
21982
21983        @Override
21984        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21985            if (!(target instanceof PendingIntentRecord)) {
21986                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21987                return;
21988            }
21989            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21990        }
21991
21992        @Override
21993        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
21994                int userId) {
21995            Preconditions.checkNotNull(values, "Configuration must not be null");
21996            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
21997            synchronized (ActivityManagerService.this) {
21998                updateConfigurationLocked(values, null, false, true, userId,
21999                        false /* deferResume */);
22000            }
22001        }
22002
22003        @Override
22004        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22005                Bundle bOptions) {
22006            Preconditions.checkNotNull(intents, "intents");
22007            final String[] resolvedTypes = new String[intents.length];
22008            for (int i = 0; i < intents.length; i++) {
22009                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22010            }
22011
22012            // UID of the package on user userId.
22013            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22014            // packageUid may not be initialized.
22015            int packageUid = 0;
22016            try {
22017                packageUid = AppGlobals.getPackageManager().getPackageUid(
22018                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22019            } catch (RemoteException e) {
22020                // Shouldn't happen.
22021            }
22022
22023            synchronized (ActivityManagerService.this) {
22024                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22025                        /*resultTo*/ null, bOptions, userId);
22026            }
22027        }
22028
22029        @Override
22030        public int getUidProcessState(int uid) {
22031            return getUidState(uid);
22032        }
22033    }
22034
22035    private final class SleepTokenImpl extends SleepToken {
22036        private final String mTag;
22037        private final long mAcquireTime;
22038
22039        public SleepTokenImpl(String tag) {
22040            mTag = tag;
22041            mAcquireTime = SystemClock.uptimeMillis();
22042        }
22043
22044        @Override
22045        public void release() {
22046            synchronized (ActivityManagerService.this) {
22047                if (mSleepTokens.remove(this)) {
22048                    updateSleepIfNeededLocked();
22049                }
22050            }
22051        }
22052
22053        @Override
22054        public String toString() {
22055            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22056        }
22057    }
22058
22059    /**
22060     * An implementation of IAppTask, that allows an app to manage its own tasks via
22061     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22062     * only the process that calls getAppTasks() can call the AppTask methods.
22063     */
22064    class AppTaskImpl extends IAppTask.Stub {
22065        private int mTaskId;
22066        private int mCallingUid;
22067
22068        public AppTaskImpl(int taskId, int callingUid) {
22069            mTaskId = taskId;
22070            mCallingUid = callingUid;
22071        }
22072
22073        private void checkCaller() {
22074            if (mCallingUid != Binder.getCallingUid()) {
22075                throw new SecurityException("Caller " + mCallingUid
22076                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22077            }
22078        }
22079
22080        @Override
22081        public void finishAndRemoveTask() {
22082            checkCaller();
22083
22084            synchronized (ActivityManagerService.this) {
22085                long origId = Binder.clearCallingIdentity();
22086                try {
22087                    // We remove the task from recents to preserve backwards
22088                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22089                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22090                    }
22091                } finally {
22092                    Binder.restoreCallingIdentity(origId);
22093                }
22094            }
22095        }
22096
22097        @Override
22098        public ActivityManager.RecentTaskInfo getTaskInfo() {
22099            checkCaller();
22100
22101            synchronized (ActivityManagerService.this) {
22102                long origId = Binder.clearCallingIdentity();
22103                try {
22104                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22105                    if (tr == null) {
22106                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22107                    }
22108                    return createRecentTaskInfoFromTaskRecord(tr);
22109                } finally {
22110                    Binder.restoreCallingIdentity(origId);
22111                }
22112            }
22113        }
22114
22115        @Override
22116        public void moveToFront() {
22117            checkCaller();
22118            // Will bring task to front if it already has a root activity.
22119            final long origId = Binder.clearCallingIdentity();
22120            try {
22121                synchronized (this) {
22122                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22123                }
22124            } finally {
22125                Binder.restoreCallingIdentity(origId);
22126            }
22127        }
22128
22129        @Override
22130        public int startActivity(IBinder whoThread, String callingPackage,
22131                Intent intent, String resolvedType, Bundle bOptions) {
22132            checkCaller();
22133
22134            int callingUser = UserHandle.getCallingUserId();
22135            TaskRecord tr;
22136            IApplicationThread appThread;
22137            synchronized (ActivityManagerService.this) {
22138                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22139                if (tr == null) {
22140                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22141                }
22142                appThread = ApplicationThreadNative.asInterface(whoThread);
22143                if (appThread == null) {
22144                    throw new IllegalArgumentException("Bad app thread " + appThread);
22145                }
22146            }
22147            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22148                    resolvedType, null, null, null, null, 0, 0, null, null,
22149                    null, bOptions, false, callingUser, null, tr);
22150        }
22151
22152        @Override
22153        public void setExcludeFromRecents(boolean exclude) {
22154            checkCaller();
22155
22156            synchronized (ActivityManagerService.this) {
22157                long origId = Binder.clearCallingIdentity();
22158                try {
22159                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22160                    if (tr == null) {
22161                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22162                    }
22163                    Intent intent = tr.getBaseIntent();
22164                    if (exclude) {
22165                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22166                    } else {
22167                        intent.setFlags(intent.getFlags()
22168                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22169                    }
22170                } finally {
22171                    Binder.restoreCallingIdentity(origId);
22172                }
22173            }
22174        }
22175    }
22176
22177    /**
22178     * Kill processes for the user with id userId and that depend on the package named packageName
22179     */
22180    @Override
22181    public void killPackageDependents(String packageName, int userId) {
22182        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22183        if (packageName == null) {
22184            throw new NullPointerException(
22185                    "Cannot kill the dependents of a package without its name.");
22186        }
22187
22188        long callingId = Binder.clearCallingIdentity();
22189        IPackageManager pm = AppGlobals.getPackageManager();
22190        int pkgUid = -1;
22191        try {
22192            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22193        } catch (RemoteException e) {
22194        }
22195        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22196            throw new IllegalArgumentException(
22197                    "Cannot kill dependents of non-existing package " + packageName);
22198        }
22199        try {
22200            synchronized(this) {
22201                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22202                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22203                        "dep: " + packageName);
22204            }
22205        } finally {
22206            Binder.restoreCallingIdentity(callingId);
22207        }
22208    }
22209
22210    @Override
22211    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22212        final int userId = intent.getCreatorUserHandle().getIdentifier();
22213        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22214            return false;
22215        }
22216        IIntentSender target = intent.getTarget();
22217        if (!(target instanceof PendingIntentRecord)) {
22218            return false;
22219        }
22220        final PendingIntentRecord record = (PendingIntentRecord) target;
22221        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22222                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22223        // For direct boot aware activities, they can be shown without triggering a work challenge
22224        // before the profile user is unlocked.
22225        return rInfo != null && rInfo.activityInfo != null;
22226    }
22227}
22228