ActivityManagerService.java revision a590d2be935ef502943a1e6615500aa10e67c85a
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.Notification;
101import android.app.NotificationManager;
102import android.app.PendingIntent;
103import android.app.ProfilerInfo;
104import android.app.admin.DevicePolicyManager;
105import android.app.assist.AssistContent;
106import android.app.assist.AssistStructure;
107import android.app.backup.IBackupManager;
108import android.app.usage.UsageEvents;
109import android.app.usage.UsageStatsManagerInternal;
110import android.appwidget.AppWidgetManager;
111import android.content.ActivityNotFoundException;
112import android.content.BroadcastReceiver;
113import android.content.ClipData;
114import android.content.ComponentCallbacks2;
115import android.content.ComponentName;
116import android.content.ContentProvider;
117import android.content.ContentResolver;
118import android.content.Context;
119import android.content.DialogInterface;
120import android.content.IContentProvider;
121import android.content.IIntentReceiver;
122import android.content.IIntentSender;
123import android.content.Intent;
124import android.content.IntentFilter;
125import android.content.IntentSender;
126import android.content.pm.ActivityInfo;
127import android.content.pm.ApplicationInfo;
128import android.content.pm.ConfigurationInfo;
129import android.content.pm.IPackageDataObserver;
130import android.content.pm.IPackageManager;
131import android.content.pm.InstrumentationInfo;
132import android.content.pm.PackageInfo;
133import android.content.pm.PackageManager;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PackageManagerInternal;
136import android.content.pm.ParceledListSlice;
137import android.content.pm.PathPermission;
138import android.content.pm.PermissionInfo;
139import android.content.pm.ProviderInfo;
140import android.content.pm.ResolveInfo;
141import android.content.pm.ServiceInfo;
142import android.content.pm.ShortcutServiceInternal;
143import android.content.pm.UserInfo;
144import android.content.res.CompatibilityInfo;
145import android.content.res.Configuration;
146import android.content.res.Resources;
147import android.database.ContentObserver;
148import android.graphics.Bitmap;
149import android.graphics.Point;
150import android.graphics.Rect;
151import android.location.LocationManager;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.BatteryStats;
156import android.os.Binder;
157import android.os.Build;
158import android.os.Bundle;
159import android.os.Debug;
160import android.os.DropBoxManager;
161import android.os.Environment;
162import android.os.FactoryTest;
163import android.os.FileObserver;
164import android.os.FileUtils;
165import android.os.Handler;
166import android.os.IBinder;
167import android.os.IPermissionController;
168import android.os.IProcessInfoService;
169import android.os.IProgressListener;
170import android.os.LocaleList;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.PersistableBundle;
176import android.os.PowerManager;
177import android.os.PowerManagerInternal;
178import android.os.Process;
179import android.os.RemoteCallbackList;
180import android.os.RemoteException;
181import android.os.ResultReceiver;
182import android.os.ServiceManager;
183import android.os.StrictMode;
184import android.os.SystemClock;
185import android.os.SystemProperties;
186import android.os.Trace;
187import android.os.TransactionTooLargeException;
188import android.os.UpdateLock;
189import android.os.UserHandle;
190import android.os.UserManager;
191import android.os.WorkSource;
192import android.os.storage.IMountService;
193import android.os.storage.MountServiceInternal;
194import android.os.storage.StorageManager;
195import android.provider.Settings;
196import android.service.voice.IVoiceInteractionSession;
197import android.service.voice.VoiceInteractionManagerInternal;
198import android.service.voice.VoiceInteractionSession;
199import android.telecom.TelecomManager;
200import android.text.format.DateUtils;
201import android.text.format.Time;
202import android.text.style.SuggestionSpan;
203import android.util.ArrayMap;
204import android.util.ArraySet;
205import android.util.AtomicFile;
206import android.util.DebugUtils;
207import android.util.DisplayMetrics;
208import android.util.EventLog;
209import android.util.Log;
210import android.util.Pair;
211import android.util.PrintWriterPrinter;
212import android.util.Slog;
213import android.util.SparseArray;
214import android.util.TimeUtils;
215import android.util.Xml;
216import android.view.Display;
217import android.view.Gravity;
218import android.view.LayoutInflater;
219import android.view.View;
220import android.view.WindowManager;
221
222import java.io.File;
223import java.io.FileDescriptor;
224import java.io.FileInputStream;
225import java.io.FileNotFoundException;
226import java.io.FileOutputStream;
227import java.io.IOException;
228import java.io.InputStreamReader;
229import java.io.PrintWriter;
230import java.io.StringWriter;
231import java.lang.ref.WeakReference;
232import java.nio.charset.StandardCharsets;
233import java.util.ArrayList;
234import java.util.Arrays;
235import java.util.Collections;
236import java.util.Comparator;
237import java.util.HashMap;
238import java.util.HashSet;
239import java.util.Iterator;
240import java.util.List;
241import java.util.Locale;
242import java.util.Map;
243import java.util.Objects;
244import java.util.Set;
245import java.util.concurrent.atomic.AtomicBoolean;
246import java.util.concurrent.atomic.AtomicLong;
247
248import dalvik.system.VMRuntime;
249
250import libcore.io.IoUtils;
251import libcore.util.EmptyArray;
252
253import static android.Manifest.permission.INTERACT_ACROSS_USERS;
254import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
255import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
256import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
257import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
258import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
259import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
260import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.HOME_STACK_ID;
263import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
264import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
265import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
266import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
267import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
268import static android.content.pm.PackageManager.GET_PROVIDERS;
269import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
270import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
272import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
276import static android.os.Process.PROC_CHAR;
277import static android.os.Process.PROC_OUT_LONG;
278import static android.os.Process.PROC_PARENS;
279import static android.os.Process.PROC_SPACE_TERM;
280import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
281import static android.provider.Settings.Global.DEBUG_APP;
282import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
283import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
284import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
285import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
286import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
287import static android.provider.Settings.System.FONT_SCALE;
288import static com.android.internal.util.XmlUtils.readBooleanAttribute;
289import static com.android.internal.util.XmlUtils.readIntAttribute;
290import static com.android.internal.util.XmlUtils.readLongAttribute;
291import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
292import static com.android.internal.util.XmlUtils.writeIntAttribute;
293import static com.android.internal.util.XmlUtils.writeLongAttribute;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
351import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
352import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
353import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
354import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
355import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
356import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
357import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
358import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
359import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
360import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
361import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
362import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
363import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
364import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
365import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
366import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
367import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
368import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
369import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
370import static org.xmlpull.v1.XmlPullParser.START_TAG;
371
372public final class ActivityManagerService extends ActivityManagerNative
373        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
374
375    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
376    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
377    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
378    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
379    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
380    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
381    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
382    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
383    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
384    private static final String TAG_LRU = TAG + POSTFIX_LRU;
385    private static final String TAG_MU = TAG + POSTFIX_MU;
386    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
387    private static final String TAG_POWER = TAG + POSTFIX_POWER;
388    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
389    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
390    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
391    private static final String TAG_PSS = TAG + POSTFIX_PSS;
392    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
393    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
394    private static final String TAG_STACK = TAG + POSTFIX_STACK;
395    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
396    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
397    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
398    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
399    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
400
401    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
402    // here so that while the job scheduler can depend on AMS, the other way around
403    // need not be the case.
404    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
405
406    /** Control over CPU and battery monitoring */
407    // write battery stats every 30 minutes.
408    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
409    static final boolean MONITOR_CPU_USAGE = true;
410    // don't sample cpu less than every 5 seconds.
411    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
412    // wait possibly forever for next cpu sample.
413    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
414    static final boolean MONITOR_THREAD_CPU_USAGE = false;
415
416    // The flags that are set for all calls we make to the package manager.
417    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
418
419    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
420
421    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
422
423    // Amount of time after a call to stopAppSwitches() during which we will
424    // prevent further untrusted switches from happening.
425    static final long APP_SWITCH_DELAY_TIME = 5*1000;
426
427    // How long we wait for a launched process to attach to the activity manager
428    // before we decide it's never going to come up for real.
429    static final int PROC_START_TIMEOUT = 10*1000;
430    // How long we wait for an attached process to publish its content providers
431    // before we decide it must be hung.
432    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
433
434    // How long we will retain processes hosting content providers in the "last activity"
435    // state before allowing them to drop down to the regular cached LRU list.  This is
436    // to avoid thrashing of provider processes under low memory situations.
437    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
438
439    // How long we wait for a launched process to attach to the activity manager
440    // before we decide it's never going to come up for real, when the process was
441    // started with a wrapper for instrumentation (such as Valgrind) because it
442    // could take much longer than usual.
443    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
444
445    // How long to wait after going idle before forcing apps to GC.
446    static final int GC_TIMEOUT = 5*1000;
447
448    // The minimum amount of time between successive GC requests for a process.
449    static final int GC_MIN_INTERVAL = 60*1000;
450
451    // The minimum amount of time between successive PSS requests for a process.
452    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
453
454    // The minimum amount of time between successive PSS requests for a process
455    // when the request is due to the memory state being lowered.
456    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
457
458    // The rate at which we check for apps using excessive power -- 15 mins.
459    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
460
461    // The minimum sample duration we will allow before deciding we have
462    // enough data on wake locks to start killing things.
463    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464
465    // The minimum sample duration we will allow before deciding we have
466    // enough data on CPU usage to start killing things.
467    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
468
469    // How long we allow a receiver to run before giving up on it.
470    static final int BROADCAST_FG_TIMEOUT = 10*1000;
471    static final int BROADCAST_BG_TIMEOUT = 60*1000;
472
473    // How long we wait until we timeout on key dispatching.
474    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
475
476    // How long we wait until we timeout on key dispatching during instrumentation.
477    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
478
479    // This is the amount of time an app needs to be running a foreground service before
480    // we will consider it to be doing interaction for usage stats.
481    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
482
483    // Maximum amount of time we will allow to elapse before re-reporting usage stats
484    // interaction with foreground processes.
485    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
486
487    // This is the amount of time we allow an app to settle after it goes into the background,
488    // before we start restricting what it can do.
489    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
490
491    // How long to wait in getAssistContextExtras for the activity and foreground services
492    // to respond with the result.
493    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
494
495    // How long top wait when going through the modern assist (which doesn't need to block
496    // on getting this result before starting to launch its UI).
497    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
498
499    // Maximum number of persisted Uri grants a package is allowed
500    static final int MAX_PERSISTED_URI_GRANTS = 128;
501
502    static final int MY_PID = Process.myPid();
503
504    static final String[] EMPTY_STRING_ARRAY = new String[0];
505
506    // How many bytes to write into the dropbox log before truncating
507    static final int DROPBOX_MAX_SIZE = 192 * 1024;
508    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
509    // as one line, but close enough for now.
510    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
511
512    // Access modes for handleIncomingUser.
513    static final int ALLOW_NON_FULL = 0;
514    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
515    static final int ALLOW_FULL_ONLY = 2;
516
517    // Delay in notifying task stack change listeners (in millis)
518    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
519
520    // Necessary ApplicationInfo flags to mark an app as persistent
521    private static final int PERSISTENT_MASK =
522            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
523
524    // Intent sent when remote bugreport collection has been completed
525    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
526            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
527
528    // Delay to disable app launch boost
529    static final int APP_BOOST_MESSAGE_DELAY = 3000;
530    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
531    static final int APP_BOOST_TIMEOUT = 2500;
532
533    // Used to indicate that a task is removed it should also be removed from recents.
534    private static final boolean REMOVE_FROM_RECENTS = true;
535    // Used to indicate that an app transition should be animated.
536    static final boolean ANIMATE = true;
537
538    // Determines whether to take full screen screenshots
539    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
540    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
541
542    private static native int nativeMigrateToBoost();
543    private static native int nativeMigrateFromBoost();
544    private boolean mIsBoosted = false;
545    private long mBoostStartTime = 0;
546
547    /** All system services */
548    SystemServiceManager mSystemServiceManager;
549
550    private Installer mInstaller;
551
552    /** Run all ActivityStacks through this */
553    final ActivityStackSupervisor mStackSupervisor;
554
555    final ActivityStarter mActivityStarter;
556
557    /** Task stack change listeners. */
558    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
559            new RemoteCallbackList<ITaskStackListener>();
560
561    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
562
563    public IntentFirewall mIntentFirewall;
564
565    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
566    // default actuion automatically.  Important for devices without direct input
567    // devices.
568    private boolean mShowDialogs = true;
569    private boolean mInVrMode = false;
570
571    BroadcastQueue mFgBroadcastQueue;
572    BroadcastQueue mBgBroadcastQueue;
573    // Convenient for easy iteration over the queues. Foreground is first
574    // so that dispatch of foreground broadcasts gets precedence.
575    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
576
577    BroadcastStats mLastBroadcastStats;
578    BroadcastStats mCurBroadcastStats;
579
580    BroadcastQueue broadcastQueueForIntent(Intent intent) {
581        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
582        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
583                "Broadcast intent " + intent + " on "
584                + (isFg ? "foreground" : "background") + " queue");
585        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
586    }
587
588    /**
589     * Activity we have told the window manager to have key focus.
590     */
591    ActivityRecord mFocusedActivity = null;
592
593    /**
594     * User id of the last activity mFocusedActivity was set to.
595     */
596    private int mLastFocusedUserId;
597
598    /**
599     * If non-null, we are tracking the time the user spends in the currently focused app.
600     */
601    private AppTimeTracker mCurAppTimeTracker;
602
603    /**
604     * List of intents that were used to start the most recent tasks.
605     */
606    final RecentTasks mRecentTasks;
607
608    /**
609     * For addAppTask: cached of the last activity component that was added.
610     */
611    ComponentName mLastAddedTaskComponent;
612
613    /**
614     * For addAppTask: cached of the last activity uid that was added.
615     */
616    int mLastAddedTaskUid;
617
618    /**
619     * For addAppTask: cached of the last ActivityInfo that was added.
620     */
621    ActivityInfo mLastAddedTaskActivity;
622
623    /**
624     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
625     */
626    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
627
628    /**
629     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
630     */
631    String mDeviceOwnerName;
632
633    final UserController mUserController;
634
635    final AppErrors mAppErrors;
636
637    boolean mDoingSetFocusedActivity;
638
639    public boolean canShowErrorDialogs() {
640        return mShowDialogs && !mSleeping && !mShuttingDown;
641    }
642
643    // it's a semaphore; boost when 0->1, reset when 1->0
644    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
645        @Override protected Integer initialValue() {
646            return 0;
647        }
648    };
649
650    static void boostPriorityForLockedSection() {
651        if (sIsBoosted.get() == 0) {
652            // boost to prio 118 while holding a global lock
653            Process.setThreadPriority(Process.myTid(), -2);
654            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
655        }
656        int cur = sIsBoosted.get();
657        sIsBoosted.set(cur + 1);
658    }
659
660    static void resetPriorityAfterLockedSection() {
661        sIsBoosted.set(sIsBoosted.get() - 1);
662        if (sIsBoosted.get() == 0) {
663            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
664            Process.setThreadPriority(Process.myTid(), 0);
665        }
666    }
667    public class PendingAssistExtras extends Binder implements Runnable {
668        public final ActivityRecord activity;
669        public final Bundle extras;
670        public final Intent intent;
671        public final String hint;
672        public final IResultReceiver receiver;
673        public final int userHandle;
674        public boolean haveResult = false;
675        public Bundle result = null;
676        public AssistStructure structure = null;
677        public AssistContent content = null;
678        public Bundle receiverExtras;
679
680        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
681                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
682            activity = _activity;
683            extras = _extras;
684            intent = _intent;
685            hint = _hint;
686            receiver = _receiver;
687            receiverExtras = _receiverExtras;
688            userHandle = _userHandle;
689        }
690        @Override
691        public void run() {
692            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
693            synchronized (this) {
694                haveResult = true;
695                notifyAll();
696            }
697            pendingAssistExtrasTimedOut(this);
698        }
699    }
700
701    final ArrayList<PendingAssistExtras> mPendingAssistExtras
702            = new ArrayList<PendingAssistExtras>();
703
704    /**
705     * Process management.
706     */
707    final ProcessList mProcessList = new ProcessList();
708
709    /**
710     * All of the applications we currently have running organized by name.
711     * The keys are strings of the application package name (as
712     * returned by the package manager), and the keys are ApplicationRecord
713     * objects.
714     */
715    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
716
717    /**
718     * Tracking long-term execution of processes to look for abuse and other
719     * bad app behavior.
720     */
721    final ProcessStatsService mProcessStats;
722
723    /**
724     * The currently running isolated processes.
725     */
726    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
727
728    /**
729     * Counter for assigning isolated process uids, to avoid frequently reusing the
730     * same ones.
731     */
732    int mNextIsolatedProcessUid = 0;
733
734    /**
735     * The currently running heavy-weight process, if any.
736     */
737    ProcessRecord mHeavyWeightProcess = null;
738
739    /**
740     * All of the processes we currently have running organized by pid.
741     * The keys are the pid running the application.
742     *
743     * <p>NOTE: This object is protected by its own lock, NOT the global
744     * activity manager lock!
745     */
746    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
747
748    /**
749     * All of the processes that have been forced to be foreground.  The key
750     * is the pid of the caller who requested it (we hold a death
751     * link on it).
752     */
753    abstract class ForegroundToken implements IBinder.DeathRecipient {
754        int pid;
755        IBinder token;
756    }
757    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
758
759    /**
760     * List of records for processes that someone had tried to start before the
761     * system was ready.  We don't start them at that point, but ensure they
762     * are started by the time booting is complete.
763     */
764    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
765
766    /**
767     * List of persistent applications that are in the process
768     * of being started.
769     */
770    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
771
772    /**
773     * Processes that are being forcibly torn down.
774     */
775    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
776
777    /**
778     * List of running applications, sorted by recent usage.
779     * The first entry in the list is the least recently used.
780     */
781    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
782
783    /**
784     * Where in mLruProcesses that the processes hosting activities start.
785     */
786    int mLruProcessActivityStart = 0;
787
788    /**
789     * Where in mLruProcesses that the processes hosting services start.
790     * This is after (lower index) than mLruProcessesActivityStart.
791     */
792    int mLruProcessServiceStart = 0;
793
794    /**
795     * List of processes that should gc as soon as things are idle.
796     */
797    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
798
799    /**
800     * Processes we want to collect PSS data from.
801     */
802    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
803
804    private boolean mBinderTransactionTrackingEnabled = false;
805
806    /**
807     * Last time we requested PSS data of all processes.
808     */
809    long mLastFullPssTime = SystemClock.uptimeMillis();
810
811    /**
812     * If set, the next time we collect PSS data we should do a full collection
813     * with data from native processes and the kernel.
814     */
815    boolean mFullPssPending = false;
816
817    /**
818     * This is the process holding what we currently consider to be
819     * the "home" activity.
820     */
821    ProcessRecord mHomeProcess;
822
823    /**
824     * This is the process holding the activity the user last visited that
825     * is in a different process from the one they are currently in.
826     */
827    ProcessRecord mPreviousProcess;
828
829    /**
830     * The time at which the previous process was last visible.
831     */
832    long mPreviousProcessVisibleTime;
833
834    /**
835     * Track all uids that have actively running processes.
836     */
837    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
838
839    /**
840     * This is for verifying the UID report flow.
841     */
842    static final boolean VALIDATE_UID_STATES = true;
843    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
844
845    /**
846     * Packages that the user has asked to have run in screen size
847     * compatibility mode instead of filling the screen.
848     */
849    final CompatModePackages mCompatModePackages;
850
851    /**
852     * Set of IntentSenderRecord objects that are currently active.
853     */
854    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
855            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
856
857    /**
858     * Fingerprints (hashCode()) of stack traces that we've
859     * already logged DropBox entries for.  Guarded by itself.  If
860     * something (rogue user app) forces this over
861     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
862     */
863    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
864    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
865
866    /**
867     * Strict Mode background batched logging state.
868     *
869     * The string buffer is guarded by itself, and its lock is also
870     * used to determine if another batched write is already
871     * in-flight.
872     */
873    private final StringBuilder mStrictModeBuffer = new StringBuilder();
874
875    /**
876     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
877     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
878     */
879    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
880
881    /**
882     * Resolver for broadcast intents to registered receivers.
883     * Holds BroadcastFilter (subclass of IntentFilter).
884     */
885    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
886            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
887        @Override
888        protected boolean allowFilterResult(
889                BroadcastFilter filter, List<BroadcastFilter> dest) {
890            IBinder target = filter.receiverList.receiver.asBinder();
891            for (int i = dest.size() - 1; i >= 0; i--) {
892                if (dest.get(i).receiverList.receiver.asBinder() == target) {
893                    return false;
894                }
895            }
896            return true;
897        }
898
899        @Override
900        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
901            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
902                    || userId == filter.owningUserId) {
903                return super.newResult(filter, match, userId);
904            }
905            return null;
906        }
907
908        @Override
909        protected BroadcastFilter[] newArray(int size) {
910            return new BroadcastFilter[size];
911        }
912
913        @Override
914        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
915            return packageName.equals(filter.packageName);
916        }
917    };
918
919    /**
920     * State of all active sticky broadcasts per user.  Keys are the action of the
921     * sticky Intent, values are an ArrayList of all broadcasted intents with
922     * that action (which should usually be one).  The SparseArray is keyed
923     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
924     * for stickies that are sent to all users.
925     */
926    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
927            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
928
929    final ActiveServices mServices;
930
931    final static class Association {
932        final int mSourceUid;
933        final String mSourceProcess;
934        final int mTargetUid;
935        final ComponentName mTargetComponent;
936        final String mTargetProcess;
937
938        int mCount;
939        long mTime;
940
941        int mNesting;
942        long mStartTime;
943
944        // states of the source process when the bind occurred.
945        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
946        long mLastStateUptime;
947        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
948                - ActivityManager.MIN_PROCESS_STATE+1];
949
950        Association(int sourceUid, String sourceProcess, int targetUid,
951                ComponentName targetComponent, String targetProcess) {
952            mSourceUid = sourceUid;
953            mSourceProcess = sourceProcess;
954            mTargetUid = targetUid;
955            mTargetComponent = targetComponent;
956            mTargetProcess = targetProcess;
957        }
958    }
959
960    /**
961     * When service association tracking is enabled, this is all of the associations we
962     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
963     * -> association data.
964     */
965    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
966            mAssociations = new SparseArray<>();
967    boolean mTrackingAssociations;
968
969    /**
970     * Backup/restore process management
971     */
972    String mBackupAppName = null;
973    BackupRecord mBackupTarget = null;
974
975    final ProviderMap mProviderMap;
976
977    /**
978     * List of content providers who have clients waiting for them.  The
979     * application is currently being launched and the provider will be
980     * removed from this list once it is published.
981     */
982    final ArrayList<ContentProviderRecord> mLaunchingProviders
983            = new ArrayList<ContentProviderRecord>();
984
985    /**
986     * File storing persisted {@link #mGrantedUriPermissions}.
987     */
988    private final AtomicFile mGrantFile;
989
990    /** XML constants used in {@link #mGrantFile} */
991    private static final String TAG_URI_GRANTS = "uri-grants";
992    private static final String TAG_URI_GRANT = "uri-grant";
993    private static final String ATTR_USER_HANDLE = "userHandle";
994    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
995    private static final String ATTR_TARGET_USER_ID = "targetUserId";
996    private static final String ATTR_SOURCE_PKG = "sourcePkg";
997    private static final String ATTR_TARGET_PKG = "targetPkg";
998    private static final String ATTR_URI = "uri";
999    private static final String ATTR_MODE_FLAGS = "modeFlags";
1000    private static final String ATTR_CREATED_TIME = "createdTime";
1001    private static final String ATTR_PREFIX = "prefix";
1002
1003    /**
1004     * Global set of specific {@link Uri} permissions that have been granted.
1005     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1006     * to {@link UriPermission#uri} to {@link UriPermission}.
1007     */
1008    @GuardedBy("this")
1009    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1010            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1011
1012    public static class GrantUri {
1013        public final int sourceUserId;
1014        public final Uri uri;
1015        public boolean prefix;
1016
1017        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1018            this.sourceUserId = sourceUserId;
1019            this.uri = uri;
1020            this.prefix = prefix;
1021        }
1022
1023        @Override
1024        public int hashCode() {
1025            int hashCode = 1;
1026            hashCode = 31 * hashCode + sourceUserId;
1027            hashCode = 31 * hashCode + uri.hashCode();
1028            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1029            return hashCode;
1030        }
1031
1032        @Override
1033        public boolean equals(Object o) {
1034            if (o instanceof GrantUri) {
1035                GrantUri other = (GrantUri) o;
1036                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1037                        && prefix == other.prefix;
1038            }
1039            return false;
1040        }
1041
1042        @Override
1043        public String toString() {
1044            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1045            if (prefix) result += " [prefix]";
1046            return result;
1047        }
1048
1049        public String toSafeString() {
1050            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1051            if (prefix) result += " [prefix]";
1052            return result;
1053        }
1054
1055        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1056            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1057                    ContentProvider.getUriWithoutUserId(uri), false);
1058        }
1059    }
1060
1061    CoreSettingsObserver mCoreSettingsObserver;
1062
1063    FontScaleSettingObserver mFontScaleSettingObserver;
1064
1065    private final class FontScaleSettingObserver extends ContentObserver {
1066        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1067
1068        public FontScaleSettingObserver() {
1069            super(mHandler);
1070            ContentResolver resolver = mContext.getContentResolver();
1071            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1072        }
1073
1074        @Override
1075        public void onChange(boolean selfChange, Uri uri) {
1076            if (mFontScaleUri.equals(uri)) {
1077                updateFontScaleIfNeeded();
1078            }
1079        }
1080    }
1081
1082    /**
1083     * Thread-local storage used to carry caller permissions over through
1084     * indirect content-provider access.
1085     */
1086    private class Identity {
1087        public final IBinder token;
1088        public final int pid;
1089        public final int uid;
1090
1091        Identity(IBinder _token, int _pid, int _uid) {
1092            token = _token;
1093            pid = _pid;
1094            uid = _uid;
1095        }
1096    }
1097
1098    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1099
1100    /**
1101     * All information we have collected about the runtime performance of
1102     * any user id that can impact battery performance.
1103     */
1104    final BatteryStatsService mBatteryStatsService;
1105
1106    /**
1107     * Information about component usage
1108     */
1109    UsageStatsManagerInternal mUsageStatsService;
1110
1111    /**
1112     * Access to DeviceIdleController service.
1113     */
1114    DeviceIdleController.LocalService mLocalDeviceIdleController;
1115
1116    /**
1117     * Information about and control over application operations
1118     */
1119    final AppOpsService mAppOpsService;
1120
1121    /**
1122     * Current configuration information.  HistoryRecord objects are given
1123     * a reference to this object to indicate which configuration they are
1124     * currently running in, so this object must be kept immutable.
1125     */
1126    Configuration mConfiguration = new Configuration();
1127
1128    /**
1129     * Current sequencing integer of the configuration, for skipping old
1130     * configurations.
1131     */
1132    int mConfigurationSeq = 0;
1133
1134    boolean mSuppressResizeConfigChanges = false;
1135
1136    /**
1137     * Hardware-reported OpenGLES version.
1138     */
1139    final int GL_ES_VERSION;
1140
1141    /**
1142     * List of initialization arguments to pass to all processes when binding applications to them.
1143     * For example, references to the commonly used services.
1144     */
1145    HashMap<String, IBinder> mAppBindArgs;
1146
1147    /**
1148     * Temporary to avoid allocations.  Protected by main lock.
1149     */
1150    final StringBuilder mStringBuilder = new StringBuilder(256);
1151
1152    /**
1153     * Used to control how we initialize the service.
1154     */
1155    ComponentName mTopComponent;
1156    String mTopAction = Intent.ACTION_MAIN;
1157    String mTopData;
1158
1159    volatile boolean mProcessesReady = false;
1160    volatile boolean mSystemReady = false;
1161    volatile boolean mOnBattery = false;
1162    volatile int mFactoryTest;
1163
1164    @GuardedBy("this") boolean mBooting = false;
1165    @GuardedBy("this") boolean mCallFinishBooting = false;
1166    @GuardedBy("this") boolean mBootAnimationComplete = false;
1167    @GuardedBy("this") boolean mLaunchWarningShown = false;
1168    @GuardedBy("this") boolean mCheckedForSetup = false;
1169
1170    Context mContext;
1171
1172    /**
1173     * The time at which we will allow normal application switches again,
1174     * after a call to {@link #stopAppSwitches()}.
1175     */
1176    long mAppSwitchesAllowedTime;
1177
1178    /**
1179     * This is set to true after the first switch after mAppSwitchesAllowedTime
1180     * is set; any switches after that will clear the time.
1181     */
1182    boolean mDidAppSwitch;
1183
1184    /**
1185     * Last time (in realtime) at which we checked for power usage.
1186     */
1187    long mLastPowerCheckRealtime;
1188
1189    /**
1190     * Last time (in uptime) at which we checked for power usage.
1191     */
1192    long mLastPowerCheckUptime;
1193
1194    /**
1195     * Set while we are wanting to sleep, to prevent any
1196     * activities from being started/resumed.
1197     */
1198    private boolean mSleeping = false;
1199
1200    /**
1201     * The process state used for processes that are running the top activities.
1202     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1203     */
1204    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1205
1206    /**
1207     * Set while we are running a voice interaction.  This overrides
1208     * sleeping while it is active.
1209     */
1210    private IVoiceInteractionSession mRunningVoice;
1211
1212    /**
1213     * For some direct access we need to power manager.
1214     */
1215    PowerManagerInternal mLocalPowerManager;
1216
1217    /**
1218     * We want to hold a wake lock while running a voice interaction session, since
1219     * this may happen with the screen off and we need to keep the CPU running to
1220     * be able to continue to interact with the user.
1221     */
1222    PowerManager.WakeLock mVoiceWakeLock;
1223
1224    /**
1225     * State of external calls telling us if the device is awake or asleep.
1226     */
1227    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1228
1229    /**
1230     * A list of tokens that cause the top activity to be put to sleep.
1231     * They are used by components that may hide and block interaction with underlying
1232     * activities.
1233     */
1234    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1235
1236    static final int LOCK_SCREEN_HIDDEN = 0;
1237    static final int LOCK_SCREEN_LEAVING = 1;
1238    static final int LOCK_SCREEN_SHOWN = 2;
1239    /**
1240     * State of external call telling us if the lock screen is shown.
1241     */
1242    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1243
1244    /**
1245     * Set if we are shutting down the system, similar to sleeping.
1246     */
1247    boolean mShuttingDown = false;
1248
1249    /**
1250     * Current sequence id for oom_adj computation traversal.
1251     */
1252    int mAdjSeq = 0;
1253
1254    /**
1255     * Current sequence id for process LRU updating.
1256     */
1257    int mLruSeq = 0;
1258
1259    /**
1260     * Keep track of the non-cached/empty process we last found, to help
1261     * determine how to distribute cached/empty processes next time.
1262     */
1263    int mNumNonCachedProcs = 0;
1264
1265    /**
1266     * Keep track of the number of cached hidden procs, to balance oom adj
1267     * distribution between those and empty procs.
1268     */
1269    int mNumCachedHiddenProcs = 0;
1270
1271    /**
1272     * Keep track of the number of service processes we last found, to
1273     * determine on the next iteration which should be B services.
1274     */
1275    int mNumServiceProcs = 0;
1276    int mNewNumAServiceProcs = 0;
1277    int mNewNumServiceProcs = 0;
1278
1279    /**
1280     * Allow the current computed overall memory level of the system to go down?
1281     * This is set to false when we are killing processes for reasons other than
1282     * memory management, so that the now smaller process list will not be taken as
1283     * an indication that memory is tighter.
1284     */
1285    boolean mAllowLowerMemLevel = false;
1286
1287    /**
1288     * The last computed memory level, for holding when we are in a state that
1289     * processes are going away for other reasons.
1290     */
1291    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1292
1293    /**
1294     * The last total number of process we have, to determine if changes actually look
1295     * like a shrinking number of process due to lower RAM.
1296     */
1297    int mLastNumProcesses;
1298
1299    /**
1300     * The uptime of the last time we performed idle maintenance.
1301     */
1302    long mLastIdleTime = SystemClock.uptimeMillis();
1303
1304    /**
1305     * Total time spent with RAM that has been added in the past since the last idle time.
1306     */
1307    long mLowRamTimeSinceLastIdle = 0;
1308
1309    /**
1310     * If RAM is currently low, when that horrible situation started.
1311     */
1312    long mLowRamStartTime = 0;
1313
1314    /**
1315     * For reporting to battery stats the current top application.
1316     */
1317    private String mCurResumedPackage = null;
1318    private int mCurResumedUid = -1;
1319
1320    /**
1321     * For reporting to battery stats the apps currently running foreground
1322     * service.  The ProcessMap is package/uid tuples; each of these contain
1323     * an array of the currently foreground processes.
1324     */
1325    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1326            = new ProcessMap<ArrayList<ProcessRecord>>();
1327
1328    /**
1329     * This is set if we had to do a delayed dexopt of an app before launching
1330     * it, to increase the ANR timeouts in that case.
1331     */
1332    boolean mDidDexOpt;
1333
1334    /**
1335     * Set if the systemServer made a call to enterSafeMode.
1336     */
1337    boolean mSafeMode;
1338
1339    /**
1340     * If true, we are running under a test environment so will sample PSS from processes
1341     * much more rapidly to try to collect better data when the tests are rapidly
1342     * running through apps.
1343     */
1344    boolean mTestPssMode = false;
1345
1346    String mDebugApp = null;
1347    boolean mWaitForDebugger = false;
1348    boolean mDebugTransient = false;
1349    String mOrigDebugApp = null;
1350    boolean mOrigWaitForDebugger = false;
1351    boolean mAlwaysFinishActivities = false;
1352    boolean mLenientBackgroundCheck = false;
1353    boolean mForceResizableActivities;
1354    boolean mSupportsMultiWindow;
1355    boolean mSupportsFreeformWindowManagement;
1356    boolean mSupportsPictureInPicture;
1357    boolean mSupportsLeanbackOnly;
1358    Rect mDefaultPinnedStackBounds;
1359    IActivityController mController = null;
1360    boolean mControllerIsAMonkey = false;
1361    String mProfileApp = null;
1362    ProcessRecord mProfileProc = null;
1363    String mProfileFile;
1364    ParcelFileDescriptor mProfileFd;
1365    int mSamplingInterval = 0;
1366    boolean mAutoStopProfiler = false;
1367    int mProfileType = 0;
1368    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1369    String mMemWatchDumpProcName;
1370    String mMemWatchDumpFile;
1371    int mMemWatchDumpPid;
1372    int mMemWatchDumpUid;
1373    String mTrackAllocationApp = null;
1374    String mNativeDebuggingApp = null;
1375
1376    final long[] mTmpLong = new long[2];
1377
1378    static final class ProcessChangeItem {
1379        static final int CHANGE_ACTIVITIES = 1<<0;
1380        static final int CHANGE_PROCESS_STATE = 1<<1;
1381        int changes;
1382        int uid;
1383        int pid;
1384        int processState;
1385        boolean foregroundActivities;
1386    }
1387
1388    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1389    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1390
1391    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1392    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1393
1394    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1395    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1396
1397    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1398    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1399
1400    /**
1401     * Runtime CPU use collection thread.  This object's lock is used to
1402     * perform synchronization with the thread (notifying it to run).
1403     */
1404    final Thread mProcessCpuThread;
1405
1406    /**
1407     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1408     * Must acquire this object's lock when accessing it.
1409     * NOTE: this lock will be held while doing long operations (trawling
1410     * through all processes in /proc), so it should never be acquired by
1411     * any critical paths such as when holding the main activity manager lock.
1412     */
1413    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1414            MONITOR_THREAD_CPU_USAGE);
1415    final AtomicLong mLastCpuTime = new AtomicLong(0);
1416    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1417
1418    long mLastWriteTime = 0;
1419
1420    /**
1421     * Used to retain an update lock when the foreground activity is in
1422     * immersive mode.
1423     */
1424    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1425
1426    /**
1427     * Set to true after the system has finished booting.
1428     */
1429    boolean mBooted = false;
1430
1431    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1432    int mProcessLimitOverride = -1;
1433
1434    WindowManagerService mWindowManager;
1435    final ActivityThread mSystemThread;
1436
1437    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1438        final ProcessRecord mApp;
1439        final int mPid;
1440        final IApplicationThread mAppThread;
1441
1442        AppDeathRecipient(ProcessRecord app, int pid,
1443                IApplicationThread thread) {
1444            if (DEBUG_ALL) Slog.v(
1445                TAG, "New death recipient " + this
1446                + " for thread " + thread.asBinder());
1447            mApp = app;
1448            mPid = pid;
1449            mAppThread = thread;
1450        }
1451
1452        @Override
1453        public void binderDied() {
1454            if (DEBUG_ALL) Slog.v(
1455                TAG, "Death received in " + this
1456                + " for thread " + mAppThread.asBinder());
1457            synchronized(ActivityManagerService.this) {
1458                appDiedLocked(mApp, mPid, mAppThread, true);
1459            }
1460        }
1461    }
1462
1463    static final int SHOW_ERROR_UI_MSG = 1;
1464    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1465    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1466    static final int UPDATE_CONFIGURATION_MSG = 4;
1467    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1468    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1469    static final int SERVICE_TIMEOUT_MSG = 12;
1470    static final int UPDATE_TIME_ZONE = 13;
1471    static final int SHOW_UID_ERROR_UI_MSG = 14;
1472    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1473    static final int PROC_START_TIMEOUT_MSG = 20;
1474    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1475    static final int KILL_APPLICATION_MSG = 22;
1476    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1477    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1478    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1479    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1480    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1481    static final int CLEAR_DNS_CACHE_MSG = 28;
1482    static final int UPDATE_HTTP_PROXY_MSG = 29;
1483    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1484    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1485    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1486    static final int REPORT_MEM_USAGE_MSG = 33;
1487    static final int REPORT_USER_SWITCH_MSG = 34;
1488    static final int CONTINUE_USER_SWITCH_MSG = 35;
1489    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1490    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1491    static final int PERSIST_URI_GRANTS_MSG = 38;
1492    static final int REQUEST_ALL_PSS_MSG = 39;
1493    static final int START_PROFILES_MSG = 40;
1494    static final int UPDATE_TIME = 41;
1495    static final int SYSTEM_USER_START_MSG = 42;
1496    static final int SYSTEM_USER_CURRENT_MSG = 43;
1497    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1498    static final int FINISH_BOOTING_MSG = 45;
1499    static final int START_USER_SWITCH_UI_MSG = 46;
1500    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1501    static final int DISMISS_DIALOG_UI_MSG = 48;
1502    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1503    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1504    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1505    static final int DELETE_DUMPHEAP_MSG = 52;
1506    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1507    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1508    static final int REPORT_TIME_TRACKER_MSG = 55;
1509    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1510    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1511    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1512    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1513    static final int IDLE_UIDS_MSG = 60;
1514    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1515    static final int LOG_STACK_STATE = 62;
1516    static final int VR_MODE_CHANGE_MSG = 63;
1517    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1518    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1519    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1520    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1521    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1522    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1523    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1524
1525    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1526    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1527    static final int FIRST_COMPAT_MODE_MSG = 300;
1528    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1529
1530    static ServiceThread sKillThread = null;
1531    static KillHandler sKillHandler = null;
1532
1533    CompatModeDialog mCompatModeDialog;
1534    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1535    long mLastMemUsageReportTime = 0;
1536
1537    /**
1538     * Flag whether the current user is a "monkey", i.e. whether
1539     * the UI is driven by a UI automation tool.
1540     */
1541    private boolean mUserIsMonkey;
1542
1543    /** Flag whether the device has a Recents UI */
1544    boolean mHasRecents;
1545
1546    /** The dimensions of the thumbnails in the Recents UI. */
1547    int mThumbnailWidth;
1548    int mThumbnailHeight;
1549    float mFullscreenThumbnailScale;
1550
1551    final ServiceThread mHandlerThread;
1552    final MainHandler mHandler;
1553    final UiHandler mUiHandler;
1554
1555    PackageManagerInternal mPackageManagerInt;
1556
1557    // VoiceInteraction session ID that changes for each new request except when
1558    // being called for multiwindow assist in a single session.
1559    private int mViSessionId = 1000;
1560
1561    final class KillHandler extends Handler {
1562        static final int KILL_PROCESS_GROUP_MSG = 4000;
1563
1564        public KillHandler(Looper looper) {
1565            super(looper, null, true);
1566        }
1567
1568        @Override
1569        public void handleMessage(Message msg) {
1570            switch (msg.what) {
1571                case KILL_PROCESS_GROUP_MSG:
1572                {
1573                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1574                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1575                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1576                }
1577                break;
1578
1579                default:
1580                    super.handleMessage(msg);
1581            }
1582        }
1583    }
1584
1585    final class UiHandler extends Handler {
1586        public UiHandler() {
1587            super(com.android.server.UiThread.get().getLooper(), null, true);
1588        }
1589
1590        @Override
1591        public void handleMessage(Message msg) {
1592            switch (msg.what) {
1593            case SHOW_ERROR_UI_MSG: {
1594                mAppErrors.handleShowAppErrorUi(msg);
1595                ensureBootCompleted();
1596            } break;
1597            case SHOW_NOT_RESPONDING_UI_MSG: {
1598                mAppErrors.handleShowAnrUi(msg);
1599                ensureBootCompleted();
1600            } break;
1601            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1602                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1603                synchronized (ActivityManagerService.this) {
1604                    ProcessRecord proc = (ProcessRecord) data.get("app");
1605                    if (proc == null) {
1606                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1607                        break;
1608                    }
1609                    if (proc.crashDialog != null) {
1610                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1611                        return;
1612                    }
1613                    AppErrorResult res = (AppErrorResult) data.get("result");
1614                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1615                        Dialog d = new StrictModeViolationDialog(mContext,
1616                                ActivityManagerService.this, res, proc);
1617                        d.show();
1618                        proc.crashDialog = d;
1619                    } else {
1620                        // The device is asleep, so just pretend that the user
1621                        // saw a crash dialog and hit "force quit".
1622                        res.set(0);
1623                    }
1624                }
1625                ensureBootCompleted();
1626            } break;
1627            case SHOW_FACTORY_ERROR_UI_MSG: {
1628                Dialog d = new FactoryErrorDialog(
1629                    mContext, msg.getData().getCharSequence("msg"));
1630                d.show();
1631                ensureBootCompleted();
1632            } break;
1633            case WAIT_FOR_DEBUGGER_UI_MSG: {
1634                synchronized (ActivityManagerService.this) {
1635                    ProcessRecord app = (ProcessRecord)msg.obj;
1636                    if (msg.arg1 != 0) {
1637                        if (!app.waitedForDebugger) {
1638                            Dialog d = new AppWaitingForDebuggerDialog(
1639                                    ActivityManagerService.this,
1640                                    mContext, app);
1641                            app.waitDialog = d;
1642                            app.waitedForDebugger = true;
1643                            d.show();
1644                        }
1645                    } else {
1646                        if (app.waitDialog != null) {
1647                            app.waitDialog.dismiss();
1648                            app.waitDialog = null;
1649                        }
1650                    }
1651                }
1652            } break;
1653            case SHOW_UID_ERROR_UI_MSG: {
1654                if (mShowDialogs) {
1655                    AlertDialog d = new BaseErrorDialog(mContext);
1656                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1657                    d.setCancelable(false);
1658                    d.setTitle(mContext.getText(R.string.android_system_label));
1659                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1660                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1661                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1662                    d.show();
1663                }
1664            } break;
1665            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1666                if (mShowDialogs) {
1667                    AlertDialog d = new BaseErrorDialog(mContext);
1668                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1669                    d.setCancelable(false);
1670                    d.setTitle(mContext.getText(R.string.android_system_label));
1671                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1672                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1673                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1674                    d.show();
1675                }
1676            } break;
1677            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1678                synchronized (ActivityManagerService.this) {
1679                    ActivityRecord ar = (ActivityRecord) msg.obj;
1680                    if (mCompatModeDialog != null) {
1681                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1682                                ar.info.applicationInfo.packageName)) {
1683                            return;
1684                        }
1685                        mCompatModeDialog.dismiss();
1686                        mCompatModeDialog = null;
1687                    }
1688                    if (ar != null && false) {
1689                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1690                                ar.packageName)) {
1691                            int mode = mCompatModePackages.computeCompatModeLocked(
1692                                    ar.info.applicationInfo);
1693                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1694                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1695                                mCompatModeDialog = new CompatModeDialog(
1696                                        ActivityManagerService.this, mContext,
1697                                        ar.info.applicationInfo);
1698                                mCompatModeDialog.show();
1699                            }
1700                        }
1701                    }
1702                }
1703                break;
1704            }
1705            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1706                synchronized (ActivityManagerService.this) {
1707                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1708                    if (mUnsupportedDisplaySizeDialog != null) {
1709                        mUnsupportedDisplaySizeDialog.dismiss();
1710                        mUnsupportedDisplaySizeDialog = null;
1711                    }
1712                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1713                            ar.packageName)) {
1714                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1715                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1716                        mUnsupportedDisplaySizeDialog.show();
1717                    }
1718                }
1719                break;
1720            }
1721            case START_USER_SWITCH_UI_MSG: {
1722                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1723                break;
1724            }
1725            case DISMISS_DIALOG_UI_MSG: {
1726                final Dialog d = (Dialog) msg.obj;
1727                d.dismiss();
1728                break;
1729            }
1730            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1731                dispatchProcessesChanged();
1732                break;
1733            }
1734            case DISPATCH_PROCESS_DIED_UI_MSG: {
1735                final int pid = msg.arg1;
1736                final int uid = msg.arg2;
1737                dispatchProcessDied(pid, uid);
1738                break;
1739            }
1740            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1741                dispatchUidsChanged();
1742            } break;
1743            }
1744        }
1745    }
1746
1747    final class MainHandler extends Handler {
1748        public MainHandler(Looper looper) {
1749            super(looper, null, true);
1750        }
1751
1752        @Override
1753        public void handleMessage(Message msg) {
1754            switch (msg.what) {
1755            case UPDATE_CONFIGURATION_MSG: {
1756                final ContentResolver resolver = mContext.getContentResolver();
1757                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1758                        msg.arg1);
1759            } break;
1760            case GC_BACKGROUND_PROCESSES_MSG: {
1761                synchronized (ActivityManagerService.this) {
1762                    performAppGcsIfAppropriateLocked();
1763                }
1764            } break;
1765            case SERVICE_TIMEOUT_MSG: {
1766                if (mDidDexOpt) {
1767                    mDidDexOpt = false;
1768                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1769                    nmsg.obj = msg.obj;
1770                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1771                    return;
1772                }
1773                mServices.serviceTimeout((ProcessRecord)msg.obj);
1774            } break;
1775            case UPDATE_TIME_ZONE: {
1776                synchronized (ActivityManagerService.this) {
1777                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1778                        ProcessRecord r = mLruProcesses.get(i);
1779                        if (r.thread != null) {
1780                            try {
1781                                r.thread.updateTimeZone();
1782                            } catch (RemoteException ex) {
1783                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1784                            }
1785                        }
1786                    }
1787                }
1788            } break;
1789            case CLEAR_DNS_CACHE_MSG: {
1790                synchronized (ActivityManagerService.this) {
1791                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1792                        ProcessRecord r = mLruProcesses.get(i);
1793                        if (r.thread != null) {
1794                            try {
1795                                r.thread.clearDnsCache();
1796                            } catch (RemoteException ex) {
1797                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1798                            }
1799                        }
1800                    }
1801                }
1802            } break;
1803            case UPDATE_HTTP_PROXY_MSG: {
1804                ProxyInfo proxy = (ProxyInfo)msg.obj;
1805                String host = "";
1806                String port = "";
1807                String exclList = "";
1808                Uri pacFileUrl = Uri.EMPTY;
1809                if (proxy != null) {
1810                    host = proxy.getHost();
1811                    port = Integer.toString(proxy.getPort());
1812                    exclList = proxy.getExclusionListAsString();
1813                    pacFileUrl = proxy.getPacFileUrl();
1814                }
1815                synchronized (ActivityManagerService.this) {
1816                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1817                        ProcessRecord r = mLruProcesses.get(i);
1818                        if (r.thread != null) {
1819                            try {
1820                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1821                            } catch (RemoteException ex) {
1822                                Slog.w(TAG, "Failed to update http proxy for: " +
1823                                        r.info.processName);
1824                            }
1825                        }
1826                    }
1827                }
1828            } break;
1829            case PROC_START_TIMEOUT_MSG: {
1830                if (mDidDexOpt) {
1831                    mDidDexOpt = false;
1832                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1833                    nmsg.obj = msg.obj;
1834                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1835                    return;
1836                }
1837                ProcessRecord app = (ProcessRecord)msg.obj;
1838                synchronized (ActivityManagerService.this) {
1839                    processStartTimedOutLocked(app);
1840                }
1841            } break;
1842            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1843                ProcessRecord app = (ProcessRecord)msg.obj;
1844                synchronized (ActivityManagerService.this) {
1845                    processContentProviderPublishTimedOutLocked(app);
1846                }
1847            } break;
1848            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1849                synchronized (ActivityManagerService.this) {
1850                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1851                }
1852            } break;
1853            case KILL_APPLICATION_MSG: {
1854                synchronized (ActivityManagerService.this) {
1855                    final int appId = msg.arg1;
1856                    final int userId = msg.arg2;
1857                    Bundle bundle = (Bundle)msg.obj;
1858                    String pkg = bundle.getString("pkg");
1859                    String reason = bundle.getString("reason");
1860                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1861                            false, userId, reason);
1862                }
1863            } break;
1864            case FINALIZE_PENDING_INTENT_MSG: {
1865                ((PendingIntentRecord)msg.obj).completeFinalize();
1866            } break;
1867            case POST_HEAVY_NOTIFICATION_MSG: {
1868                INotificationManager inm = NotificationManager.getService();
1869                if (inm == null) {
1870                    return;
1871                }
1872
1873                ActivityRecord root = (ActivityRecord)msg.obj;
1874                ProcessRecord process = root.app;
1875                if (process == null) {
1876                    return;
1877                }
1878
1879                try {
1880                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1881                    String text = mContext.getString(R.string.heavy_weight_notification,
1882                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1883                    Notification notification = new Notification.Builder(context)
1884                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1885                            .setWhen(0)
1886                            .setOngoing(true)
1887                            .setTicker(text)
1888                            .setColor(mContext.getColor(
1889                                    com.android.internal.R.color.system_notification_accent_color))
1890                            .setContentTitle(text)
1891                            .setContentText(
1892                                    mContext.getText(R.string.heavy_weight_notification_detail))
1893                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1894                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1895                                    new UserHandle(root.userId)))
1896                            .build();
1897                    try {
1898                        int[] outId = new int[1];
1899                        inm.enqueueNotificationWithTag("android", "android", null,
1900                                R.string.heavy_weight_notification,
1901                                notification, outId, root.userId);
1902                    } catch (RuntimeException e) {
1903                        Slog.w(ActivityManagerService.TAG,
1904                                "Error showing notification for heavy-weight app", e);
1905                    } catch (RemoteException e) {
1906                    }
1907                } catch (NameNotFoundException e) {
1908                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1909                }
1910            } break;
1911            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1912                INotificationManager inm = NotificationManager.getService();
1913                if (inm == null) {
1914                    return;
1915                }
1916                try {
1917                    inm.cancelNotificationWithTag("android", null,
1918                            R.string.heavy_weight_notification,  msg.arg1);
1919                } catch (RuntimeException e) {
1920                    Slog.w(ActivityManagerService.TAG,
1921                            "Error canceling notification for service", e);
1922                } catch (RemoteException e) {
1923                }
1924            } break;
1925            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1926                synchronized (ActivityManagerService.this) {
1927                    checkExcessivePowerUsageLocked(true);
1928                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1929                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1930                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1931                }
1932            } break;
1933            case REPORT_MEM_USAGE_MSG: {
1934                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1935                Thread thread = new Thread() {
1936                    @Override public void run() {
1937                        reportMemUsage(memInfos);
1938                    }
1939                };
1940                thread.start();
1941                break;
1942            }
1943            case REPORT_USER_SWITCH_MSG: {
1944                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1945                break;
1946            }
1947            case CONTINUE_USER_SWITCH_MSG: {
1948                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1949                break;
1950            }
1951            case USER_SWITCH_TIMEOUT_MSG: {
1952                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1953                break;
1954            }
1955            case IMMERSIVE_MODE_LOCK_MSG: {
1956                final boolean nextState = (msg.arg1 != 0);
1957                if (mUpdateLock.isHeld() != nextState) {
1958                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1959                            "Applying new update lock state '" + nextState
1960                            + "' for " + (ActivityRecord)msg.obj);
1961                    if (nextState) {
1962                        mUpdateLock.acquire();
1963                    } else {
1964                        mUpdateLock.release();
1965                    }
1966                }
1967                break;
1968            }
1969            case PERSIST_URI_GRANTS_MSG: {
1970                writeGrantedUriPermissions();
1971                break;
1972            }
1973            case REQUEST_ALL_PSS_MSG: {
1974                synchronized (ActivityManagerService.this) {
1975                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1976                }
1977                break;
1978            }
1979            case START_PROFILES_MSG: {
1980                synchronized (ActivityManagerService.this) {
1981                    mUserController.startProfilesLocked();
1982                }
1983                break;
1984            }
1985            case UPDATE_TIME: {
1986                synchronized (ActivityManagerService.this) {
1987                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1988                        ProcessRecord r = mLruProcesses.get(i);
1989                        if (r.thread != null) {
1990                            try {
1991                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1992                            } catch (RemoteException ex) {
1993                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1994                            }
1995                        }
1996                    }
1997                }
1998                break;
1999            }
2000            case SYSTEM_USER_START_MSG: {
2001                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2002                        Integer.toString(msg.arg1), msg.arg1);
2003                mSystemServiceManager.startUser(msg.arg1);
2004                break;
2005            }
2006            case SYSTEM_USER_UNLOCK_MSG: {
2007                final int userId = msg.arg1;
2008                mSystemServiceManager.unlockUser(userId);
2009                synchronized (ActivityManagerService.this) {
2010                    mRecentTasks.loadUserRecentsLocked(userId);
2011                }
2012                if (userId == UserHandle.USER_SYSTEM) {
2013                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2014                }
2015                installEncryptionUnawareProviders(userId);
2016                mUserController.finishUserUnlocked((UserState) msg.obj);
2017                break;
2018            }
2019            case SYSTEM_USER_CURRENT_MSG: {
2020                mBatteryStatsService.noteEvent(
2021                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2022                        Integer.toString(msg.arg2), msg.arg2);
2023                mBatteryStatsService.noteEvent(
2024                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2025                        Integer.toString(msg.arg1), msg.arg1);
2026                mSystemServiceManager.switchUser(msg.arg1);
2027                break;
2028            }
2029            case ENTER_ANIMATION_COMPLETE_MSG: {
2030                synchronized (ActivityManagerService.this) {
2031                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2032                    if (r != null && r.app != null && r.app.thread != null) {
2033                        try {
2034                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2035                        } catch (RemoteException e) {
2036                        }
2037                    }
2038                }
2039                break;
2040            }
2041            case FINISH_BOOTING_MSG: {
2042                if (msg.arg1 != 0) {
2043                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2044                    finishBooting();
2045                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2046                }
2047                if (msg.arg2 != 0) {
2048                    enableScreenAfterBoot();
2049                }
2050                break;
2051            }
2052            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2053                try {
2054                    Locale l = (Locale) msg.obj;
2055                    IBinder service = ServiceManager.getService("mount");
2056                    IMountService mountService = IMountService.Stub.asInterface(service);
2057                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2058                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2059                } catch (RemoteException e) {
2060                    Log.e(TAG, "Error storing locale for decryption UI", e);
2061                }
2062                break;
2063            }
2064            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2065                synchronized (ActivityManagerService.this) {
2066                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2067                        try {
2068                            // Make a one-way callback to the listener
2069                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2070                        } catch (RemoteException e){
2071                            // Handled by the RemoteCallbackList
2072                        }
2073                    }
2074                    mTaskStackListeners.finishBroadcast();
2075                }
2076                break;
2077            }
2078            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2079                synchronized (ActivityManagerService.this) {
2080                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2081                        try {
2082                            // Make a one-way callback to the listener
2083                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2084                        } catch (RemoteException e){
2085                            // Handled by the RemoteCallbackList
2086                        }
2087                    }
2088                    mTaskStackListeners.finishBroadcast();
2089                }
2090                break;
2091            }
2092            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2093                synchronized (ActivityManagerService.this) {
2094                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2095                        try {
2096                            // Make a one-way callback to the listener
2097                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2098                        } catch (RemoteException e){
2099                            // Handled by the RemoteCallbackList
2100                        }
2101                    }
2102                    mTaskStackListeners.finishBroadcast();
2103                }
2104                break;
2105            }
2106            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2107                synchronized (ActivityManagerService.this) {
2108                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2109                        try {
2110                            // Make a one-way callback to the listener
2111                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2112                        } catch (RemoteException e){
2113                            // Handled by the RemoteCallbackList
2114                        }
2115                    }
2116                    mTaskStackListeners.finishBroadcast();
2117                }
2118                break;
2119            }
2120            case NOTIFY_FORCED_RESIZABLE_MSG: {
2121                synchronized (ActivityManagerService.this) {
2122                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2123                        try {
2124                            // Make a one-way callback to the listener
2125                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2126                                    (String) msg.obj, msg.arg1);
2127                        } catch (RemoteException e){
2128                            // Handled by the RemoteCallbackList
2129                        }
2130                    }
2131                    mTaskStackListeners.finishBroadcast();
2132                }
2133                break;
2134            }
2135                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2136                    synchronized (ActivityManagerService.this) {
2137                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2138                            try {
2139                                // Make a one-way callback to the listener
2140                                mTaskStackListeners.getBroadcastItem(i)
2141                                        .onActivityDismissingDockedStack();
2142                            } catch (RemoteException e){
2143                                // Handled by the RemoteCallbackList
2144                            }
2145                        }
2146                        mTaskStackListeners.finishBroadcast();
2147                    }
2148                    break;
2149                }
2150            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2151                final int uid = msg.arg1;
2152                final byte[] firstPacket = (byte[]) msg.obj;
2153
2154                synchronized (mPidsSelfLocked) {
2155                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2156                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2157                        if (p.uid == uid) {
2158                            try {
2159                                p.thread.notifyCleartextNetwork(firstPacket);
2160                            } catch (RemoteException ignored) {
2161                            }
2162                        }
2163                    }
2164                }
2165                break;
2166            }
2167            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2168                final String procName;
2169                final int uid;
2170                final long memLimit;
2171                final String reportPackage;
2172                synchronized (ActivityManagerService.this) {
2173                    procName = mMemWatchDumpProcName;
2174                    uid = mMemWatchDumpUid;
2175                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2176                    if (val == null) {
2177                        val = mMemWatchProcesses.get(procName, 0);
2178                    }
2179                    if (val != null) {
2180                        memLimit = val.first;
2181                        reportPackage = val.second;
2182                    } else {
2183                        memLimit = 0;
2184                        reportPackage = null;
2185                    }
2186                }
2187                if (procName == null) {
2188                    return;
2189                }
2190
2191                if (DEBUG_PSS) Slog.d(TAG_PSS,
2192                        "Showing dump heap notification from " + procName + "/" + uid);
2193
2194                INotificationManager inm = NotificationManager.getService();
2195                if (inm == null) {
2196                    return;
2197                }
2198
2199                String text = mContext.getString(R.string.dump_heap_notification, procName);
2200
2201
2202                Intent deleteIntent = new Intent();
2203                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2204                Intent intent = new Intent();
2205                intent.setClassName("android", DumpHeapActivity.class.getName());
2206                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2207                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2208                if (reportPackage != null) {
2209                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2210                }
2211                int userId = UserHandle.getUserId(uid);
2212                Notification notification = new Notification.Builder(mContext)
2213                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2214                        .setWhen(0)
2215                        .setOngoing(true)
2216                        .setAutoCancel(true)
2217                        .setTicker(text)
2218                        .setColor(mContext.getColor(
2219                                com.android.internal.R.color.system_notification_accent_color))
2220                        .setContentTitle(text)
2221                        .setContentText(
2222                                mContext.getText(R.string.dump_heap_notification_detail))
2223                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2224                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2225                                new UserHandle(userId)))
2226                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2227                                deleteIntent, 0, UserHandle.SYSTEM))
2228                        .build();
2229
2230                try {
2231                    int[] outId = new int[1];
2232                    inm.enqueueNotificationWithTag("android", "android", null,
2233                            R.string.dump_heap_notification,
2234                            notification, outId, userId);
2235                } catch (RuntimeException e) {
2236                    Slog.w(ActivityManagerService.TAG,
2237                            "Error showing notification for dump heap", e);
2238                } catch (RemoteException e) {
2239                }
2240            } break;
2241            case DELETE_DUMPHEAP_MSG: {
2242                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2243                        DumpHeapActivity.JAVA_URI,
2244                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2245                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2246                        UserHandle.myUserId());
2247                synchronized (ActivityManagerService.this) {
2248                    mMemWatchDumpFile = null;
2249                    mMemWatchDumpProcName = null;
2250                    mMemWatchDumpPid = -1;
2251                    mMemWatchDumpUid = -1;
2252                }
2253            } break;
2254            case FOREGROUND_PROFILE_CHANGED_MSG: {
2255                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2256            } break;
2257            case REPORT_TIME_TRACKER_MSG: {
2258                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2259                tracker.deliverResult(mContext);
2260            } break;
2261            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2262                mUserController.dispatchUserSwitchComplete(msg.arg1);
2263            } break;
2264            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2265                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2266                try {
2267                    connection.shutdown();
2268                } catch (RemoteException e) {
2269                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2270                }
2271                // Only a UiAutomation can set this flag and now that
2272                // it is finished we make sure it is reset to its default.
2273                mUserIsMonkey = false;
2274            } break;
2275            case APP_BOOST_DEACTIVATE_MSG: {
2276                synchronized(ActivityManagerService.this) {
2277                    if (mIsBoosted) {
2278                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2279                            nativeMigrateFromBoost();
2280                            mIsBoosted = false;
2281                            mBoostStartTime = 0;
2282                        } else {
2283                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2284                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2285                        }
2286                    }
2287                }
2288            } break;
2289            case IDLE_UIDS_MSG: {
2290                idleUids();
2291            } break;
2292            case LOG_STACK_STATE: {
2293                synchronized (ActivityManagerService.this) {
2294                    mStackSupervisor.logStackState();
2295                }
2296            } break;
2297            case VR_MODE_CHANGE_MSG: {
2298                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2299                final ActivityRecord r = (ActivityRecord) msg.obj;
2300                boolean vrMode;
2301                ComponentName requestedPackage;
2302                ComponentName callingPackage;
2303                int userId;
2304                synchronized (ActivityManagerService.this) {
2305                    vrMode = r.requestedVrComponent != null;
2306                    requestedPackage = r.requestedVrComponent;
2307                    userId = r.userId;
2308                    callingPackage = r.info.getComponentName();
2309                    if (mInVrMode != vrMode) {
2310                        mInVrMode = vrMode;
2311                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2312                    }
2313                }
2314                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2315            } break;
2316            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2317                final ActivityRecord r = (ActivityRecord) msg.obj;
2318                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2319                if (needsVrMode) {
2320                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2321                            r.info.getComponentName(), false);
2322                }
2323            } break;
2324            }
2325        }
2326    };
2327
2328    static final int COLLECT_PSS_BG_MSG = 1;
2329
2330    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2331        @Override
2332        public void handleMessage(Message msg) {
2333            switch (msg.what) {
2334            case COLLECT_PSS_BG_MSG: {
2335                long start = SystemClock.uptimeMillis();
2336                MemInfoReader memInfo = null;
2337                synchronized (ActivityManagerService.this) {
2338                    if (mFullPssPending) {
2339                        mFullPssPending = false;
2340                        memInfo = new MemInfoReader();
2341                    }
2342                }
2343                if (memInfo != null) {
2344                    updateCpuStatsNow();
2345                    long nativeTotalPss = 0;
2346                    synchronized (mProcessCpuTracker) {
2347                        final int N = mProcessCpuTracker.countStats();
2348                        for (int j=0; j<N; j++) {
2349                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2350                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2351                                // This is definitely an application process; skip it.
2352                                continue;
2353                            }
2354                            synchronized (mPidsSelfLocked) {
2355                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2356                                    // This is one of our own processes; skip it.
2357                                    continue;
2358                                }
2359                            }
2360                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2361                        }
2362                    }
2363                    memInfo.readMemInfo();
2364                    synchronized (ActivityManagerService.this) {
2365                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2366                                + (SystemClock.uptimeMillis()-start) + "ms");
2367                        final long cachedKb = memInfo.getCachedSizeKb();
2368                        final long freeKb = memInfo.getFreeSizeKb();
2369                        final long zramKb = memInfo.getZramTotalSizeKb();
2370                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2371                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2372                                kernelKb*1024, nativeTotalPss*1024);
2373                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2374                                nativeTotalPss);
2375                    }
2376                }
2377
2378                int num = 0;
2379                long[] tmp = new long[2];
2380                do {
2381                    ProcessRecord proc;
2382                    int procState;
2383                    int pid;
2384                    long lastPssTime;
2385                    synchronized (ActivityManagerService.this) {
2386                        if (mPendingPssProcesses.size() <= 0) {
2387                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2388                                    "Collected PSS of " + num + " processes in "
2389                                    + (SystemClock.uptimeMillis() - start) + "ms");
2390                            mPendingPssProcesses.clear();
2391                            return;
2392                        }
2393                        proc = mPendingPssProcesses.remove(0);
2394                        procState = proc.pssProcState;
2395                        lastPssTime = proc.lastPssTime;
2396                        if (proc.thread != null && procState == proc.setProcState
2397                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2398                                        < SystemClock.uptimeMillis()) {
2399                            pid = proc.pid;
2400                        } else {
2401                            proc = null;
2402                            pid = 0;
2403                        }
2404                    }
2405                    if (proc != null) {
2406                        long pss = Debug.getPss(pid, tmp, null);
2407                        synchronized (ActivityManagerService.this) {
2408                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2409                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2410                                num++;
2411                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2412                                        SystemClock.uptimeMillis());
2413                            }
2414                        }
2415                    }
2416                } while (true);
2417            }
2418            }
2419        }
2420    };
2421
2422    public void setSystemProcess() {
2423        try {
2424            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2425            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2426            ServiceManager.addService("meminfo", new MemBinder(this));
2427            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2428            ServiceManager.addService("dbinfo", new DbBinder(this));
2429            if (MONITOR_CPU_USAGE) {
2430                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2431            }
2432            ServiceManager.addService("permission", new PermissionController(this));
2433            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2434
2435            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2436                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2437            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2438
2439            synchronized (this) {
2440                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2441                app.persistent = true;
2442                app.pid = MY_PID;
2443                app.maxAdj = ProcessList.SYSTEM_ADJ;
2444                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2445                synchronized (mPidsSelfLocked) {
2446                    mPidsSelfLocked.put(app.pid, app);
2447                }
2448                updateLruProcessLocked(app, false, null);
2449                updateOomAdjLocked();
2450            }
2451        } catch (PackageManager.NameNotFoundException e) {
2452            throw new RuntimeException(
2453                    "Unable to find android system package", e);
2454        }
2455    }
2456
2457    public void setWindowManager(WindowManagerService wm) {
2458        mWindowManager = wm;
2459        mStackSupervisor.setWindowManager(wm);
2460        mActivityStarter.setWindowManager(wm);
2461    }
2462
2463    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2464        mUsageStatsService = usageStatsManager;
2465    }
2466
2467    public void startObservingNativeCrashes() {
2468        final NativeCrashListener ncl = new NativeCrashListener(this);
2469        ncl.start();
2470    }
2471
2472    public IAppOpsService getAppOpsService() {
2473        return mAppOpsService;
2474    }
2475
2476    static class MemBinder extends Binder {
2477        ActivityManagerService mActivityManagerService;
2478        MemBinder(ActivityManagerService activityManagerService) {
2479            mActivityManagerService = activityManagerService;
2480        }
2481
2482        @Override
2483        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2484            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2485                    != PackageManager.PERMISSION_GRANTED) {
2486                pw.println("Permission Denial: can't dump meminfo from from pid="
2487                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2488                        + " without permission " + android.Manifest.permission.DUMP);
2489                return;
2490            }
2491
2492            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2493        }
2494    }
2495
2496    static class GraphicsBinder extends Binder {
2497        ActivityManagerService mActivityManagerService;
2498        GraphicsBinder(ActivityManagerService activityManagerService) {
2499            mActivityManagerService = activityManagerService;
2500        }
2501
2502        @Override
2503        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2504            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2505                    != PackageManager.PERMISSION_GRANTED) {
2506                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2507                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2508                        + " without permission " + android.Manifest.permission.DUMP);
2509                return;
2510            }
2511
2512            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2513        }
2514    }
2515
2516    static class DbBinder extends Binder {
2517        ActivityManagerService mActivityManagerService;
2518        DbBinder(ActivityManagerService activityManagerService) {
2519            mActivityManagerService = activityManagerService;
2520        }
2521
2522        @Override
2523        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2524            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2525                    != PackageManager.PERMISSION_GRANTED) {
2526                pw.println("Permission Denial: can't dump dbinfo from from pid="
2527                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2528                        + " without permission " + android.Manifest.permission.DUMP);
2529                return;
2530            }
2531
2532            mActivityManagerService.dumpDbInfo(fd, pw, args);
2533        }
2534    }
2535
2536    static class CpuBinder extends Binder {
2537        ActivityManagerService mActivityManagerService;
2538        CpuBinder(ActivityManagerService activityManagerService) {
2539            mActivityManagerService = activityManagerService;
2540        }
2541
2542        @Override
2543        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2544            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2545                    != PackageManager.PERMISSION_GRANTED) {
2546                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2547                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2548                        + " without permission " + android.Manifest.permission.DUMP);
2549                return;
2550            }
2551
2552            synchronized (mActivityManagerService.mProcessCpuTracker) {
2553                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2554                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2555                        SystemClock.uptimeMillis()));
2556            }
2557        }
2558    }
2559
2560    public static final class Lifecycle extends SystemService {
2561        private final ActivityManagerService mService;
2562
2563        public Lifecycle(Context context) {
2564            super(context);
2565            mService = new ActivityManagerService(context);
2566        }
2567
2568        @Override
2569        public void onStart() {
2570            mService.start();
2571        }
2572
2573        public ActivityManagerService getService() {
2574            return mService;
2575        }
2576    }
2577
2578    // Note: This method is invoked on the main thread but may need to attach various
2579    // handlers to other threads.  So take care to be explicit about the looper.
2580    public ActivityManagerService(Context systemContext) {
2581        mContext = systemContext;
2582        mFactoryTest = FactoryTest.getMode();
2583        mSystemThread = ActivityThread.currentActivityThread();
2584
2585        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2586
2587        mHandlerThread = new ServiceThread(TAG,
2588                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2589        mHandlerThread.start();
2590        mHandler = new MainHandler(mHandlerThread.getLooper());
2591        mUiHandler = new UiHandler();
2592
2593        /* static; one-time init here */
2594        if (sKillHandler == null) {
2595            sKillThread = new ServiceThread(TAG + ":kill",
2596                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2597            sKillThread.start();
2598            sKillHandler = new KillHandler(sKillThread.getLooper());
2599        }
2600
2601        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2602                "foreground", BROADCAST_FG_TIMEOUT, false);
2603        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2604                "background", BROADCAST_BG_TIMEOUT, true);
2605        mBroadcastQueues[0] = mFgBroadcastQueue;
2606        mBroadcastQueues[1] = mBgBroadcastQueue;
2607
2608        mServices = new ActiveServices(this);
2609        mProviderMap = new ProviderMap(this);
2610        mAppErrors = new AppErrors(mContext, this);
2611
2612        // TODO: Move creation of battery stats service outside of activity manager service.
2613        File dataDir = Environment.getDataDirectory();
2614        File systemDir = new File(dataDir, "system");
2615        systemDir.mkdirs();
2616        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2617        mBatteryStatsService.getActiveStatistics().readLocked();
2618        mBatteryStatsService.scheduleWriteToDisk();
2619        mOnBattery = DEBUG_POWER ? true
2620                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2621        mBatteryStatsService.getActiveStatistics().setCallback(this);
2622
2623        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2624
2625        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2626        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2627                new IAppOpsCallback.Stub() {
2628                    @Override public void opChanged(int op, int uid, String packageName) {
2629                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2630                            if (mAppOpsService.checkOperation(op, uid, packageName)
2631                                    != AppOpsManager.MODE_ALLOWED) {
2632                                runInBackgroundDisabled(uid);
2633                            }
2634                        }
2635                    }
2636                });
2637
2638        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2639
2640        mUserController = new UserController(this);
2641
2642        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2643            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2644
2645        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2646
2647        mConfiguration.setToDefaults();
2648        mConfiguration.setLocales(LocaleList.getDefault());
2649
2650        mConfigurationSeq = mConfiguration.seq = 1;
2651        mProcessCpuTracker.init();
2652
2653        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2654        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2655        mStackSupervisor = new ActivityStackSupervisor(this);
2656        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2657        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2658
2659        mProcessCpuThread = new Thread("CpuTracker") {
2660            @Override
2661            public void run() {
2662                while (true) {
2663                    try {
2664                        try {
2665                            synchronized(this) {
2666                                final long now = SystemClock.uptimeMillis();
2667                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2668                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2669                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2670                                //        + ", write delay=" + nextWriteDelay);
2671                                if (nextWriteDelay < nextCpuDelay) {
2672                                    nextCpuDelay = nextWriteDelay;
2673                                }
2674                                if (nextCpuDelay > 0) {
2675                                    mProcessCpuMutexFree.set(true);
2676                                    this.wait(nextCpuDelay);
2677                                }
2678                            }
2679                        } catch (InterruptedException e) {
2680                        }
2681                        updateCpuStatsNow();
2682                    } catch (Exception e) {
2683                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2684                    }
2685                }
2686            }
2687        };
2688
2689        Watchdog.getInstance().addMonitor(this);
2690        Watchdog.getInstance().addThread(mHandler);
2691    }
2692
2693    public void setSystemServiceManager(SystemServiceManager mgr) {
2694        mSystemServiceManager = mgr;
2695    }
2696
2697    public void setInstaller(Installer installer) {
2698        mInstaller = installer;
2699    }
2700
2701    private void start() {
2702        Process.removeAllProcessGroups();
2703        mProcessCpuThread.start();
2704
2705        mBatteryStatsService.publish(mContext);
2706        mAppOpsService.publish(mContext);
2707        Slog.d("AppOps", "AppOpsService published");
2708        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2709    }
2710
2711    void onUserStoppedLocked(int userId) {
2712        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2713    }
2714
2715    public void initPowerManagement() {
2716        mStackSupervisor.initPowerManagement();
2717        mBatteryStatsService.initPowerManagement();
2718        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2719        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2720        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2721        mVoiceWakeLock.setReferenceCounted(false);
2722    }
2723
2724    @Override
2725    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2726            throws RemoteException {
2727        if (code == SYSPROPS_TRANSACTION) {
2728            // We need to tell all apps about the system property change.
2729            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2730            synchronized(this) {
2731                final int NP = mProcessNames.getMap().size();
2732                for (int ip=0; ip<NP; ip++) {
2733                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2734                    final int NA = apps.size();
2735                    for (int ia=0; ia<NA; ia++) {
2736                        ProcessRecord app = apps.valueAt(ia);
2737                        if (app.thread != null) {
2738                            procs.add(app.thread.asBinder());
2739                        }
2740                    }
2741                }
2742            }
2743
2744            int N = procs.size();
2745            for (int i=0; i<N; i++) {
2746                Parcel data2 = Parcel.obtain();
2747                try {
2748                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2749                } catch (RemoteException e) {
2750                }
2751                data2.recycle();
2752            }
2753        }
2754        try {
2755            return super.onTransact(code, data, reply, flags);
2756        } catch (RuntimeException e) {
2757            // The activity manager only throws security exceptions, so let's
2758            // log all others.
2759            if (!(e instanceof SecurityException)) {
2760                Slog.wtf(TAG, "Activity Manager Crash", e);
2761            }
2762            throw e;
2763        }
2764    }
2765
2766    void updateCpuStats() {
2767        final long now = SystemClock.uptimeMillis();
2768        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2769            return;
2770        }
2771        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2772            synchronized (mProcessCpuThread) {
2773                mProcessCpuThread.notify();
2774            }
2775        }
2776    }
2777
2778    void updateCpuStatsNow() {
2779        synchronized (mProcessCpuTracker) {
2780            mProcessCpuMutexFree.set(false);
2781            final long now = SystemClock.uptimeMillis();
2782            boolean haveNewCpuStats = false;
2783
2784            if (MONITOR_CPU_USAGE &&
2785                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2786                mLastCpuTime.set(now);
2787                mProcessCpuTracker.update();
2788                if (mProcessCpuTracker.hasGoodLastStats()) {
2789                    haveNewCpuStats = true;
2790                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2791                    //Slog.i(TAG, "Total CPU usage: "
2792                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2793
2794                    // Slog the cpu usage if the property is set.
2795                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2796                        int user = mProcessCpuTracker.getLastUserTime();
2797                        int system = mProcessCpuTracker.getLastSystemTime();
2798                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2799                        int irq = mProcessCpuTracker.getLastIrqTime();
2800                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2801                        int idle = mProcessCpuTracker.getLastIdleTime();
2802
2803                        int total = user + system + iowait + irq + softIrq + idle;
2804                        if (total == 0) total = 1;
2805
2806                        EventLog.writeEvent(EventLogTags.CPU,
2807                                ((user+system+iowait+irq+softIrq) * 100) / total,
2808                                (user * 100) / total,
2809                                (system * 100) / total,
2810                                (iowait * 100) / total,
2811                                (irq * 100) / total,
2812                                (softIrq * 100) / total);
2813                    }
2814                }
2815            }
2816
2817            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2818            synchronized(bstats) {
2819                synchronized(mPidsSelfLocked) {
2820                    if (haveNewCpuStats) {
2821                        if (bstats.startAddingCpuLocked()) {
2822                            int totalUTime = 0;
2823                            int totalSTime = 0;
2824                            final int N = mProcessCpuTracker.countStats();
2825                            for (int i=0; i<N; i++) {
2826                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2827                                if (!st.working) {
2828                                    continue;
2829                                }
2830                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2831                                totalUTime += st.rel_utime;
2832                                totalSTime += st.rel_stime;
2833                                if (pr != null) {
2834                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2835                                    if (ps == null || !ps.isActive()) {
2836                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2837                                                pr.info.uid, pr.processName);
2838                                    }
2839                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2840                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2841                                } else {
2842                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2843                                    if (ps == null || !ps.isActive()) {
2844                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2845                                                bstats.mapUid(st.uid), st.name);
2846                                    }
2847                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2848                                }
2849                            }
2850                            final int userTime = mProcessCpuTracker.getLastUserTime();
2851                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2852                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2853                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2854                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2855                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2856                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2857                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2858                        }
2859                    }
2860                }
2861
2862                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2863                    mLastWriteTime = now;
2864                    mBatteryStatsService.scheduleWriteToDisk();
2865                }
2866            }
2867        }
2868    }
2869
2870    @Override
2871    public void batteryNeedsCpuUpdate() {
2872        updateCpuStatsNow();
2873    }
2874
2875    @Override
2876    public void batteryPowerChanged(boolean onBattery) {
2877        // When plugging in, update the CPU stats first before changing
2878        // the plug state.
2879        updateCpuStatsNow();
2880        synchronized (this) {
2881            synchronized(mPidsSelfLocked) {
2882                mOnBattery = DEBUG_POWER ? true : onBattery;
2883            }
2884        }
2885    }
2886
2887    @Override
2888    public void batterySendBroadcast(Intent intent) {
2889        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2890                AppOpsManager.OP_NONE, null, false, false,
2891                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2892    }
2893
2894    /**
2895     * Initialize the application bind args. These are passed to each
2896     * process when the bindApplication() IPC is sent to the process. They're
2897     * lazily setup to make sure the services are running when they're asked for.
2898     */
2899    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2900        if (mAppBindArgs == null) {
2901            mAppBindArgs = new HashMap<>();
2902
2903            // Isolated processes won't get this optimization, so that we don't
2904            // violate the rules about which services they have access to.
2905            if (!isolated) {
2906                // Setup the application init args
2907                mAppBindArgs.put("package", ServiceManager.getService("package"));
2908                mAppBindArgs.put("window", ServiceManager.getService("window"));
2909                mAppBindArgs.put(Context.ALARM_SERVICE,
2910                        ServiceManager.getService(Context.ALARM_SERVICE));
2911            }
2912        }
2913        return mAppBindArgs;
2914    }
2915
2916    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2917        if (r == null || mFocusedActivity == r) {
2918            return false;
2919        }
2920
2921        if (!r.isFocusable()) {
2922            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2923            return false;
2924        }
2925
2926        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2927
2928        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2929        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2930                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2931        mDoingSetFocusedActivity = true;
2932
2933        final ActivityRecord last = mFocusedActivity;
2934        mFocusedActivity = r;
2935        if (r.task.isApplicationTask()) {
2936            if (mCurAppTimeTracker != r.appTimeTracker) {
2937                // We are switching app tracking.  Complete the current one.
2938                if (mCurAppTimeTracker != null) {
2939                    mCurAppTimeTracker.stop();
2940                    mHandler.obtainMessage(
2941                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2942                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2943                    mCurAppTimeTracker = null;
2944                }
2945                if (r.appTimeTracker != null) {
2946                    mCurAppTimeTracker = r.appTimeTracker;
2947                    startTimeTrackingFocusedActivityLocked();
2948                }
2949            } else {
2950                startTimeTrackingFocusedActivityLocked();
2951            }
2952        } else {
2953            r.appTimeTracker = null;
2954        }
2955        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2956        // TODO: Probably not, because we don't want to resume voice on switching
2957        // back to this activity
2958        if (r.task.voiceInteractor != null) {
2959            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2960        } else {
2961            finishRunningVoiceLocked();
2962            IVoiceInteractionSession session;
2963            if (last != null && ((session = last.task.voiceSession) != null
2964                    || (session = last.voiceSession) != null)) {
2965                // We had been in a voice interaction session, but now focused has
2966                // move to something different.  Just finish the session, we can't
2967                // return to it and retain the proper state and synchronization with
2968                // the voice interaction service.
2969                finishVoiceTask(session);
2970            }
2971        }
2972        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2973            mWindowManager.setFocusedApp(r.appToken, true);
2974        }
2975        applyUpdateLockStateLocked(r);
2976        applyUpdateVrModeLocked(r);
2977        if (mFocusedActivity.userId != mLastFocusedUserId) {
2978            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2979            mHandler.obtainMessage(
2980                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2981            mLastFocusedUserId = mFocusedActivity.userId;
2982        }
2983
2984        // Log a warning if the focused app is changed during the process. This could
2985        // indicate a problem of the focus setting logic!
2986        if (mFocusedActivity != r) Slog.w(TAG,
2987                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2988        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2989
2990        EventLogTags.writeAmFocusedActivity(
2991                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2992                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2993                reason);
2994        return true;
2995    }
2996
2997    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2998        if (mFocusedActivity != goingAway) {
2999            return;
3000        }
3001
3002        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3003        if (focusedStack != null) {
3004            final ActivityRecord top = focusedStack.topActivity();
3005            if (top != null && top.userId != mLastFocusedUserId) {
3006                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3007                mHandler.sendMessage(
3008                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3009                mLastFocusedUserId = top.userId;
3010            }
3011        }
3012
3013        // Try to move focus to another activity if possible.
3014        if (setFocusedActivityLocked(
3015                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3016            return;
3017        }
3018
3019        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3020                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3021        mFocusedActivity = null;
3022        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3023    }
3024
3025    @Override
3026    public void setFocusedStack(int stackId) {
3027        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3028        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3029        final long callingId = Binder.clearCallingIdentity();
3030        try {
3031            synchronized (this) {
3032                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3033                if (stack == null) {
3034                    return;
3035                }
3036                final ActivityRecord r = stack.topRunningActivityLocked();
3037                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3038                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3039                }
3040            }
3041        } finally {
3042            Binder.restoreCallingIdentity(callingId);
3043        }
3044    }
3045
3046    @Override
3047    public void setFocusedTask(int taskId) {
3048        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3049        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3050        final long callingId = Binder.clearCallingIdentity();
3051        try {
3052            synchronized (this) {
3053                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3054                if (task == null) {
3055                    return;
3056                }
3057                final ActivityRecord r = task.topRunningActivityLocked();
3058                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3059                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3060                }
3061            }
3062        } finally {
3063            Binder.restoreCallingIdentity(callingId);
3064        }
3065    }
3066
3067    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3068    @Override
3069    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3070        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3071        synchronized (this) {
3072            if (listener != null) {
3073                mTaskStackListeners.register(listener);
3074            }
3075        }
3076    }
3077
3078    @Override
3079    public void notifyActivityDrawn(IBinder token) {
3080        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3081        synchronized (this) {
3082            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3083            if (r != null) {
3084                r.task.stack.notifyActivityDrawnLocked(r);
3085            }
3086        }
3087    }
3088
3089    final void applyUpdateLockStateLocked(ActivityRecord r) {
3090        // Modifications to the UpdateLock state are done on our handler, outside
3091        // the activity manager's locks.  The new state is determined based on the
3092        // state *now* of the relevant activity record.  The object is passed to
3093        // the handler solely for logging detail, not to be consulted/modified.
3094        final boolean nextState = r != null && r.immersive;
3095        mHandler.sendMessage(
3096                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3097    }
3098
3099    final void applyUpdateVrModeLocked(ActivityRecord r) {
3100        mHandler.sendMessage(
3101                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3102    }
3103
3104    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3105        mHandler.sendMessage(
3106                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3107    }
3108
3109    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3110            ComponentName callingPackage, boolean immediate) {
3111        VrManagerInternal vrService =
3112                LocalServices.getService(VrManagerInternal.class);
3113        if (immediate) {
3114            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3115        } else {
3116            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3117        }
3118    }
3119
3120    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3121        Message msg = Message.obtain();
3122        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3123        msg.obj = r.task.askedCompatMode ? null : r;
3124        mUiHandler.sendMessage(msg);
3125    }
3126
3127    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3128        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3129                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3130            final Message msg = Message.obtain();
3131            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3132            msg.obj = r;
3133            mUiHandler.sendMessage(msg);
3134        }
3135    }
3136
3137    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3138            String what, Object obj, ProcessRecord srcApp) {
3139        app.lastActivityTime = now;
3140
3141        if (app.activities.size() > 0) {
3142            // Don't want to touch dependent processes that are hosting activities.
3143            return index;
3144        }
3145
3146        int lrui = mLruProcesses.lastIndexOf(app);
3147        if (lrui < 0) {
3148            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3149                    + what + " " + obj + " from " + srcApp);
3150            return index;
3151        }
3152
3153        if (lrui >= index) {
3154            // Don't want to cause this to move dependent processes *back* in the
3155            // list as if they were less frequently used.
3156            return index;
3157        }
3158
3159        if (lrui >= mLruProcessActivityStart) {
3160            // Don't want to touch dependent processes that are hosting activities.
3161            return index;
3162        }
3163
3164        mLruProcesses.remove(lrui);
3165        if (index > 0) {
3166            index--;
3167        }
3168        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3169                + " in LRU list: " + app);
3170        mLruProcesses.add(index, app);
3171        return index;
3172    }
3173
3174    static void killProcessGroup(int uid, int pid) {
3175        if (sKillHandler != null) {
3176            sKillHandler.sendMessage(
3177                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3178        } else {
3179            Slog.w(TAG, "Asked to kill process group before system bringup!");
3180            Process.killProcessGroup(uid, pid);
3181        }
3182    }
3183
3184    final void removeLruProcessLocked(ProcessRecord app) {
3185        int lrui = mLruProcesses.lastIndexOf(app);
3186        if (lrui >= 0) {
3187            if (!app.killed) {
3188                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3189                Process.killProcessQuiet(app.pid);
3190                killProcessGroup(app.uid, app.pid);
3191            }
3192            if (lrui <= mLruProcessActivityStart) {
3193                mLruProcessActivityStart--;
3194            }
3195            if (lrui <= mLruProcessServiceStart) {
3196                mLruProcessServiceStart--;
3197            }
3198            mLruProcesses.remove(lrui);
3199        }
3200    }
3201
3202    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3203            ProcessRecord client) {
3204        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3205                || app.treatLikeActivity;
3206        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3207        if (!activityChange && hasActivity) {
3208            // The process has activities, so we are only allowing activity-based adjustments
3209            // to move it.  It should be kept in the front of the list with other
3210            // processes that have activities, and we don't want those to change their
3211            // order except due to activity operations.
3212            return;
3213        }
3214
3215        mLruSeq++;
3216        final long now = SystemClock.uptimeMillis();
3217        app.lastActivityTime = now;
3218
3219        // First a quick reject: if the app is already at the position we will
3220        // put it, then there is nothing to do.
3221        if (hasActivity) {
3222            final int N = mLruProcesses.size();
3223            if (N > 0 && mLruProcesses.get(N-1) == app) {
3224                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3225                return;
3226            }
3227        } else {
3228            if (mLruProcessServiceStart > 0
3229                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3230                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3231                return;
3232            }
3233        }
3234
3235        int lrui = mLruProcesses.lastIndexOf(app);
3236
3237        if (app.persistent && lrui >= 0) {
3238            // We don't care about the position of persistent processes, as long as
3239            // they are in the list.
3240            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3241            return;
3242        }
3243
3244        /* In progress: compute new position first, so we can avoid doing work
3245           if the process is not actually going to move.  Not yet working.
3246        int addIndex;
3247        int nextIndex;
3248        boolean inActivity = false, inService = false;
3249        if (hasActivity) {
3250            // Process has activities, put it at the very tipsy-top.
3251            addIndex = mLruProcesses.size();
3252            nextIndex = mLruProcessServiceStart;
3253            inActivity = true;
3254        } else if (hasService) {
3255            // Process has services, put it at the top of the service list.
3256            addIndex = mLruProcessActivityStart;
3257            nextIndex = mLruProcessServiceStart;
3258            inActivity = true;
3259            inService = true;
3260        } else  {
3261            // Process not otherwise of interest, it goes to the top of the non-service area.
3262            addIndex = mLruProcessServiceStart;
3263            if (client != null) {
3264                int clientIndex = mLruProcesses.lastIndexOf(client);
3265                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3266                        + app);
3267                if (clientIndex >= 0 && addIndex > clientIndex) {
3268                    addIndex = clientIndex;
3269                }
3270            }
3271            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3272        }
3273
3274        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3275                + mLruProcessActivityStart + "): " + app);
3276        */
3277
3278        if (lrui >= 0) {
3279            if (lrui < mLruProcessActivityStart) {
3280                mLruProcessActivityStart--;
3281            }
3282            if (lrui < mLruProcessServiceStart) {
3283                mLruProcessServiceStart--;
3284            }
3285            /*
3286            if (addIndex > lrui) {
3287                addIndex--;
3288            }
3289            if (nextIndex > lrui) {
3290                nextIndex--;
3291            }
3292            */
3293            mLruProcesses.remove(lrui);
3294        }
3295
3296        /*
3297        mLruProcesses.add(addIndex, app);
3298        if (inActivity) {
3299            mLruProcessActivityStart++;
3300        }
3301        if (inService) {
3302            mLruProcessActivityStart++;
3303        }
3304        */
3305
3306        int nextIndex;
3307        if (hasActivity) {
3308            final int N = mLruProcesses.size();
3309            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3310                // Process doesn't have activities, but has clients with
3311                // activities...  move it up, but one below the top (the top
3312                // should always have a real activity).
3313                if (DEBUG_LRU) Slog.d(TAG_LRU,
3314                        "Adding to second-top of LRU activity list: " + app);
3315                mLruProcesses.add(N - 1, app);
3316                // To keep it from spamming the LRU list (by making a bunch of clients),
3317                // we will push down any other entries owned by the app.
3318                final int uid = app.info.uid;
3319                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3320                    ProcessRecord subProc = mLruProcesses.get(i);
3321                    if (subProc.info.uid == uid) {
3322                        // We want to push this one down the list.  If the process after
3323                        // it is for the same uid, however, don't do so, because we don't
3324                        // want them internally to be re-ordered.
3325                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3326                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3327                                    "Pushing uid " + uid + " swapping at " + i + ": "
3328                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3329                            ProcessRecord tmp = mLruProcesses.get(i);
3330                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3331                            mLruProcesses.set(i - 1, tmp);
3332                            i--;
3333                        }
3334                    } else {
3335                        // A gap, we can stop here.
3336                        break;
3337                    }
3338                }
3339            } else {
3340                // Process has activities, put it at the very tipsy-top.
3341                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3342                mLruProcesses.add(app);
3343            }
3344            nextIndex = mLruProcessServiceStart;
3345        } else if (hasService) {
3346            // Process has services, put it at the top of the service list.
3347            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3348            mLruProcesses.add(mLruProcessActivityStart, app);
3349            nextIndex = mLruProcessServiceStart;
3350            mLruProcessActivityStart++;
3351        } else  {
3352            // Process not otherwise of interest, it goes to the top of the non-service area.
3353            int index = mLruProcessServiceStart;
3354            if (client != null) {
3355                // If there is a client, don't allow the process to be moved up higher
3356                // in the list than that client.
3357                int clientIndex = mLruProcesses.lastIndexOf(client);
3358                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3359                        + " when updating " + app);
3360                if (clientIndex <= lrui) {
3361                    // Don't allow the client index restriction to push it down farther in the
3362                    // list than it already is.
3363                    clientIndex = lrui;
3364                }
3365                if (clientIndex >= 0 && index > clientIndex) {
3366                    index = clientIndex;
3367                }
3368            }
3369            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3370            mLruProcesses.add(index, app);
3371            nextIndex = index-1;
3372            mLruProcessActivityStart++;
3373            mLruProcessServiceStart++;
3374        }
3375
3376        // If the app is currently using a content provider or service,
3377        // bump those processes as well.
3378        for (int j=app.connections.size()-1; j>=0; j--) {
3379            ConnectionRecord cr = app.connections.valueAt(j);
3380            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3381                    && cr.binding.service.app != null
3382                    && cr.binding.service.app.lruSeq != mLruSeq
3383                    && !cr.binding.service.app.persistent) {
3384                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3385                        "service connection", cr, app);
3386            }
3387        }
3388        for (int j=app.conProviders.size()-1; j>=0; j--) {
3389            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3390            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3391                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3392                        "provider reference", cpr, app);
3393            }
3394        }
3395    }
3396
3397    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3398        if (uid == Process.SYSTEM_UID) {
3399            // The system gets to run in any process.  If there are multiple
3400            // processes with the same uid, just pick the first (this
3401            // should never happen).
3402            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3403            if (procs == null) return null;
3404            final int procCount = procs.size();
3405            for (int i = 0; i < procCount; i++) {
3406                final int procUid = procs.keyAt(i);
3407                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3408                    // Don't use an app process or different user process for system component.
3409                    continue;
3410                }
3411                return procs.valueAt(i);
3412            }
3413        }
3414        ProcessRecord proc = mProcessNames.get(processName, uid);
3415        if (false && proc != null && !keepIfLarge
3416                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3417                && proc.lastCachedPss >= 4000) {
3418            // Turn this condition on to cause killing to happen regularly, for testing.
3419            if (proc.baseProcessTracker != null) {
3420                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3421            }
3422            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3423        } else if (proc != null && !keepIfLarge
3424                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3425                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3426            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3427            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3428                if (proc.baseProcessTracker != null) {
3429                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3430                }
3431                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3432            }
3433        }
3434        return proc;
3435    }
3436
3437    void notifyPackageUse(String packageName, int reason) {
3438        IPackageManager pm = AppGlobals.getPackageManager();
3439        try {
3440            pm.notifyPackageUse(packageName, reason);
3441        } catch (RemoteException e) {
3442        }
3443    }
3444
3445    boolean isNextTransitionForward() {
3446        int transit = mWindowManager.getPendingAppTransition();
3447        return transit == TRANSIT_ACTIVITY_OPEN
3448                || transit == TRANSIT_TASK_OPEN
3449                || transit == TRANSIT_TASK_TO_FRONT;
3450    }
3451
3452    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3453            String processName, String abiOverride, int uid, Runnable crashHandler) {
3454        synchronized(this) {
3455            ApplicationInfo info = new ApplicationInfo();
3456            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3457            // For isolated processes, the former contains the parent's uid and the latter the
3458            // actual uid of the isolated process.
3459            // In the special case introduced by this method (which is, starting an isolated
3460            // process directly from the SystemServer without an actual parent app process) the
3461            // closest thing to a parent's uid is SYSTEM_UID.
3462            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3463            // the |isolated| logic in the ProcessRecord constructor.
3464            info.uid = Process.SYSTEM_UID;
3465            info.processName = processName;
3466            info.className = entryPoint;
3467            info.packageName = "android";
3468            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3469                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3470                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3471                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3472                    crashHandler);
3473            return proc != null ? proc.pid : 0;
3474        }
3475    }
3476
3477    final ProcessRecord startProcessLocked(String processName,
3478            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3479            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3480            boolean isolated, boolean keepIfLarge) {
3481        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3482                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3483                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3484                null /* crashHandler */);
3485    }
3486
3487    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3488            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3489            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3490            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3491        long startTime = SystemClock.elapsedRealtime();
3492        ProcessRecord app;
3493        if (!isolated) {
3494            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3495            checkTime(startTime, "startProcess: after getProcessRecord");
3496
3497            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3498                // If we are in the background, then check to see if this process
3499                // is bad.  If so, we will just silently fail.
3500                if (mAppErrors.isBadProcessLocked(info)) {
3501                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3502                            + "/" + info.processName);
3503                    return null;
3504                }
3505            } else {
3506                // When the user is explicitly starting a process, then clear its
3507                // crash count so that we won't make it bad until they see at
3508                // least one crash dialog again, and make the process good again
3509                // if it had been bad.
3510                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3511                        + "/" + info.processName);
3512                mAppErrors.resetProcessCrashTimeLocked(info);
3513                if (mAppErrors.isBadProcessLocked(info)) {
3514                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3515                            UserHandle.getUserId(info.uid), info.uid,
3516                            info.processName);
3517                    mAppErrors.clearBadProcessLocked(info);
3518                    if (app != null) {
3519                        app.bad = false;
3520                    }
3521                }
3522            }
3523        } else {
3524            // If this is an isolated process, it can't re-use an existing process.
3525            app = null;
3526        }
3527
3528        // app launch boost for big.little configurations
3529        // use cpusets to migrate freshly launched tasks to big cores
3530        nativeMigrateToBoost();
3531        mIsBoosted = true;
3532        mBoostStartTime = SystemClock.uptimeMillis();
3533        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3534        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3535
3536        // We don't have to do anything more if:
3537        // (1) There is an existing application record; and
3538        // (2) The caller doesn't think it is dead, OR there is no thread
3539        //     object attached to it so we know it couldn't have crashed; and
3540        // (3) There is a pid assigned to it, so it is either starting or
3541        //     already running.
3542        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3543                + " app=" + app + " knownToBeDead=" + knownToBeDead
3544                + " thread=" + (app != null ? app.thread : null)
3545                + " pid=" + (app != null ? app.pid : -1));
3546        if (app != null && app.pid > 0) {
3547            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3548                // We already have the app running, or are waiting for it to
3549                // come up (we have a pid but not yet its thread), so keep it.
3550                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3551                // If this is a new package in the process, add the package to the list
3552                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3553                checkTime(startTime, "startProcess: done, added package to proc");
3554                return app;
3555            }
3556
3557            // An application record is attached to a previous process,
3558            // clean it up now.
3559            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3560            checkTime(startTime, "startProcess: bad proc running, killing");
3561            killProcessGroup(app.uid, app.pid);
3562            handleAppDiedLocked(app, true, true);
3563            checkTime(startTime, "startProcess: done killing old proc");
3564        }
3565
3566        String hostingNameStr = hostingName != null
3567                ? hostingName.flattenToShortString() : null;
3568
3569        if (app == null) {
3570            checkTime(startTime, "startProcess: creating new process record");
3571            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3572            if (app == null) {
3573                Slog.w(TAG, "Failed making new process record for "
3574                        + processName + "/" + info.uid + " isolated=" + isolated);
3575                return null;
3576            }
3577            app.crashHandler = crashHandler;
3578            checkTime(startTime, "startProcess: done creating new process record");
3579        } else {
3580            // If this is a new package in the process, add the package to the list
3581            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3582            checkTime(startTime, "startProcess: added package to existing proc");
3583        }
3584
3585        // If the system is not ready yet, then hold off on starting this
3586        // process until it is.
3587        if (!mProcessesReady
3588                && !isAllowedWhileBooting(info)
3589                && !allowWhileBooting) {
3590            if (!mProcessesOnHold.contains(app)) {
3591                mProcessesOnHold.add(app);
3592            }
3593            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3594                    "System not ready, putting on hold: " + app);
3595            checkTime(startTime, "startProcess: returning with proc on hold");
3596            return app;
3597        }
3598
3599        checkTime(startTime, "startProcess: stepping in to startProcess");
3600        startProcessLocked(
3601                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3602        checkTime(startTime, "startProcess: done starting proc!");
3603        return (app.pid != 0) ? app : null;
3604    }
3605
3606    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3607        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3608    }
3609
3610    private final void startProcessLocked(ProcessRecord app,
3611            String hostingType, String hostingNameStr) {
3612        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3613                null /* entryPoint */, null /* entryPointArgs */);
3614    }
3615
3616    private final void startProcessLocked(ProcessRecord app, String hostingType,
3617            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3618        long startTime = SystemClock.elapsedRealtime();
3619        if (app.pid > 0 && app.pid != MY_PID) {
3620            checkTime(startTime, "startProcess: removing from pids map");
3621            synchronized (mPidsSelfLocked) {
3622                mPidsSelfLocked.remove(app.pid);
3623                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3624            }
3625            checkTime(startTime, "startProcess: done removing from pids map");
3626            app.setPid(0);
3627        }
3628
3629        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3630                "startProcessLocked removing on hold: " + app);
3631        mProcessesOnHold.remove(app);
3632
3633        checkTime(startTime, "startProcess: starting to update cpu stats");
3634        updateCpuStats();
3635        checkTime(startTime, "startProcess: done updating cpu stats");
3636
3637        try {
3638            try {
3639                final int userId = UserHandle.getUserId(app.uid);
3640                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3641            } catch (RemoteException e) {
3642                throw e.rethrowAsRuntimeException();
3643            }
3644
3645            int uid = app.uid;
3646            int[] gids = null;
3647            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3648            if (!app.isolated) {
3649                int[] permGids = null;
3650                try {
3651                    checkTime(startTime, "startProcess: getting gids from package manager");
3652                    final IPackageManager pm = AppGlobals.getPackageManager();
3653                    permGids = pm.getPackageGids(app.info.packageName,
3654                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3655                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3656                            MountServiceInternal.class);
3657                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3658                            app.info.packageName);
3659                } catch (RemoteException e) {
3660                    throw e.rethrowAsRuntimeException();
3661                }
3662
3663                /*
3664                 * Add shared application and profile GIDs so applications can share some
3665                 * resources like shared libraries and access user-wide resources
3666                 */
3667                if (ArrayUtils.isEmpty(permGids)) {
3668                    gids = new int[2];
3669                } else {
3670                    gids = new int[permGids.length + 2];
3671                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3672                }
3673                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3674                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3675            }
3676            checkTime(startTime, "startProcess: building args");
3677            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3678                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3679                        && mTopComponent != null
3680                        && app.processName.equals(mTopComponent.getPackageName())) {
3681                    uid = 0;
3682                }
3683                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3684                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3685                    uid = 0;
3686                }
3687            }
3688            int debugFlags = 0;
3689            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3690                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3691                // Also turn on CheckJNI for debuggable apps. It's quite
3692                // awkward to turn on otherwise.
3693                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3694            }
3695            // Run the app in safe mode if its manifest requests so or the
3696            // system is booted in safe mode.
3697            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3698                mSafeMode == true) {
3699                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3700            }
3701            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3702                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3703            }
3704            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3705            if ("true".equals(genDebugInfoProperty)) {
3706                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3707            }
3708            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3709                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3710            }
3711            if ("1".equals(SystemProperties.get("debug.assert"))) {
3712                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3713            }
3714            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3715                // Enable all debug flags required by the native debugger.
3716                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3717                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3718                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3719                mNativeDebuggingApp = null;
3720            }
3721
3722            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3723            if (requiredAbi == null) {
3724                requiredAbi = Build.SUPPORTED_ABIS[0];
3725            }
3726
3727            String instructionSet = null;
3728            if (app.info.primaryCpuAbi != null) {
3729                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3730            }
3731
3732            app.gids = gids;
3733            app.requiredAbi = requiredAbi;
3734            app.instructionSet = instructionSet;
3735
3736            // Start the process.  It will either succeed and return a result containing
3737            // the PID of the new process, or else throw a RuntimeException.
3738            boolean isActivityProcess = (entryPoint == null);
3739            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3740            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3741                    app.processName);
3742            checkTime(startTime, "startProcess: asking zygote to start proc");
3743            Process.ProcessStartResult startResult = Process.start(entryPoint,
3744                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3745                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3746                    app.info.dataDir, entryPointArgs);
3747            checkTime(startTime, "startProcess: returned from zygote!");
3748            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3749
3750            if (app.isolated) {
3751                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3752            }
3753            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3754            checkTime(startTime, "startProcess: done updating battery stats");
3755
3756            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3757                    UserHandle.getUserId(uid), startResult.pid, uid,
3758                    app.processName, hostingType,
3759                    hostingNameStr != null ? hostingNameStr : "");
3760
3761            try {
3762                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3763                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3764            } catch (RemoteException ex) {
3765                // Ignore
3766            }
3767
3768            if (app.persistent) {
3769                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3770            }
3771
3772            checkTime(startTime, "startProcess: building log message");
3773            StringBuilder buf = mStringBuilder;
3774            buf.setLength(0);
3775            buf.append("Start proc ");
3776            buf.append(startResult.pid);
3777            buf.append(':');
3778            buf.append(app.processName);
3779            buf.append('/');
3780            UserHandle.formatUid(buf, uid);
3781            if (!isActivityProcess) {
3782                buf.append(" [");
3783                buf.append(entryPoint);
3784                buf.append("]");
3785            }
3786            buf.append(" for ");
3787            buf.append(hostingType);
3788            if (hostingNameStr != null) {
3789                buf.append(" ");
3790                buf.append(hostingNameStr);
3791            }
3792            Slog.i(TAG, buf.toString());
3793            app.setPid(startResult.pid);
3794            app.usingWrapper = startResult.usingWrapper;
3795            app.removed = false;
3796            app.killed = false;
3797            app.killedByAm = false;
3798            checkTime(startTime, "startProcess: starting to update pids map");
3799            synchronized (mPidsSelfLocked) {
3800                this.mPidsSelfLocked.put(startResult.pid, app);
3801                if (isActivityProcess) {
3802                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3803                    msg.obj = app;
3804                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3805                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3806                }
3807            }
3808            checkTime(startTime, "startProcess: done updating pids map");
3809        } catch (RuntimeException e) {
3810            Slog.e(TAG, "Failure starting process " + app.processName, e);
3811
3812            // Something went very wrong while trying to start this process; one
3813            // common case is when the package is frozen due to an active
3814            // upgrade. To recover, clean up any active bookkeeping related to
3815            // starting this process. (We already invoked this method once when
3816            // the package was initially frozen through KILL_APPLICATION_MSG, so
3817            // it doesn't hurt to use it again.)
3818            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3819                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3820        }
3821    }
3822
3823    void updateUsageStats(ActivityRecord component, boolean resumed) {
3824        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3825                "updateUsageStats: comp=" + component + "res=" + resumed);
3826        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3827        if (resumed) {
3828            if (mUsageStatsService != null) {
3829                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3830                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3831            }
3832            synchronized (stats) {
3833                stats.noteActivityResumedLocked(component.app.uid);
3834            }
3835        } else {
3836            if (mUsageStatsService != null) {
3837                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3838                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3839            }
3840            synchronized (stats) {
3841                stats.noteActivityPausedLocked(component.app.uid);
3842            }
3843        }
3844    }
3845
3846    Intent getHomeIntent() {
3847        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3848        intent.setComponent(mTopComponent);
3849        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3850        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3851            intent.addCategory(Intent.CATEGORY_HOME);
3852        }
3853        return intent;
3854    }
3855
3856    boolean startHomeActivityLocked(int userId, String reason) {
3857        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3858                && mTopAction == null) {
3859            // We are running in factory test mode, but unable to find
3860            // the factory test app, so just sit around displaying the
3861            // error message and don't try to start anything.
3862            return false;
3863        }
3864        Intent intent = getHomeIntent();
3865        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3866        if (aInfo != null) {
3867            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3868            // Don't do this if the home app is currently being
3869            // instrumented.
3870            aInfo = new ActivityInfo(aInfo);
3871            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3872            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3873                    aInfo.applicationInfo.uid, true);
3874            if (app == null || app.instrumentationClass == null) {
3875                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3876                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3877            }
3878        } else {
3879            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3880        }
3881
3882        return true;
3883    }
3884
3885    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3886        ActivityInfo ai = null;
3887        ComponentName comp = intent.getComponent();
3888        try {
3889            if (comp != null) {
3890                // Factory test.
3891                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3892            } else {
3893                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3894                        intent,
3895                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3896                        flags, userId);
3897
3898                if (info != null) {
3899                    ai = info.activityInfo;
3900                }
3901            }
3902        } catch (RemoteException e) {
3903            // ignore
3904        }
3905
3906        return ai;
3907    }
3908
3909    /**
3910     * Starts the "new version setup screen" if appropriate.
3911     */
3912    void startSetupActivityLocked() {
3913        // Only do this once per boot.
3914        if (mCheckedForSetup) {
3915            return;
3916        }
3917
3918        // We will show this screen if the current one is a different
3919        // version than the last one shown, and we are not running in
3920        // low-level factory test mode.
3921        final ContentResolver resolver = mContext.getContentResolver();
3922        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3923                Settings.Global.getInt(resolver,
3924                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3925            mCheckedForSetup = true;
3926
3927            // See if we should be showing the platform update setup UI.
3928            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3929            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3930                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3931            if (!ris.isEmpty()) {
3932                final ResolveInfo ri = ris.get(0);
3933                String vers = ri.activityInfo.metaData != null
3934                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3935                        : null;
3936                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3937                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3938                            Intent.METADATA_SETUP_VERSION);
3939                }
3940                String lastVers = Settings.Secure.getString(
3941                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3942                if (vers != null && !vers.equals(lastVers)) {
3943                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3944                    intent.setComponent(new ComponentName(
3945                            ri.activityInfo.packageName, ri.activityInfo.name));
3946                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3947                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3948                            null, 0, 0, 0, null, false, false, null, null, null);
3949                }
3950            }
3951        }
3952    }
3953
3954    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3955        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3956    }
3957
3958    void enforceNotIsolatedCaller(String caller) {
3959        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3960            throw new SecurityException("Isolated process not allowed to call " + caller);
3961        }
3962    }
3963
3964    void enforceShellRestriction(String restriction, int userHandle) {
3965        if (Binder.getCallingUid() == Process.SHELL_UID) {
3966            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3967                throw new SecurityException("Shell does not have permission to access user "
3968                        + userHandle);
3969            }
3970        }
3971    }
3972
3973    @Override
3974    public int getFrontActivityScreenCompatMode() {
3975        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3976        synchronized (this) {
3977            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3978        }
3979    }
3980
3981    @Override
3982    public void setFrontActivityScreenCompatMode(int mode) {
3983        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3984                "setFrontActivityScreenCompatMode");
3985        synchronized (this) {
3986            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3987        }
3988    }
3989
3990    @Override
3991    public int getPackageScreenCompatMode(String packageName) {
3992        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3993        synchronized (this) {
3994            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3995        }
3996    }
3997
3998    @Override
3999    public void setPackageScreenCompatMode(String packageName, int mode) {
4000        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4001                "setPackageScreenCompatMode");
4002        synchronized (this) {
4003            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4004        }
4005    }
4006
4007    @Override
4008    public boolean getPackageAskScreenCompat(String packageName) {
4009        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4010        synchronized (this) {
4011            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4012        }
4013    }
4014
4015    @Override
4016    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4017        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4018                "setPackageAskScreenCompat");
4019        synchronized (this) {
4020            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4021        }
4022    }
4023
4024    private boolean hasUsageStatsPermission(String callingPackage) {
4025        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4026                Binder.getCallingUid(), callingPackage);
4027        if (mode == AppOpsManager.MODE_DEFAULT) {
4028            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4029                    == PackageManager.PERMISSION_GRANTED;
4030        }
4031        return mode == AppOpsManager.MODE_ALLOWED;
4032    }
4033
4034    @Override
4035    public int getPackageProcessState(String packageName, String callingPackage) {
4036        if (!hasUsageStatsPermission(callingPackage)) {
4037            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4038                    "getPackageProcessState");
4039        }
4040
4041        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4042        synchronized (this) {
4043            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4044                final ProcessRecord proc = mLruProcesses.get(i);
4045                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4046                        || procState > proc.setProcState) {
4047                    boolean found = false;
4048                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4049                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4050                            procState = proc.setProcState;
4051                            found = true;
4052                        }
4053                    }
4054                    if (proc.pkgDeps != null && !found) {
4055                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4056                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4057                                procState = proc.setProcState;
4058                                break;
4059                            }
4060                        }
4061                    }
4062                }
4063            }
4064        }
4065        return procState;
4066    }
4067
4068    @Override
4069    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4070        synchronized (this) {
4071            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4072            if (app == null) {
4073                return false;
4074            }
4075            if (app.trimMemoryLevel < level && app.thread != null &&
4076                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4077                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4078                try {
4079                    app.thread.scheduleTrimMemory(level);
4080                    app.trimMemoryLevel = level;
4081                    return true;
4082                } catch (RemoteException e) {
4083                    // Fallthrough to failure case.
4084                }
4085            }
4086        }
4087        return false;
4088    }
4089
4090    private void dispatchProcessesChanged() {
4091        int N;
4092        synchronized (this) {
4093            N = mPendingProcessChanges.size();
4094            if (mActiveProcessChanges.length < N) {
4095                mActiveProcessChanges = new ProcessChangeItem[N];
4096            }
4097            mPendingProcessChanges.toArray(mActiveProcessChanges);
4098            mPendingProcessChanges.clear();
4099            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4100                    "*** Delivering " + N + " process changes");
4101        }
4102
4103        int i = mProcessObservers.beginBroadcast();
4104        while (i > 0) {
4105            i--;
4106            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4107            if (observer != null) {
4108                try {
4109                    for (int j=0; j<N; j++) {
4110                        ProcessChangeItem item = mActiveProcessChanges[j];
4111                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4112                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4113                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4114                                    + item.uid + ": " + item.foregroundActivities);
4115                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4116                                    item.foregroundActivities);
4117                        }
4118                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4119                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4120                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4121                                    + ": " + item.processState);
4122                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4123                        }
4124                    }
4125                } catch (RemoteException e) {
4126                }
4127            }
4128        }
4129        mProcessObservers.finishBroadcast();
4130
4131        synchronized (this) {
4132            for (int j=0; j<N; j++) {
4133                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4134            }
4135        }
4136    }
4137
4138    private void dispatchProcessDied(int pid, int uid) {
4139        int i = mProcessObservers.beginBroadcast();
4140        while (i > 0) {
4141            i--;
4142            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4143            if (observer != null) {
4144                try {
4145                    observer.onProcessDied(pid, uid);
4146                } catch (RemoteException e) {
4147                }
4148            }
4149        }
4150        mProcessObservers.finishBroadcast();
4151    }
4152
4153    private void dispatchUidsChanged() {
4154        int N;
4155        synchronized (this) {
4156            N = mPendingUidChanges.size();
4157            if (mActiveUidChanges.length < N) {
4158                mActiveUidChanges = new UidRecord.ChangeItem[N];
4159            }
4160            for (int i=0; i<N; i++) {
4161                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4162                mActiveUidChanges[i] = change;
4163                if (change.uidRecord != null) {
4164                    change.uidRecord.pendingChange = null;
4165                    change.uidRecord = null;
4166                }
4167            }
4168            mPendingUidChanges.clear();
4169            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4170                    "*** Delivering " + N + " uid changes");
4171        }
4172
4173        if (mLocalPowerManager != null) {
4174            for (int j=0; j<N; j++) {
4175                UidRecord.ChangeItem item = mActiveUidChanges[j];
4176                if (item.change == UidRecord.CHANGE_GONE
4177                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4178                    mLocalPowerManager.uidGone(item.uid);
4179                } else {
4180                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4181                }
4182            }
4183        }
4184
4185        int i = mUidObservers.beginBroadcast();
4186        while (i > 0) {
4187            i--;
4188            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4189            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4190            if (observer != null) {
4191                try {
4192                    for (int j=0; j<N; j++) {
4193                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4194                        final int change = item.change;
4195                        UidRecord validateUid = null;
4196                        if (VALIDATE_UID_STATES && i == 0) {
4197                            validateUid = mValidateUids.get(item.uid);
4198                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4199                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4200                                validateUid = new UidRecord(item.uid);
4201                                mValidateUids.put(item.uid, validateUid);
4202                            }
4203                        }
4204                        if (change == UidRecord.CHANGE_IDLE
4205                                || change == UidRecord.CHANGE_GONE_IDLE) {
4206                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4207                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4208                                        "UID idle uid=" + item.uid);
4209                                observer.onUidIdle(item.uid);
4210                            }
4211                            if (VALIDATE_UID_STATES && i == 0) {
4212                                if (validateUid != null) {
4213                                    validateUid.idle = true;
4214                                }
4215                            }
4216                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4217                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4218                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4219                                        "UID active uid=" + item.uid);
4220                                observer.onUidActive(item.uid);
4221                            }
4222                            if (VALIDATE_UID_STATES && i == 0) {
4223                                validateUid.idle = false;
4224                            }
4225                        }
4226                        if (change == UidRecord.CHANGE_GONE
4227                                || change == UidRecord.CHANGE_GONE_IDLE) {
4228                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4229                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4230                                        "UID gone uid=" + item.uid);
4231                                observer.onUidGone(item.uid);
4232                            }
4233                            if (VALIDATE_UID_STATES && i == 0) {
4234                                if (validateUid != null) {
4235                                    mValidateUids.remove(item.uid);
4236                                }
4237                            }
4238                        } else {
4239                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4240                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4241                                        "UID CHANGED uid=" + item.uid
4242                                                + ": " + item.processState);
4243                                observer.onUidStateChanged(item.uid, item.processState);
4244                            }
4245                            if (VALIDATE_UID_STATES && i == 0) {
4246                                validateUid.curProcState = validateUid.setProcState
4247                                        = item.processState;
4248                            }
4249                        }
4250                    }
4251                } catch (RemoteException e) {
4252                }
4253            }
4254        }
4255        mUidObservers.finishBroadcast();
4256
4257        synchronized (this) {
4258            for (int j=0; j<N; j++) {
4259                mAvailUidChanges.add(mActiveUidChanges[j]);
4260            }
4261        }
4262    }
4263
4264    @Override
4265    public final int startActivity(IApplicationThread caller, String callingPackage,
4266            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4267            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4268        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4269                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4270                UserHandle.getCallingUserId());
4271    }
4272
4273    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4274        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4275        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4276                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4277                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4278
4279        // TODO: Switch to user app stacks here.
4280        String mimeType = intent.getType();
4281        final Uri data = intent.getData();
4282        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4283            mimeType = getProviderMimeType(data, userId);
4284        }
4285        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4286
4287        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4288        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4289                null, 0, 0, null, null, null, null, false, userId, container, null);
4290    }
4291
4292    @Override
4293    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4294            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4295            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4296        enforceNotIsolatedCaller("startActivity");
4297        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4298                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4299        // TODO: Switch to user app stacks here.
4300        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4301                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4302                profilerInfo, null, null, bOptions, false, userId, null, null);
4303    }
4304
4305    @Override
4306    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4307            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4308            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4309            int userId) {
4310
4311        // This is very dangerous -- it allows you to perform a start activity (including
4312        // permission grants) as any app that may launch one of your own activities.  So
4313        // we will only allow this to be done from activities that are part of the core framework,
4314        // and then only when they are running as the system.
4315        final ActivityRecord sourceRecord;
4316        final int targetUid;
4317        final String targetPackage;
4318        synchronized (this) {
4319            if (resultTo == null) {
4320                throw new SecurityException("Must be called from an activity");
4321            }
4322            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4323            if (sourceRecord == null) {
4324                throw new SecurityException("Called with bad activity token: " + resultTo);
4325            }
4326            if (!sourceRecord.info.packageName.equals("android")) {
4327                throw new SecurityException(
4328                        "Must be called from an activity that is declared in the android package");
4329            }
4330            if (sourceRecord.app == null) {
4331                throw new SecurityException("Called without a process attached to activity");
4332            }
4333            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4334                // This is still okay, as long as this activity is running under the
4335                // uid of the original calling activity.
4336                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4337                    throw new SecurityException(
4338                            "Calling activity in uid " + sourceRecord.app.uid
4339                                    + " must be system uid or original calling uid "
4340                                    + sourceRecord.launchedFromUid);
4341                }
4342            }
4343            if (ignoreTargetSecurity) {
4344                if (intent.getComponent() == null) {
4345                    throw new SecurityException(
4346                            "Component must be specified with ignoreTargetSecurity");
4347                }
4348                if (intent.getSelector() != null) {
4349                    throw new SecurityException(
4350                            "Selector not allowed with ignoreTargetSecurity");
4351                }
4352            }
4353            targetUid = sourceRecord.launchedFromUid;
4354            targetPackage = sourceRecord.launchedFromPackage;
4355        }
4356
4357        if (userId == UserHandle.USER_NULL) {
4358            userId = UserHandle.getUserId(sourceRecord.app.uid);
4359        }
4360
4361        // TODO: Switch to user app stacks here.
4362        try {
4363            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4364                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4365                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4366            return ret;
4367        } catch (SecurityException e) {
4368            // XXX need to figure out how to propagate to original app.
4369            // A SecurityException here is generally actually a fault of the original
4370            // calling activity (such as a fairly granting permissions), so propagate it
4371            // back to them.
4372            /*
4373            StringBuilder msg = new StringBuilder();
4374            msg.append("While launching");
4375            msg.append(intent.toString());
4376            msg.append(": ");
4377            msg.append(e.getMessage());
4378            */
4379            throw e;
4380        }
4381    }
4382
4383    @Override
4384    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4385            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4386            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4387        enforceNotIsolatedCaller("startActivityAndWait");
4388        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4389                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4390        WaitResult res = new WaitResult();
4391        // TODO: Switch to user app stacks here.
4392        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4393                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4394                bOptions, false, userId, null, null);
4395        return res;
4396    }
4397
4398    @Override
4399    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4400            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4401            int startFlags, Configuration config, Bundle bOptions, int userId) {
4402        enforceNotIsolatedCaller("startActivityWithConfig");
4403        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4404                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4405        // TODO: Switch to user app stacks here.
4406        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4407                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4408                null, null, config, bOptions, false, userId, null, null);
4409        return ret;
4410    }
4411
4412    @Override
4413    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4414            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4415            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4416            throws TransactionTooLargeException {
4417        enforceNotIsolatedCaller("startActivityIntentSender");
4418        // Refuse possible leaked file descriptors
4419        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4420            throw new IllegalArgumentException("File descriptors passed in Intent");
4421        }
4422
4423        IIntentSender sender = intent.getTarget();
4424        if (!(sender instanceof PendingIntentRecord)) {
4425            throw new IllegalArgumentException("Bad PendingIntent object");
4426        }
4427
4428        PendingIntentRecord pir = (PendingIntentRecord)sender;
4429
4430        synchronized (this) {
4431            // If this is coming from the currently resumed activity, it is
4432            // effectively saying that app switches are allowed at this point.
4433            final ActivityStack stack = getFocusedStack();
4434            if (stack.mResumedActivity != null &&
4435                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4436                mAppSwitchesAllowedTime = 0;
4437            }
4438        }
4439        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4440                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4441        return ret;
4442    }
4443
4444    @Override
4445    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4446            Intent intent, String resolvedType, IVoiceInteractionSession session,
4447            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4448            Bundle bOptions, int userId) {
4449        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4450                != PackageManager.PERMISSION_GRANTED) {
4451            String msg = "Permission Denial: startVoiceActivity() from pid="
4452                    + Binder.getCallingPid()
4453                    + ", uid=" + Binder.getCallingUid()
4454                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4455            Slog.w(TAG, msg);
4456            throw new SecurityException(msg);
4457        }
4458        if (session == null || interactor == null) {
4459            throw new NullPointerException("null session or interactor");
4460        }
4461        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4462                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4463        // TODO: Switch to user app stacks here.
4464        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4465                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4466                null, bOptions, false, userId, null, null);
4467    }
4468
4469    @Override
4470    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4471            throws RemoteException {
4472        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4473        synchronized (this) {
4474            ActivityRecord activity = getFocusedStack().topActivity();
4475            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4476                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4477            }
4478            if (mRunningVoice != null || activity.task.voiceSession != null
4479                    || activity.voiceSession != null) {
4480                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4481                return;
4482            }
4483            if (activity.pendingVoiceInteractionStart) {
4484                Slog.w(TAG, "Pending start of voice interaction already.");
4485                return;
4486            }
4487            activity.pendingVoiceInteractionStart = true;
4488        }
4489        LocalServices.getService(VoiceInteractionManagerInternal.class)
4490                .startLocalVoiceInteraction(callingActivity, options);
4491    }
4492
4493    @Override
4494    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4495        LocalServices.getService(VoiceInteractionManagerInternal.class)
4496                .stopLocalVoiceInteraction(callingActivity);
4497    }
4498
4499    @Override
4500    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4501        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4502                .supportsLocalVoiceInteraction();
4503    }
4504
4505    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4506            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4507        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4508        if (activityToCallback == null) return;
4509        activityToCallback.setVoiceSessionLocked(voiceSession);
4510
4511        // Inform the activity
4512        try {
4513            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4514                    voiceInteractor);
4515            long token = Binder.clearCallingIdentity();
4516            try {
4517                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4518            } finally {
4519                Binder.restoreCallingIdentity(token);
4520            }
4521            // TODO: VI Should we cache the activity so that it's easier to find later
4522            // rather than scan through all the stacks and activities?
4523        } catch (RemoteException re) {
4524            activityToCallback.clearVoiceSessionLocked();
4525            // TODO: VI Should this terminate the voice session?
4526        }
4527    }
4528
4529    @Override
4530    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4531        synchronized (this) {
4532            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4533                if (keepAwake) {
4534                    mVoiceWakeLock.acquire();
4535                } else {
4536                    mVoiceWakeLock.release();
4537                }
4538            }
4539        }
4540    }
4541
4542    @Override
4543    public boolean startNextMatchingActivity(IBinder callingActivity,
4544            Intent intent, Bundle bOptions) {
4545        // Refuse possible leaked file descriptors
4546        if (intent != null && intent.hasFileDescriptors() == true) {
4547            throw new IllegalArgumentException("File descriptors passed in Intent");
4548        }
4549        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4550
4551        synchronized (this) {
4552            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4553            if (r == null) {
4554                ActivityOptions.abort(options);
4555                return false;
4556            }
4557            if (r.app == null || r.app.thread == null) {
4558                // The caller is not running...  d'oh!
4559                ActivityOptions.abort(options);
4560                return false;
4561            }
4562            intent = new Intent(intent);
4563            // The caller is not allowed to change the data.
4564            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4565            // And we are resetting to find the next component...
4566            intent.setComponent(null);
4567
4568            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4569
4570            ActivityInfo aInfo = null;
4571            try {
4572                List<ResolveInfo> resolves =
4573                    AppGlobals.getPackageManager().queryIntentActivities(
4574                            intent, r.resolvedType,
4575                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4576                            UserHandle.getCallingUserId()).getList();
4577
4578                // Look for the original activity in the list...
4579                final int N = resolves != null ? resolves.size() : 0;
4580                for (int i=0; i<N; i++) {
4581                    ResolveInfo rInfo = resolves.get(i);
4582                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4583                            && rInfo.activityInfo.name.equals(r.info.name)) {
4584                        // We found the current one...  the next matching is
4585                        // after it.
4586                        i++;
4587                        if (i<N) {
4588                            aInfo = resolves.get(i).activityInfo;
4589                        }
4590                        if (debug) {
4591                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4592                                    + "/" + r.info.name);
4593                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4594                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4595                        }
4596                        break;
4597                    }
4598                }
4599            } catch (RemoteException e) {
4600            }
4601
4602            if (aInfo == null) {
4603                // Nobody who is next!
4604                ActivityOptions.abort(options);
4605                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4606                return false;
4607            }
4608
4609            intent.setComponent(new ComponentName(
4610                    aInfo.applicationInfo.packageName, aInfo.name));
4611            intent.setFlags(intent.getFlags()&~(
4612                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4613                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4614                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4615                    Intent.FLAG_ACTIVITY_NEW_TASK));
4616
4617            // Okay now we need to start the new activity, replacing the
4618            // currently running activity.  This is a little tricky because
4619            // we want to start the new one as if the current one is finished,
4620            // but not finish the current one first so that there is no flicker.
4621            // And thus...
4622            final boolean wasFinishing = r.finishing;
4623            r.finishing = true;
4624
4625            // Propagate reply information over to the new activity.
4626            final ActivityRecord resultTo = r.resultTo;
4627            final String resultWho = r.resultWho;
4628            final int requestCode = r.requestCode;
4629            r.resultTo = null;
4630            if (resultTo != null) {
4631                resultTo.removeResultsLocked(r, resultWho, requestCode);
4632            }
4633
4634            final long origId = Binder.clearCallingIdentity();
4635            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4636                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4637                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4638                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4639                    false, false, null, null, null);
4640            Binder.restoreCallingIdentity(origId);
4641
4642            r.finishing = wasFinishing;
4643            if (res != ActivityManager.START_SUCCESS) {
4644                return false;
4645            }
4646            return true;
4647        }
4648    }
4649
4650    @Override
4651    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4652        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4653            String msg = "Permission Denial: startActivityFromRecents called without " +
4654                    START_TASKS_FROM_RECENTS;
4655            Slog.w(TAG, msg);
4656            throw new SecurityException(msg);
4657        }
4658        final long origId = Binder.clearCallingIdentity();
4659        try {
4660            synchronized (this) {
4661                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4662            }
4663        } finally {
4664            Binder.restoreCallingIdentity(origId);
4665        }
4666    }
4667
4668    final int startActivityInPackage(int uid, String callingPackage,
4669            Intent intent, String resolvedType, IBinder resultTo,
4670            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4671            IActivityContainer container, TaskRecord inTask) {
4672
4673        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4674                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4675
4676        // TODO: Switch to user app stacks here.
4677        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4678                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4679                null, null, null, bOptions, false, userId, container, inTask);
4680        return ret;
4681    }
4682
4683    @Override
4684    public final int startActivities(IApplicationThread caller, String callingPackage,
4685            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4686            int userId) {
4687        enforceNotIsolatedCaller("startActivities");
4688        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4689                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4690        // TODO: Switch to user app stacks here.
4691        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4692                resolvedTypes, resultTo, bOptions, userId);
4693        return ret;
4694    }
4695
4696    final int startActivitiesInPackage(int uid, String callingPackage,
4697            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4698            Bundle bOptions, int userId) {
4699
4700        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4701                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4702        // TODO: Switch to user app stacks here.
4703        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4704                resultTo, bOptions, userId);
4705        return ret;
4706    }
4707
4708    @Override
4709    public void reportActivityFullyDrawn(IBinder token) {
4710        synchronized (this) {
4711            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4712            if (r == null) {
4713                return;
4714            }
4715            r.reportFullyDrawnLocked();
4716        }
4717    }
4718
4719    @Override
4720    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4721        synchronized (this) {
4722            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4723            if (r == null) {
4724                return;
4725            }
4726            TaskRecord task = r.task;
4727            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4728                // Fixed screen orientation isn't supported when activities aren't in full screen
4729                // mode.
4730                return;
4731            }
4732            final long origId = Binder.clearCallingIdentity();
4733            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4734            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4735                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4736            if (config != null) {
4737                r.frozenBeforeDestroy = true;
4738                if (!updateConfigurationLocked(config, r, false)) {
4739                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4740                }
4741            }
4742            Binder.restoreCallingIdentity(origId);
4743        }
4744    }
4745
4746    @Override
4747    public int getRequestedOrientation(IBinder token) {
4748        synchronized (this) {
4749            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4750            if (r == null) {
4751                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4752            }
4753            return mWindowManager.getAppOrientation(r.appToken);
4754        }
4755    }
4756
4757    /**
4758     * This is the internal entry point for handling Activity.finish().
4759     *
4760     * @param token The Binder token referencing the Activity we want to finish.
4761     * @param resultCode Result code, if any, from this Activity.
4762     * @param resultData Result data (Intent), if any, from this Activity.
4763     * @param finishTask Whether to finish the task associated with this Activity.
4764     *
4765     * @return Returns true if the activity successfully finished, or false if it is still running.
4766     */
4767    @Override
4768    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4769            int finishTask) {
4770        // Refuse possible leaked file descriptors
4771        if (resultData != null && resultData.hasFileDescriptors() == true) {
4772            throw new IllegalArgumentException("File descriptors passed in Intent");
4773        }
4774
4775        synchronized(this) {
4776            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4777            if (r == null) {
4778                return true;
4779            }
4780            // Keep track of the root activity of the task before we finish it
4781            TaskRecord tr = r.task;
4782            ActivityRecord rootR = tr.getRootActivity();
4783            if (rootR == null) {
4784                Slog.w(TAG, "Finishing task with all activities already finished");
4785            }
4786            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4787            // finish.
4788            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4789                    mStackSupervisor.isLastLockedTask(tr)) {
4790                Slog.i(TAG, "Not finishing task in lock task mode");
4791                mStackSupervisor.showLockTaskToast();
4792                return false;
4793            }
4794            if (mController != null) {
4795                // Find the first activity that is not finishing.
4796                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4797                if (next != null) {
4798                    // ask watcher if this is allowed
4799                    boolean resumeOK = true;
4800                    try {
4801                        resumeOK = mController.activityResuming(next.packageName);
4802                    } catch (RemoteException e) {
4803                        mController = null;
4804                        Watchdog.getInstance().setActivityController(null);
4805                    }
4806
4807                    if (!resumeOK) {
4808                        Slog.i(TAG, "Not finishing activity because controller resumed");
4809                        return false;
4810                    }
4811                }
4812            }
4813            final long origId = Binder.clearCallingIdentity();
4814            try {
4815                boolean res;
4816                final boolean finishWithRootActivity =
4817                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4818                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4819                        || (finishWithRootActivity && r == rootR)) {
4820                    // If requested, remove the task that is associated to this activity only if it
4821                    // was the root activity in the task. The result code and data is ignored
4822                    // because we don't support returning them across task boundaries. Also, to
4823                    // keep backwards compatibility we remove the task from recents when finishing
4824                    // task with root activity.
4825                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4826                    if (!res) {
4827                        Slog.i(TAG, "Removing task failed to finish activity");
4828                    }
4829                } else {
4830                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4831                            resultData, "app-request", true);
4832                    if (!res) {
4833                        Slog.i(TAG, "Failed to finish by app-request");
4834                    }
4835                }
4836                return res;
4837            } finally {
4838                Binder.restoreCallingIdentity(origId);
4839            }
4840        }
4841    }
4842
4843    @Override
4844    public final void finishHeavyWeightApp() {
4845        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4846                != PackageManager.PERMISSION_GRANTED) {
4847            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4848                    + Binder.getCallingPid()
4849                    + ", uid=" + Binder.getCallingUid()
4850                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4851            Slog.w(TAG, msg);
4852            throw new SecurityException(msg);
4853        }
4854
4855        synchronized(this) {
4856            if (mHeavyWeightProcess == null) {
4857                return;
4858            }
4859
4860            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4861            for (int i = 0; i < activities.size(); i++) {
4862                ActivityRecord r = activities.get(i);
4863                if (!r.finishing && r.isInStackLocked()) {
4864                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4865                            null, "finish-heavy", true);
4866                }
4867            }
4868
4869            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4870                    mHeavyWeightProcess.userId, 0));
4871            mHeavyWeightProcess = null;
4872        }
4873    }
4874
4875    @Override
4876    public void crashApplication(int uid, int initialPid, String packageName,
4877            String message) {
4878        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4879                != PackageManager.PERMISSION_GRANTED) {
4880            String msg = "Permission Denial: crashApplication() from pid="
4881                    + Binder.getCallingPid()
4882                    + ", uid=" + Binder.getCallingUid()
4883                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4884            Slog.w(TAG, msg);
4885            throw new SecurityException(msg);
4886        }
4887
4888        synchronized(this) {
4889            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4890        }
4891    }
4892
4893    @Override
4894    public final void finishSubActivity(IBinder token, String resultWho,
4895            int requestCode) {
4896        synchronized(this) {
4897            final long origId = Binder.clearCallingIdentity();
4898            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4899            if (r != null) {
4900                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4901            }
4902            Binder.restoreCallingIdentity(origId);
4903        }
4904    }
4905
4906    @Override
4907    public boolean finishActivityAffinity(IBinder token) {
4908        synchronized(this) {
4909            final long origId = Binder.clearCallingIdentity();
4910            try {
4911                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4912                if (r == null) {
4913                    return false;
4914                }
4915
4916                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4917                // can finish.
4918                final TaskRecord task = r.task;
4919                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4920                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4921                    mStackSupervisor.showLockTaskToast();
4922                    return false;
4923                }
4924                return task.stack.finishActivityAffinityLocked(r);
4925            } finally {
4926                Binder.restoreCallingIdentity(origId);
4927            }
4928        }
4929    }
4930
4931    @Override
4932    public void finishVoiceTask(IVoiceInteractionSession session) {
4933        synchronized (this) {
4934            final long origId = Binder.clearCallingIdentity();
4935            try {
4936                // TODO: VI Consider treating local voice interactions and voice tasks
4937                // differently here
4938                mStackSupervisor.finishVoiceTask(session);
4939            } finally {
4940                Binder.restoreCallingIdentity(origId);
4941            }
4942        }
4943
4944    }
4945
4946    @Override
4947    public boolean releaseActivityInstance(IBinder token) {
4948        synchronized(this) {
4949            final long origId = Binder.clearCallingIdentity();
4950            try {
4951                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4952                if (r == null) {
4953                    return false;
4954                }
4955                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4956            } finally {
4957                Binder.restoreCallingIdentity(origId);
4958            }
4959        }
4960    }
4961
4962    @Override
4963    public void releaseSomeActivities(IApplicationThread appInt) {
4964        synchronized(this) {
4965            final long origId = Binder.clearCallingIdentity();
4966            try {
4967                ProcessRecord app = getRecordForAppLocked(appInt);
4968                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4969            } finally {
4970                Binder.restoreCallingIdentity(origId);
4971            }
4972        }
4973    }
4974
4975    @Override
4976    public boolean willActivityBeVisible(IBinder token) {
4977        synchronized(this) {
4978            ActivityStack stack = ActivityRecord.getStackLocked(token);
4979            if (stack != null) {
4980                return stack.willActivityBeVisibleLocked(token);
4981            }
4982            return false;
4983        }
4984    }
4985
4986    @Override
4987    public void overridePendingTransition(IBinder token, String packageName,
4988            int enterAnim, int exitAnim) {
4989        synchronized(this) {
4990            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4991            if (self == null) {
4992                return;
4993            }
4994
4995            final long origId = Binder.clearCallingIdentity();
4996
4997            if (self.state == ActivityState.RESUMED
4998                    || self.state == ActivityState.PAUSING) {
4999                mWindowManager.overridePendingAppTransition(packageName,
5000                        enterAnim, exitAnim, null);
5001            }
5002
5003            Binder.restoreCallingIdentity(origId);
5004        }
5005    }
5006
5007    /**
5008     * Main function for removing an existing process from the activity manager
5009     * as a result of that process going away.  Clears out all connections
5010     * to the process.
5011     */
5012    private final void handleAppDiedLocked(ProcessRecord app,
5013            boolean restarting, boolean allowRestart) {
5014        int pid = app.pid;
5015        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5016        if (!kept && !restarting) {
5017            removeLruProcessLocked(app);
5018            if (pid > 0) {
5019                ProcessList.remove(pid);
5020            }
5021        }
5022
5023        if (mProfileProc == app) {
5024            clearProfilerLocked();
5025        }
5026
5027        // Remove this application's activities from active lists.
5028        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5029
5030        app.activities.clear();
5031
5032        if (app.instrumentationClass != null) {
5033            Slog.w(TAG, "Crash of app " + app.processName
5034                  + " running instrumentation " + app.instrumentationClass);
5035            Bundle info = new Bundle();
5036            info.putString("shortMsg", "Process crashed.");
5037            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5038        }
5039
5040        if (!restarting && hasVisibleActivities
5041                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5042            // If there was nothing to resume, and we are not already restarting this process, but
5043            // there is a visible activity that is hosted by the process...  then make sure all
5044            // visible activities are running, taking care of restarting this process.
5045            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5046        }
5047    }
5048
5049    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5050        IBinder threadBinder = thread.asBinder();
5051        // Find the application record.
5052        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5053            ProcessRecord rec = mLruProcesses.get(i);
5054            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5055                return i;
5056            }
5057        }
5058        return -1;
5059    }
5060
5061    final ProcessRecord getRecordForAppLocked(
5062            IApplicationThread thread) {
5063        if (thread == null) {
5064            return null;
5065        }
5066
5067        int appIndex = getLRURecordIndexForAppLocked(thread);
5068        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5069    }
5070
5071    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5072        // If there are no longer any background processes running,
5073        // and the app that died was not running instrumentation,
5074        // then tell everyone we are now low on memory.
5075        boolean haveBg = false;
5076        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5077            ProcessRecord rec = mLruProcesses.get(i);
5078            if (rec.thread != null
5079                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5080                haveBg = true;
5081                break;
5082            }
5083        }
5084
5085        if (!haveBg) {
5086            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5087            if (doReport) {
5088                long now = SystemClock.uptimeMillis();
5089                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5090                    doReport = false;
5091                } else {
5092                    mLastMemUsageReportTime = now;
5093                }
5094            }
5095            final ArrayList<ProcessMemInfo> memInfos
5096                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5097            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5098            long now = SystemClock.uptimeMillis();
5099            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5100                ProcessRecord rec = mLruProcesses.get(i);
5101                if (rec == dyingProc || rec.thread == null) {
5102                    continue;
5103                }
5104                if (doReport) {
5105                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5106                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5107                }
5108                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5109                    // The low memory report is overriding any current
5110                    // state for a GC request.  Make sure to do
5111                    // heavy/important/visible/foreground processes first.
5112                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5113                        rec.lastRequestedGc = 0;
5114                    } else {
5115                        rec.lastRequestedGc = rec.lastLowMemory;
5116                    }
5117                    rec.reportLowMemory = true;
5118                    rec.lastLowMemory = now;
5119                    mProcessesToGc.remove(rec);
5120                    addProcessToGcListLocked(rec);
5121                }
5122            }
5123            if (doReport) {
5124                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5125                mHandler.sendMessage(msg);
5126            }
5127            scheduleAppGcsLocked();
5128        }
5129    }
5130
5131    final void appDiedLocked(ProcessRecord app) {
5132       appDiedLocked(app, app.pid, app.thread, false);
5133    }
5134
5135    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5136            boolean fromBinderDied) {
5137        // First check if this ProcessRecord is actually active for the pid.
5138        synchronized (mPidsSelfLocked) {
5139            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5140            if (curProc != app) {
5141                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5142                return;
5143            }
5144        }
5145
5146        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5147        synchronized (stats) {
5148            stats.noteProcessDiedLocked(app.info.uid, pid);
5149        }
5150
5151        if (!app.killed) {
5152            if (!fromBinderDied) {
5153                Process.killProcessQuiet(pid);
5154            }
5155            killProcessGroup(app.uid, pid);
5156            app.killed = true;
5157        }
5158
5159        // Clean up already done if the process has been re-started.
5160        if (app.pid == pid && app.thread != null &&
5161                app.thread.asBinder() == thread.asBinder()) {
5162            boolean doLowMem = app.instrumentationClass == null;
5163            boolean doOomAdj = doLowMem;
5164            if (!app.killedByAm) {
5165                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5166                        + ") has died");
5167                mAllowLowerMemLevel = true;
5168            } else {
5169                // Note that we always want to do oom adj to update our state with the
5170                // new number of procs.
5171                mAllowLowerMemLevel = false;
5172                doLowMem = false;
5173            }
5174            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5175            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5176                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5177            handleAppDiedLocked(app, false, true);
5178
5179            if (doOomAdj) {
5180                updateOomAdjLocked();
5181            }
5182            if (doLowMem) {
5183                doLowMemReportIfNeededLocked(app);
5184            }
5185        } else if (app.pid != pid) {
5186            // A new process has already been started.
5187            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5188                    + ") has died and restarted (pid " + app.pid + ").");
5189            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5190        } else if (DEBUG_PROCESSES) {
5191            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5192                    + thread.asBinder());
5193        }
5194    }
5195
5196    /**
5197     * If a stack trace dump file is configured, dump process stack traces.
5198     * @param clearTraces causes the dump file to be erased prior to the new
5199     *    traces being written, if true; when false, the new traces will be
5200     *    appended to any existing file content.
5201     * @param firstPids of dalvik VM processes to dump stack traces for first
5202     * @param lastPids of dalvik VM processes to dump stack traces for last
5203     * @param nativeProcs optional list of native process names to dump stack crawls
5204     * @return file containing stack traces, or null if no dump file is configured
5205     */
5206    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5207            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5208        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5209        if (tracesPath == null || tracesPath.length() == 0) {
5210            return null;
5211        }
5212
5213        File tracesFile = new File(tracesPath);
5214        try {
5215            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5216            tracesFile.createNewFile();
5217            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5218        } catch (IOException e) {
5219            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5220            return null;
5221        }
5222
5223        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5224        return tracesFile;
5225    }
5226
5227    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5228            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5229        // Use a FileObserver to detect when traces finish writing.
5230        // The order of traces is considered important to maintain for legibility.
5231        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5232            @Override
5233            public synchronized void onEvent(int event, String path) { notify(); }
5234        };
5235
5236        try {
5237            observer.startWatching();
5238
5239            // First collect all of the stacks of the most important pids.
5240            if (firstPids != null) {
5241                try {
5242                    int num = firstPids.size();
5243                    for (int i = 0; i < num; i++) {
5244                        synchronized (observer) {
5245                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5246                                    + firstPids.get(i));
5247                            final long sime = SystemClock.elapsedRealtime();
5248                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5249                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5250                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5251                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5252                        }
5253                    }
5254                } catch (InterruptedException e) {
5255                    Slog.wtf(TAG, e);
5256                }
5257            }
5258
5259            // Next collect the stacks of the native pids
5260            if (nativeProcs != null) {
5261                int[] pids = Process.getPidsForCommands(nativeProcs);
5262                if (pids != null) {
5263                    for (int pid : pids) {
5264                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5265                        final long sime = SystemClock.elapsedRealtime();
5266                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5267                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5268                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5269                    }
5270                }
5271            }
5272
5273            // Lastly, measure CPU usage.
5274            if (processCpuTracker != null) {
5275                processCpuTracker.init();
5276                System.gc();
5277                processCpuTracker.update();
5278                try {
5279                    synchronized (processCpuTracker) {
5280                        processCpuTracker.wait(500); // measure over 1/2 second.
5281                    }
5282                } catch (InterruptedException e) {
5283                }
5284                processCpuTracker.update();
5285
5286                // We'll take the stack crawls of just the top apps using CPU.
5287                final int N = processCpuTracker.countWorkingStats();
5288                int numProcs = 0;
5289                for (int i=0; i<N && numProcs<5; i++) {
5290                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5291                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5292                        numProcs++;
5293                        try {
5294                            synchronized (observer) {
5295                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5296                                        + stats.pid);
5297                                final long stime = SystemClock.elapsedRealtime();
5298                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5299                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5300                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5301                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5302                            }
5303                        } catch (InterruptedException e) {
5304                            Slog.wtf(TAG, e);
5305                        }
5306                    } else if (DEBUG_ANR) {
5307                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5308                                + stats.pid);
5309                    }
5310                }
5311            }
5312        } finally {
5313            observer.stopWatching();
5314        }
5315    }
5316
5317    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5318        if (true || IS_USER_BUILD) {
5319            return;
5320        }
5321        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5322        if (tracesPath == null || tracesPath.length() == 0) {
5323            return;
5324        }
5325
5326        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5327        StrictMode.allowThreadDiskWrites();
5328        try {
5329            final File tracesFile = new File(tracesPath);
5330            final File tracesDir = tracesFile.getParentFile();
5331            final File tracesTmp = new File(tracesDir, "__tmp__");
5332            try {
5333                if (tracesFile.exists()) {
5334                    tracesTmp.delete();
5335                    tracesFile.renameTo(tracesTmp);
5336                }
5337                StringBuilder sb = new StringBuilder();
5338                Time tobj = new Time();
5339                tobj.set(System.currentTimeMillis());
5340                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5341                sb.append(": ");
5342                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5343                sb.append(" since ");
5344                sb.append(msg);
5345                FileOutputStream fos = new FileOutputStream(tracesFile);
5346                fos.write(sb.toString().getBytes());
5347                if (app == null) {
5348                    fos.write("\n*** No application process!".getBytes());
5349                }
5350                fos.close();
5351                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5352            } catch (IOException e) {
5353                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5354                return;
5355            }
5356
5357            if (app != null) {
5358                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5359                firstPids.add(app.pid);
5360                dumpStackTraces(tracesPath, firstPids, null, null, null);
5361            }
5362
5363            File lastTracesFile = null;
5364            File curTracesFile = null;
5365            for (int i=9; i>=0; i--) {
5366                String name = String.format(Locale.US, "slow%02d.txt", i);
5367                curTracesFile = new File(tracesDir, name);
5368                if (curTracesFile.exists()) {
5369                    if (lastTracesFile != null) {
5370                        curTracesFile.renameTo(lastTracesFile);
5371                    } else {
5372                        curTracesFile.delete();
5373                    }
5374                }
5375                lastTracesFile = curTracesFile;
5376            }
5377            tracesFile.renameTo(curTracesFile);
5378            if (tracesTmp.exists()) {
5379                tracesTmp.renameTo(tracesFile);
5380            }
5381        } finally {
5382            StrictMode.setThreadPolicy(oldPolicy);
5383        }
5384    }
5385
5386    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5387        if (!mLaunchWarningShown) {
5388            mLaunchWarningShown = true;
5389            mUiHandler.post(new Runnable() {
5390                @Override
5391                public void run() {
5392                    synchronized (ActivityManagerService.this) {
5393                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5394                        d.show();
5395                        mUiHandler.postDelayed(new Runnable() {
5396                            @Override
5397                            public void run() {
5398                                synchronized (ActivityManagerService.this) {
5399                                    d.dismiss();
5400                                    mLaunchWarningShown = false;
5401                                }
5402                            }
5403                        }, 4000);
5404                    }
5405                }
5406            });
5407        }
5408    }
5409
5410    @Override
5411    public boolean clearApplicationUserData(final String packageName,
5412            final IPackageDataObserver observer, int userId) {
5413        enforceNotIsolatedCaller("clearApplicationUserData");
5414        int uid = Binder.getCallingUid();
5415        int pid = Binder.getCallingPid();
5416        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5417                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5418
5419
5420        long callingId = Binder.clearCallingIdentity();
5421        try {
5422            IPackageManager pm = AppGlobals.getPackageManager();
5423            int pkgUid = -1;
5424            synchronized(this) {
5425                if (getPackageManagerInternalLocked().canPackageBeWiped(
5426                        userId, packageName)) {
5427                    throw new SecurityException(
5428                            "Cannot clear data for a device owner or a profile owner");
5429                }
5430
5431                try {
5432                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5433                } catch (RemoteException e) {
5434                }
5435                if (pkgUid == -1) {
5436                    Slog.w(TAG, "Invalid packageName: " + packageName);
5437                    if (observer != null) {
5438                        try {
5439                            observer.onRemoveCompleted(packageName, false);
5440                        } catch (RemoteException e) {
5441                            Slog.i(TAG, "Observer no longer exists.");
5442                        }
5443                    }
5444                    return false;
5445                }
5446                if (uid == pkgUid || checkComponentPermission(
5447                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5448                        pid, uid, -1, true)
5449                        == PackageManager.PERMISSION_GRANTED) {
5450                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5451                } else {
5452                    throw new SecurityException("PID " + pid + " does not have permission "
5453                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5454                                    + " of package " + packageName);
5455                }
5456
5457                // Remove all tasks match the cleared application package and user
5458                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5459                    final TaskRecord tr = mRecentTasks.get(i);
5460                    final String taskPackageName =
5461                            tr.getBaseIntent().getComponent().getPackageName();
5462                    if (tr.userId != userId) continue;
5463                    if (!taskPackageName.equals(packageName)) continue;
5464                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5465                }
5466            }
5467
5468            final int pkgUidF = pkgUid;
5469            final int userIdF = userId;
5470            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5471                @Override
5472                public void onRemoveCompleted(String packageName, boolean succeeded)
5473                        throws RemoteException {
5474                    synchronized (ActivityManagerService.this) {
5475                        finishForceStopPackageLocked(packageName, pkgUidF);
5476                    }
5477
5478                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5479                            Uri.fromParts("package", packageName, null));
5480                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5481                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5482                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5483                            null, null, 0, null, null, null, null, false, false, userIdF);
5484
5485                    if (observer != null) {
5486                        observer.onRemoveCompleted(packageName, succeeded);
5487                    }
5488                }
5489            };
5490
5491            try {
5492                // Clear application user data
5493                pm.clearApplicationUserData(packageName, localObserver, userId);
5494
5495                synchronized(this) {
5496                    // Remove all permissions granted from/to this package
5497                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5498                }
5499
5500                // Remove all zen rules created by this package; revoke it's zen access.
5501                INotificationManager inm = NotificationManager.getService();
5502                inm.removeAutomaticZenRules(packageName);
5503                inm.setNotificationPolicyAccessGranted(packageName, false);
5504
5505            } catch (RemoteException e) {
5506            }
5507        } finally {
5508            Binder.restoreCallingIdentity(callingId);
5509        }
5510        return true;
5511    }
5512
5513    @Override
5514    public void killBackgroundProcesses(final String packageName, int userId) {
5515        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5516                != PackageManager.PERMISSION_GRANTED &&
5517                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5518                        != PackageManager.PERMISSION_GRANTED) {
5519            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5520                    + Binder.getCallingPid()
5521                    + ", uid=" + Binder.getCallingUid()
5522                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5523            Slog.w(TAG, msg);
5524            throw new SecurityException(msg);
5525        }
5526
5527        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5528                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5529        long callingId = Binder.clearCallingIdentity();
5530        try {
5531            IPackageManager pm = AppGlobals.getPackageManager();
5532            synchronized(this) {
5533                int appId = -1;
5534                try {
5535                    appId = UserHandle.getAppId(
5536                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5537                } catch (RemoteException e) {
5538                }
5539                if (appId == -1) {
5540                    Slog.w(TAG, "Invalid packageName: " + packageName);
5541                    return;
5542                }
5543                killPackageProcessesLocked(packageName, appId, userId,
5544                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5545            }
5546        } finally {
5547            Binder.restoreCallingIdentity(callingId);
5548        }
5549    }
5550
5551    @Override
5552    public void killAllBackgroundProcesses() {
5553        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5554                != PackageManager.PERMISSION_GRANTED) {
5555            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5556                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5557                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5558            Slog.w(TAG, msg);
5559            throw new SecurityException(msg);
5560        }
5561
5562        final long callingId = Binder.clearCallingIdentity();
5563        try {
5564            synchronized (this) {
5565                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5566                final int NP = mProcessNames.getMap().size();
5567                for (int ip = 0; ip < NP; ip++) {
5568                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5569                    final int NA = apps.size();
5570                    for (int ia = 0; ia < NA; ia++) {
5571                        final ProcessRecord app = apps.valueAt(ia);
5572                        if (app.persistent) {
5573                            // We don't kill persistent processes.
5574                            continue;
5575                        }
5576                        if (app.removed) {
5577                            procs.add(app);
5578                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5579                            app.removed = true;
5580                            procs.add(app);
5581                        }
5582                    }
5583                }
5584
5585                final int N = procs.size();
5586                for (int i = 0; i < N; i++) {
5587                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5588                }
5589
5590                mAllowLowerMemLevel = true;
5591
5592                updateOomAdjLocked();
5593                doLowMemReportIfNeededLocked(null);
5594            }
5595        } finally {
5596            Binder.restoreCallingIdentity(callingId);
5597        }
5598    }
5599
5600    /**
5601     * Kills all background processes, except those matching any of the
5602     * specified properties.
5603     *
5604     * @param minTargetSdk the target SDK version at or above which to preserve
5605     *                     processes, or {@code -1} to ignore the target SDK
5606     * @param maxProcState the process state at or below which to preserve
5607     *                     processes, or {@code -1} to ignore the process state
5608     */
5609    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5610        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5611                != PackageManager.PERMISSION_GRANTED) {
5612            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5613                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5614                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5615            Slog.w(TAG, msg);
5616            throw new SecurityException(msg);
5617        }
5618
5619        final long callingId = Binder.clearCallingIdentity();
5620        try {
5621            synchronized (this) {
5622                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5623                final int NP = mProcessNames.getMap().size();
5624                for (int ip = 0; ip < NP; ip++) {
5625                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5626                    final int NA = apps.size();
5627                    for (int ia = 0; ia < NA; ia++) {
5628                        final ProcessRecord app = apps.valueAt(ia);
5629                        if (app.removed) {
5630                            procs.add(app);
5631                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5632                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5633                            app.removed = true;
5634                            procs.add(app);
5635                        }
5636                    }
5637                }
5638
5639                final int N = procs.size();
5640                for (int i = 0; i < N; i++) {
5641                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5642                }
5643            }
5644        } finally {
5645            Binder.restoreCallingIdentity(callingId);
5646        }
5647    }
5648
5649    @Override
5650    public void forceStopPackage(final String packageName, int userId) {
5651        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5652                != PackageManager.PERMISSION_GRANTED) {
5653            String msg = "Permission Denial: forceStopPackage() from pid="
5654                    + Binder.getCallingPid()
5655                    + ", uid=" + Binder.getCallingUid()
5656                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5657            Slog.w(TAG, msg);
5658            throw new SecurityException(msg);
5659        }
5660        final int callingPid = Binder.getCallingPid();
5661        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5662                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5663        long callingId = Binder.clearCallingIdentity();
5664        try {
5665            IPackageManager pm = AppGlobals.getPackageManager();
5666            synchronized(this) {
5667                int[] users = userId == UserHandle.USER_ALL
5668                        ? mUserController.getUsers() : new int[] { userId };
5669                for (int user : users) {
5670                    int pkgUid = -1;
5671                    try {
5672                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5673                                user);
5674                    } catch (RemoteException e) {
5675                    }
5676                    if (pkgUid == -1) {
5677                        Slog.w(TAG, "Invalid packageName: " + packageName);
5678                        continue;
5679                    }
5680                    try {
5681                        pm.setPackageStoppedState(packageName, true, user);
5682                    } catch (RemoteException e) {
5683                    } catch (IllegalArgumentException e) {
5684                        Slog.w(TAG, "Failed trying to unstop package "
5685                                + packageName + ": " + e);
5686                    }
5687                    if (mUserController.isUserRunningLocked(user, 0)) {
5688                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5689                        finishForceStopPackageLocked(packageName, pkgUid);
5690                    }
5691                }
5692            }
5693        } finally {
5694            Binder.restoreCallingIdentity(callingId);
5695        }
5696    }
5697
5698    @Override
5699    public void addPackageDependency(String packageName) {
5700        synchronized (this) {
5701            int callingPid = Binder.getCallingPid();
5702            if (callingPid == Process.myPid()) {
5703                //  Yeah, um, no.
5704                return;
5705            }
5706            ProcessRecord proc;
5707            synchronized (mPidsSelfLocked) {
5708                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5709            }
5710            if (proc != null) {
5711                if (proc.pkgDeps == null) {
5712                    proc.pkgDeps = new ArraySet<String>(1);
5713                }
5714                proc.pkgDeps.add(packageName);
5715            }
5716        }
5717    }
5718
5719    /*
5720     * The pkg name and app id have to be specified.
5721     */
5722    @Override
5723    public void killApplication(String pkg, int appId, int userId, String reason) {
5724        if (pkg == null) {
5725            return;
5726        }
5727        // Make sure the uid is valid.
5728        if (appId < 0) {
5729            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5730            return;
5731        }
5732        int callerUid = Binder.getCallingUid();
5733        // Only the system server can kill an application
5734        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5735            // Post an aysnc message to kill the application
5736            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5737            msg.arg1 = appId;
5738            msg.arg2 = userId;
5739            Bundle bundle = new Bundle();
5740            bundle.putString("pkg", pkg);
5741            bundle.putString("reason", reason);
5742            msg.obj = bundle;
5743            mHandler.sendMessage(msg);
5744        } else {
5745            throw new SecurityException(callerUid + " cannot kill pkg: " +
5746                    pkg);
5747        }
5748    }
5749
5750    @Override
5751    public void closeSystemDialogs(String reason) {
5752        enforceNotIsolatedCaller("closeSystemDialogs");
5753
5754        final int pid = Binder.getCallingPid();
5755        final int uid = Binder.getCallingUid();
5756        final long origId = Binder.clearCallingIdentity();
5757        try {
5758            synchronized (this) {
5759                // Only allow this from foreground processes, so that background
5760                // applications can't abuse it to prevent system UI from being shown.
5761                if (uid >= Process.FIRST_APPLICATION_UID) {
5762                    ProcessRecord proc;
5763                    synchronized (mPidsSelfLocked) {
5764                        proc = mPidsSelfLocked.get(pid);
5765                    }
5766                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5767                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5768                                + " from background process " + proc);
5769                        return;
5770                    }
5771                }
5772                closeSystemDialogsLocked(reason);
5773            }
5774        } finally {
5775            Binder.restoreCallingIdentity(origId);
5776        }
5777    }
5778
5779    void closeSystemDialogsLocked(String reason) {
5780        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5781        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5782                | Intent.FLAG_RECEIVER_FOREGROUND);
5783        if (reason != null) {
5784            intent.putExtra("reason", reason);
5785        }
5786        mWindowManager.closeSystemDialogs(reason);
5787
5788        mStackSupervisor.closeSystemDialogsLocked();
5789
5790        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5791                AppOpsManager.OP_NONE, null, false, false,
5792                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5793    }
5794
5795    @Override
5796    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5797        enforceNotIsolatedCaller("getProcessMemoryInfo");
5798        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5799        for (int i=pids.length-1; i>=0; i--) {
5800            ProcessRecord proc;
5801            int oomAdj;
5802            synchronized (this) {
5803                synchronized (mPidsSelfLocked) {
5804                    proc = mPidsSelfLocked.get(pids[i]);
5805                    oomAdj = proc != null ? proc.setAdj : 0;
5806                }
5807            }
5808            infos[i] = new Debug.MemoryInfo();
5809            Debug.getMemoryInfo(pids[i], infos[i]);
5810            if (proc != null) {
5811                synchronized (this) {
5812                    if (proc.thread != null && proc.setAdj == oomAdj) {
5813                        // Record this for posterity if the process has been stable.
5814                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5815                                infos[i].getTotalUss(), false, proc.pkgList);
5816                    }
5817                }
5818            }
5819        }
5820        return infos;
5821    }
5822
5823    @Override
5824    public long[] getProcessPss(int[] pids) {
5825        enforceNotIsolatedCaller("getProcessPss");
5826        long[] pss = new long[pids.length];
5827        for (int i=pids.length-1; i>=0; i--) {
5828            ProcessRecord proc;
5829            int oomAdj;
5830            synchronized (this) {
5831                synchronized (mPidsSelfLocked) {
5832                    proc = mPidsSelfLocked.get(pids[i]);
5833                    oomAdj = proc != null ? proc.setAdj : 0;
5834                }
5835            }
5836            long[] tmpUss = new long[1];
5837            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5838            if (proc != null) {
5839                synchronized (this) {
5840                    if (proc.thread != null && proc.setAdj == oomAdj) {
5841                        // Record this for posterity if the process has been stable.
5842                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5843                    }
5844                }
5845            }
5846        }
5847        return pss;
5848    }
5849
5850    @Override
5851    public void killApplicationProcess(String processName, int uid) {
5852        if (processName == null) {
5853            return;
5854        }
5855
5856        int callerUid = Binder.getCallingUid();
5857        // Only the system server can kill an application
5858        if (callerUid == Process.SYSTEM_UID) {
5859            synchronized (this) {
5860                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5861                if (app != null && app.thread != null) {
5862                    try {
5863                        app.thread.scheduleSuicide();
5864                    } catch (RemoteException e) {
5865                        // If the other end already died, then our work here is done.
5866                    }
5867                } else {
5868                    Slog.w(TAG, "Process/uid not found attempting kill of "
5869                            + processName + " / " + uid);
5870                }
5871            }
5872        } else {
5873            throw new SecurityException(callerUid + " cannot kill app process: " +
5874                    processName);
5875        }
5876    }
5877
5878    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5879        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5880                false, true, false, false, UserHandle.getUserId(uid), reason);
5881    }
5882
5883    private void finishForceStopPackageLocked(final String packageName, int uid) {
5884        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5885                Uri.fromParts("package", packageName, null));
5886        if (!mProcessesReady) {
5887            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5888                    | Intent.FLAG_RECEIVER_FOREGROUND);
5889        }
5890        intent.putExtra(Intent.EXTRA_UID, uid);
5891        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5892        broadcastIntentLocked(null, null, intent,
5893                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5894                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5895    }
5896
5897
5898    private final boolean killPackageProcessesLocked(String packageName, int appId,
5899            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5900            boolean doit, boolean evenPersistent, String reason) {
5901        ArrayList<ProcessRecord> procs = new ArrayList<>();
5902
5903        // Remove all processes this package may have touched: all with the
5904        // same UID (except for the system or root user), and all whose name
5905        // matches the package name.
5906        final int NP = mProcessNames.getMap().size();
5907        for (int ip=0; ip<NP; ip++) {
5908            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5909            final int NA = apps.size();
5910            for (int ia=0; ia<NA; ia++) {
5911                ProcessRecord app = apps.valueAt(ia);
5912                if (app.persistent && !evenPersistent) {
5913                    // we don't kill persistent processes
5914                    continue;
5915                }
5916                if (app.removed) {
5917                    if (doit) {
5918                        procs.add(app);
5919                    }
5920                    continue;
5921                }
5922
5923                // Skip process if it doesn't meet our oom adj requirement.
5924                if (app.setAdj < minOomAdj) {
5925                    continue;
5926                }
5927
5928                // If no package is specified, we call all processes under the
5929                // give user id.
5930                if (packageName == null) {
5931                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5932                        continue;
5933                    }
5934                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5935                        continue;
5936                    }
5937                // Package has been specified, we want to hit all processes
5938                // that match it.  We need to qualify this by the processes
5939                // that are running under the specified app and user ID.
5940                } else {
5941                    final boolean isDep = app.pkgDeps != null
5942                            && app.pkgDeps.contains(packageName);
5943                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5944                        continue;
5945                    }
5946                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5947                        continue;
5948                    }
5949                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5950                        continue;
5951                    }
5952                }
5953
5954                // Process has passed all conditions, kill it!
5955                if (!doit) {
5956                    return true;
5957                }
5958                app.removed = true;
5959                procs.add(app);
5960            }
5961        }
5962
5963        int N = procs.size();
5964        for (int i=0; i<N; i++) {
5965            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5966        }
5967        updateOomAdjLocked();
5968        return N > 0;
5969    }
5970
5971    private void cleanupDisabledPackageComponentsLocked(
5972            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5973
5974        Set<String> disabledClasses = null;
5975        boolean packageDisabled = false;
5976        IPackageManager pm = AppGlobals.getPackageManager();
5977
5978        if (changedClasses == null) {
5979            // Nothing changed...
5980            return;
5981        }
5982
5983        // Determine enable/disable state of the package and its components.
5984        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5985        for (int i = changedClasses.length - 1; i >= 0; i--) {
5986            final String changedClass = changedClasses[i];
5987
5988            if (changedClass.equals(packageName)) {
5989                try {
5990                    // Entire package setting changed
5991                    enabled = pm.getApplicationEnabledSetting(packageName,
5992                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5993                } catch (Exception e) {
5994                    // No such package/component; probably racing with uninstall.  In any
5995                    // event it means we have nothing further to do here.
5996                    return;
5997                }
5998                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5999                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6000                if (packageDisabled) {
6001                    // Entire package is disabled.
6002                    // No need to continue to check component states.
6003                    disabledClasses = null;
6004                    break;
6005                }
6006            } else {
6007                try {
6008                    enabled = pm.getComponentEnabledSetting(
6009                            new ComponentName(packageName, changedClass),
6010                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6011                } catch (Exception e) {
6012                    // As above, probably racing with uninstall.
6013                    return;
6014                }
6015                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6016                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6017                    if (disabledClasses == null) {
6018                        disabledClasses = new ArraySet<>(changedClasses.length);
6019                    }
6020                    disabledClasses.add(changedClass);
6021                }
6022            }
6023        }
6024
6025        if (!packageDisabled && disabledClasses == null) {
6026            // Nothing to do here...
6027            return;
6028        }
6029
6030        // Clean-up disabled activities.
6031        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6032                packageName, disabledClasses, true, false, userId) && mBooted) {
6033            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6034            mStackSupervisor.scheduleIdleLocked();
6035        }
6036
6037        // Clean-up disabled tasks
6038        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6039
6040        // Clean-up disabled services.
6041        mServices.bringDownDisabledPackageServicesLocked(
6042                packageName, disabledClasses, userId, false, killProcess, true);
6043
6044        // Clean-up disabled providers.
6045        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6046        mProviderMap.collectPackageProvidersLocked(
6047                packageName, disabledClasses, true, false, userId, providers);
6048        for (int i = providers.size() - 1; i >= 0; i--) {
6049            removeDyingProviderLocked(null, providers.get(i), true);
6050        }
6051
6052        // Clean-up disabled broadcast receivers.
6053        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6054            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6055                    packageName, disabledClasses, userId, true);
6056        }
6057
6058    }
6059
6060    final boolean clearBroadcastQueueForUserLocked(int userId) {
6061        boolean didSomething = false;
6062        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6063            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6064                    null, null, userId, true);
6065        }
6066        return didSomething;
6067    }
6068
6069    final boolean forceStopPackageLocked(String packageName, int appId,
6070            boolean callerWillRestart, boolean purgeCache, boolean doit,
6071            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6072        int i;
6073
6074        if (userId == UserHandle.USER_ALL && packageName == null) {
6075            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6076        }
6077
6078        if (appId < 0 && packageName != null) {
6079            try {
6080                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6081                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6082            } catch (RemoteException e) {
6083            }
6084        }
6085
6086        if (doit) {
6087            if (packageName != null) {
6088                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6089                        + " user=" + userId + ": " + reason);
6090            } else {
6091                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6092            }
6093
6094            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6095        }
6096
6097        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6098                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6099                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6100
6101        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6102                packageName, null, doit, evenPersistent, userId)) {
6103            if (!doit) {
6104                return true;
6105            }
6106            didSomething = true;
6107        }
6108
6109        if (mServices.bringDownDisabledPackageServicesLocked(
6110                packageName, null, userId, evenPersistent, true, doit)) {
6111            if (!doit) {
6112                return true;
6113            }
6114            didSomething = true;
6115        }
6116
6117        if (packageName == null) {
6118            // Remove all sticky broadcasts from this user.
6119            mStickyBroadcasts.remove(userId);
6120        }
6121
6122        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6123        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6124                userId, providers)) {
6125            if (!doit) {
6126                return true;
6127            }
6128            didSomething = true;
6129        }
6130        for (i = providers.size() - 1; i >= 0; i--) {
6131            removeDyingProviderLocked(null, providers.get(i), true);
6132        }
6133
6134        // Remove transient permissions granted from/to this package/user
6135        removeUriPermissionsForPackageLocked(packageName, userId, false);
6136
6137        if (doit) {
6138            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6139                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6140                        packageName, null, userId, doit);
6141            }
6142        }
6143
6144        if (packageName == null || uninstalling) {
6145            // Remove pending intents.  For now we only do this when force
6146            // stopping users, because we have some problems when doing this
6147            // for packages -- app widgets are not currently cleaned up for
6148            // such packages, so they can be left with bad pending intents.
6149            if (mIntentSenderRecords.size() > 0) {
6150                Iterator<WeakReference<PendingIntentRecord>> it
6151                        = mIntentSenderRecords.values().iterator();
6152                while (it.hasNext()) {
6153                    WeakReference<PendingIntentRecord> wpir = it.next();
6154                    if (wpir == null) {
6155                        it.remove();
6156                        continue;
6157                    }
6158                    PendingIntentRecord pir = wpir.get();
6159                    if (pir == null) {
6160                        it.remove();
6161                        continue;
6162                    }
6163                    if (packageName == null) {
6164                        // Stopping user, remove all objects for the user.
6165                        if (pir.key.userId != userId) {
6166                            // Not the same user, skip it.
6167                            continue;
6168                        }
6169                    } else {
6170                        if (UserHandle.getAppId(pir.uid) != appId) {
6171                            // Different app id, skip it.
6172                            continue;
6173                        }
6174                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6175                            // Different user, skip it.
6176                            continue;
6177                        }
6178                        if (!pir.key.packageName.equals(packageName)) {
6179                            // Different package, skip it.
6180                            continue;
6181                        }
6182                    }
6183                    if (!doit) {
6184                        return true;
6185                    }
6186                    didSomething = true;
6187                    it.remove();
6188                    pir.canceled = true;
6189                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6190                        pir.key.activity.pendingResults.remove(pir.ref);
6191                    }
6192                }
6193            }
6194        }
6195
6196        if (doit) {
6197            if (purgeCache && packageName != null) {
6198                AttributeCache ac = AttributeCache.instance();
6199                if (ac != null) {
6200                    ac.removePackage(packageName);
6201                }
6202            }
6203            if (mBooted) {
6204                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6205                mStackSupervisor.scheduleIdleLocked();
6206            }
6207        }
6208
6209        return didSomething;
6210    }
6211
6212    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6213        ProcessRecord old = mProcessNames.remove(name, uid);
6214        if (old != null) {
6215            old.uidRecord.numProcs--;
6216            if (old.uidRecord.numProcs == 0) {
6217                // No more processes using this uid, tell clients it is gone.
6218                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6219                        "No more processes in " + old.uidRecord);
6220                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6221                mActiveUids.remove(uid);
6222                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6223            }
6224            old.uidRecord = null;
6225        }
6226        mIsolatedProcesses.remove(uid);
6227        return old;
6228    }
6229
6230    private final void addProcessNameLocked(ProcessRecord proc) {
6231        // We shouldn't already have a process under this name, but just in case we
6232        // need to clean up whatever may be there now.
6233        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6234        if (old == proc && proc.persistent) {
6235            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6236            Slog.w(TAG, "Re-adding persistent process " + proc);
6237        } else if (old != null) {
6238            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6239        }
6240        UidRecord uidRec = mActiveUids.get(proc.uid);
6241        if (uidRec == null) {
6242            uidRec = new UidRecord(proc.uid);
6243            // This is the first appearance of the uid, report it now!
6244            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6245                    "Creating new process uid: " + uidRec);
6246            mActiveUids.put(proc.uid, uidRec);
6247            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6248            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6249        }
6250        proc.uidRecord = uidRec;
6251        uidRec.numProcs++;
6252        mProcessNames.put(proc.processName, proc.uid, proc);
6253        if (proc.isolated) {
6254            mIsolatedProcesses.put(proc.uid, proc);
6255        }
6256    }
6257
6258    boolean removeProcessLocked(ProcessRecord app,
6259            boolean callerWillRestart, boolean allowRestart, String reason) {
6260        final String name = app.processName;
6261        final int uid = app.uid;
6262        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6263            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6264
6265        ProcessRecord old = mProcessNames.get(name, uid);
6266        if (old != app) {
6267            // This process is no longer active, so nothing to do.
6268            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6269            return false;
6270        }
6271        removeProcessNameLocked(name, uid);
6272        if (mHeavyWeightProcess == app) {
6273            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6274                    mHeavyWeightProcess.userId, 0));
6275            mHeavyWeightProcess = null;
6276        }
6277        boolean needRestart = false;
6278        if (app.pid > 0 && app.pid != MY_PID) {
6279            int pid = app.pid;
6280            synchronized (mPidsSelfLocked) {
6281                mPidsSelfLocked.remove(pid);
6282                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6283            }
6284            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6285            if (app.isolated) {
6286                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6287            }
6288            boolean willRestart = false;
6289            if (app.persistent && !app.isolated) {
6290                if (!callerWillRestart) {
6291                    willRestart = true;
6292                } else {
6293                    needRestart = true;
6294                }
6295            }
6296            app.kill(reason, true);
6297            handleAppDiedLocked(app, willRestart, allowRestart);
6298            if (willRestart) {
6299                removeLruProcessLocked(app);
6300                addAppLocked(app.info, false, null /* ABI override */);
6301            }
6302        } else {
6303            mRemovedProcesses.add(app);
6304        }
6305
6306        return needRestart;
6307    }
6308
6309    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6310        cleanupAppInLaunchingProvidersLocked(app, true);
6311        removeProcessLocked(app, false, true, "timeout publishing content providers");
6312    }
6313
6314    private final void processStartTimedOutLocked(ProcessRecord app) {
6315        final int pid = app.pid;
6316        boolean gone = false;
6317        synchronized (mPidsSelfLocked) {
6318            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6319            if (knownApp != null && knownApp.thread == null) {
6320                mPidsSelfLocked.remove(pid);
6321                gone = true;
6322            }
6323        }
6324
6325        if (gone) {
6326            Slog.w(TAG, "Process " + app + " failed to attach");
6327            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6328                    pid, app.uid, app.processName);
6329            removeProcessNameLocked(app.processName, app.uid);
6330            if (mHeavyWeightProcess == app) {
6331                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6332                        mHeavyWeightProcess.userId, 0));
6333                mHeavyWeightProcess = null;
6334            }
6335            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6336            if (app.isolated) {
6337                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6338            }
6339            // Take care of any launching providers waiting for this process.
6340            cleanupAppInLaunchingProvidersLocked(app, true);
6341            // Take care of any services that are waiting for the process.
6342            mServices.processStartTimedOutLocked(app);
6343            app.kill("start timeout", true);
6344            removeLruProcessLocked(app);
6345            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6346                Slog.w(TAG, "Unattached app died before backup, skipping");
6347                try {
6348                    IBackupManager bm = IBackupManager.Stub.asInterface(
6349                            ServiceManager.getService(Context.BACKUP_SERVICE));
6350                    bm.agentDisconnected(app.info.packageName);
6351                } catch (RemoteException e) {
6352                    // Can't happen; the backup manager is local
6353                }
6354            }
6355            if (isPendingBroadcastProcessLocked(pid)) {
6356                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6357                skipPendingBroadcastLocked(pid);
6358            }
6359        } else {
6360            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6361        }
6362    }
6363
6364    private final boolean attachApplicationLocked(IApplicationThread thread,
6365            int pid) {
6366
6367        // Find the application record that is being attached...  either via
6368        // the pid if we are running in multiple processes, or just pull the
6369        // next app record if we are emulating process with anonymous threads.
6370        ProcessRecord app;
6371        if (pid != MY_PID && pid >= 0) {
6372            synchronized (mPidsSelfLocked) {
6373                app = mPidsSelfLocked.get(pid);
6374            }
6375        } else {
6376            app = null;
6377        }
6378
6379        if (app == null) {
6380            Slog.w(TAG, "No pending application record for pid " + pid
6381                    + " (IApplicationThread " + thread + "); dropping process");
6382            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6383            if (pid > 0 && pid != MY_PID) {
6384                Process.killProcessQuiet(pid);
6385                //TODO: killProcessGroup(app.info.uid, pid);
6386            } else {
6387                try {
6388                    thread.scheduleExit();
6389                } catch (Exception e) {
6390                    // Ignore exceptions.
6391                }
6392            }
6393            return false;
6394        }
6395
6396        // If this application record is still attached to a previous
6397        // process, clean it up now.
6398        if (app.thread != null) {
6399            handleAppDiedLocked(app, true, true);
6400        }
6401
6402        // Tell the process all about itself.
6403
6404        if (DEBUG_ALL) Slog.v(
6405                TAG, "Binding process pid " + pid + " to record " + app);
6406
6407        final String processName = app.processName;
6408        try {
6409            AppDeathRecipient adr = new AppDeathRecipient(
6410                    app, pid, thread);
6411            thread.asBinder().linkToDeath(adr, 0);
6412            app.deathRecipient = adr;
6413        } catch (RemoteException e) {
6414            app.resetPackageList(mProcessStats);
6415            startProcessLocked(app, "link fail", processName);
6416            return false;
6417        }
6418
6419        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6420
6421        app.makeActive(thread, mProcessStats);
6422        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6423        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6424        app.forcingToForeground = null;
6425        updateProcessForegroundLocked(app, false, false);
6426        app.hasShownUi = false;
6427        app.debugging = false;
6428        app.cached = false;
6429        app.killedByAm = false;
6430
6431        // We carefully use the same state that PackageManager uses for
6432        // filtering, since we use this flag to decide if we need to install
6433        // providers when user is unlocked later
6434        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6435
6436        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6437
6438        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6439        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6440
6441        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6442            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6443            msg.obj = app;
6444            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6445        }
6446
6447        if (!normalMode) {
6448            Slog.i(TAG, "Launching preboot mode app: " + app);
6449        }
6450
6451        if (DEBUG_ALL) Slog.v(
6452            TAG, "New app record " + app
6453            + " thread=" + thread.asBinder() + " pid=" + pid);
6454        try {
6455            int testMode = IApplicationThread.DEBUG_OFF;
6456            if (mDebugApp != null && mDebugApp.equals(processName)) {
6457                testMode = mWaitForDebugger
6458                    ? IApplicationThread.DEBUG_WAIT
6459                    : IApplicationThread.DEBUG_ON;
6460                app.debugging = true;
6461                if (mDebugTransient) {
6462                    mDebugApp = mOrigDebugApp;
6463                    mWaitForDebugger = mOrigWaitForDebugger;
6464                }
6465            }
6466            String profileFile = app.instrumentationProfileFile;
6467            ParcelFileDescriptor profileFd = null;
6468            int samplingInterval = 0;
6469            boolean profileAutoStop = false;
6470            if (mProfileApp != null && mProfileApp.equals(processName)) {
6471                mProfileProc = app;
6472                profileFile = mProfileFile;
6473                profileFd = mProfileFd;
6474                samplingInterval = mSamplingInterval;
6475                profileAutoStop = mAutoStopProfiler;
6476            }
6477            boolean enableTrackAllocation = false;
6478            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6479                enableTrackAllocation = true;
6480                mTrackAllocationApp = null;
6481            }
6482
6483            // If the app is being launched for restore or full backup, set it up specially
6484            boolean isRestrictedBackupMode = false;
6485            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6486                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6487                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6488                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6489                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6490            }
6491
6492            if (app.instrumentationClass != null) {
6493                notifyPackageUse(app.instrumentationClass.getPackageName(),
6494                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6495            }
6496            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6497                    + processName + " with config " + mConfiguration);
6498            ApplicationInfo appInfo = app.instrumentationInfo != null
6499                    ? app.instrumentationInfo : app.info;
6500            app.compat = compatibilityInfoForPackageLocked(appInfo);
6501            if (profileFd != null) {
6502                profileFd = profileFd.dup();
6503            }
6504            ProfilerInfo profilerInfo = profileFile == null ? null
6505                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6506            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6507                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6508                    app.instrumentationUiAutomationConnection, testMode,
6509                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6510                    isRestrictedBackupMode || !normalMode, app.persistent,
6511                    new Configuration(mConfiguration), app.compat,
6512                    getCommonServicesLocked(app.isolated),
6513                    mCoreSettingsObserver.getCoreSettingsLocked());
6514            updateLruProcessLocked(app, false, null);
6515            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6516        } catch (Exception e) {
6517            // todo: Yikes!  What should we do?  For now we will try to
6518            // start another process, but that could easily get us in
6519            // an infinite loop of restarting processes...
6520            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6521
6522            app.resetPackageList(mProcessStats);
6523            app.unlinkDeathRecipient();
6524            startProcessLocked(app, "bind fail", processName);
6525            return false;
6526        }
6527
6528        // Remove this record from the list of starting applications.
6529        mPersistentStartingProcesses.remove(app);
6530        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6531                "Attach application locked removing on hold: " + app);
6532        mProcessesOnHold.remove(app);
6533
6534        boolean badApp = false;
6535        boolean didSomething = false;
6536
6537        // See if the top visible activity is waiting to run in this process...
6538        if (normalMode) {
6539            try {
6540                if (mStackSupervisor.attachApplicationLocked(app)) {
6541                    didSomething = true;
6542                }
6543            } catch (Exception e) {
6544                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6545                badApp = true;
6546            }
6547        }
6548
6549        // Find any services that should be running in this process...
6550        if (!badApp) {
6551            try {
6552                didSomething |= mServices.attachApplicationLocked(app, processName);
6553            } catch (Exception e) {
6554                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6555                badApp = true;
6556            }
6557        }
6558
6559        // Check if a next-broadcast receiver is in this process...
6560        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6561            try {
6562                didSomething |= sendPendingBroadcastsLocked(app);
6563            } catch (Exception e) {
6564                // If the app died trying to launch the receiver we declare it 'bad'
6565                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6566                badApp = true;
6567            }
6568        }
6569
6570        // Check whether the next backup agent is in this process...
6571        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6572            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6573                    "New app is backup target, launching agent for " + app);
6574            notifyPackageUse(mBackupTarget.appInfo.packageName,
6575                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6576            try {
6577                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6578                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6579                        mBackupTarget.backupMode);
6580            } catch (Exception e) {
6581                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6582                badApp = true;
6583            }
6584        }
6585
6586        if (badApp) {
6587            app.kill("error during init", true);
6588            handleAppDiedLocked(app, false, true);
6589            return false;
6590        }
6591
6592        if (!didSomething) {
6593            updateOomAdjLocked();
6594        }
6595
6596        return true;
6597    }
6598
6599    @Override
6600    public final void attachApplication(IApplicationThread thread) {
6601        synchronized (this) {
6602            int callingPid = Binder.getCallingPid();
6603            final long origId = Binder.clearCallingIdentity();
6604            attachApplicationLocked(thread, callingPid);
6605            Binder.restoreCallingIdentity(origId);
6606        }
6607    }
6608
6609    @Override
6610    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6611        final long origId = Binder.clearCallingIdentity();
6612        synchronized (this) {
6613            ActivityStack stack = ActivityRecord.getStackLocked(token);
6614            if (stack != null) {
6615                ActivityRecord r =
6616                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6617                if (stopProfiling) {
6618                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6619                        try {
6620                            mProfileFd.close();
6621                        } catch (IOException e) {
6622                        }
6623                        clearProfilerLocked();
6624                    }
6625                }
6626            }
6627        }
6628        Binder.restoreCallingIdentity(origId);
6629    }
6630
6631    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6632        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6633                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6634    }
6635
6636    void enableScreenAfterBoot() {
6637        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6638                SystemClock.uptimeMillis());
6639        mWindowManager.enableScreenAfterBoot();
6640
6641        synchronized (this) {
6642            updateEventDispatchingLocked();
6643        }
6644    }
6645
6646    @Override
6647    public void showBootMessage(final CharSequence msg, final boolean always) {
6648        if (Binder.getCallingUid() != Process.myUid()) {
6649            // These days only the core system can call this, so apps can't get in
6650            // the way of what we show about running them.
6651        }
6652        mWindowManager.showBootMessage(msg, always);
6653    }
6654
6655    @Override
6656    public void keyguardWaitingForActivityDrawn() {
6657        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6658        final long token = Binder.clearCallingIdentity();
6659        try {
6660            synchronized (this) {
6661                if (DEBUG_LOCKSCREEN) logLockScreen("");
6662                mWindowManager.keyguardWaitingForActivityDrawn();
6663                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6664                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6665                    updateSleepIfNeededLocked();
6666                }
6667            }
6668        } finally {
6669            Binder.restoreCallingIdentity(token);
6670        }
6671    }
6672
6673    @Override
6674    public void keyguardGoingAway(int flags) {
6675        enforceNotIsolatedCaller("keyguardGoingAway");
6676        final long token = Binder.clearCallingIdentity();
6677        try {
6678            synchronized (this) {
6679                if (DEBUG_LOCKSCREEN) logLockScreen("");
6680                mWindowManager.keyguardGoingAway(flags);
6681                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6682                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6683                    updateSleepIfNeededLocked();
6684
6685                    // Some stack visibility might change (e.g. docked stack)
6686                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6687                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6688                }
6689            }
6690        } finally {
6691            Binder.restoreCallingIdentity(token);
6692        }
6693    }
6694
6695    final void finishBooting() {
6696        synchronized (this) {
6697            if (!mBootAnimationComplete) {
6698                mCallFinishBooting = true;
6699                return;
6700            }
6701            mCallFinishBooting = false;
6702        }
6703
6704        ArraySet<String> completedIsas = new ArraySet<String>();
6705        for (String abi : Build.SUPPORTED_ABIS) {
6706            Process.establishZygoteConnectionForAbi(abi);
6707            final String instructionSet = VMRuntime.getInstructionSet(abi);
6708            if (!completedIsas.contains(instructionSet)) {
6709                try {
6710                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6711                } catch (InstallerException e) {
6712                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6713                            e.getMessage() +")");
6714                }
6715                completedIsas.add(instructionSet);
6716            }
6717        }
6718
6719        IntentFilter pkgFilter = new IntentFilter();
6720        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6721        pkgFilter.addDataScheme("package");
6722        mContext.registerReceiver(new BroadcastReceiver() {
6723            @Override
6724            public void onReceive(Context context, Intent intent) {
6725                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6726                if (pkgs != null) {
6727                    for (String pkg : pkgs) {
6728                        synchronized (ActivityManagerService.this) {
6729                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6730                                    0, "query restart")) {
6731                                setResultCode(Activity.RESULT_OK);
6732                                return;
6733                            }
6734                        }
6735                    }
6736                }
6737            }
6738        }, pkgFilter);
6739
6740        IntentFilter dumpheapFilter = new IntentFilter();
6741        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6742        mContext.registerReceiver(new BroadcastReceiver() {
6743            @Override
6744            public void onReceive(Context context, Intent intent) {
6745                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6746                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6747                } else {
6748                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6749                }
6750            }
6751        }, dumpheapFilter);
6752
6753        // Let system services know.
6754        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6755
6756        synchronized (this) {
6757            // Ensure that any processes we had put on hold are now started
6758            // up.
6759            final int NP = mProcessesOnHold.size();
6760            if (NP > 0) {
6761                ArrayList<ProcessRecord> procs =
6762                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6763                for (int ip=0; ip<NP; ip++) {
6764                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6765                            + procs.get(ip));
6766                    startProcessLocked(procs.get(ip), "on-hold", null);
6767                }
6768            }
6769
6770            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6771                // Start looking for apps that are abusing wake locks.
6772                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6773                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6774                // Tell anyone interested that we are done booting!
6775                SystemProperties.set("sys.boot_completed", "1");
6776
6777                // And trigger dev.bootcomplete if we are not showing encryption progress
6778                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6779                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6780                    SystemProperties.set("dev.bootcomplete", "1");
6781                }
6782                mUserController.sendBootCompletedLocked(
6783                        new IIntentReceiver.Stub() {
6784                            @Override
6785                            public void performReceive(Intent intent, int resultCode,
6786                                    String data, Bundle extras, boolean ordered,
6787                                    boolean sticky, int sendingUser) {
6788                                synchronized (ActivityManagerService.this) {
6789                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6790                                            true, false);
6791                                }
6792                            }
6793                        });
6794                scheduleStartProfilesLocked();
6795            }
6796        }
6797    }
6798
6799    @Override
6800    public void bootAnimationComplete() {
6801        final boolean callFinishBooting;
6802        synchronized (this) {
6803            callFinishBooting = mCallFinishBooting;
6804            mBootAnimationComplete = true;
6805        }
6806        if (callFinishBooting) {
6807            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6808            finishBooting();
6809            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6810        }
6811    }
6812
6813    final void ensureBootCompleted() {
6814        boolean booting;
6815        boolean enableScreen;
6816        synchronized (this) {
6817            booting = mBooting;
6818            mBooting = false;
6819            enableScreen = !mBooted;
6820            mBooted = true;
6821        }
6822
6823        if (booting) {
6824            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6825            finishBooting();
6826            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6827        }
6828
6829        if (enableScreen) {
6830            enableScreenAfterBoot();
6831        }
6832    }
6833
6834    @Override
6835    public final void activityResumed(IBinder token) {
6836        final long origId = Binder.clearCallingIdentity();
6837        synchronized(this) {
6838            ActivityStack stack = ActivityRecord.getStackLocked(token);
6839            if (stack != null) {
6840                stack.activityResumedLocked(token);
6841            }
6842        }
6843        Binder.restoreCallingIdentity(origId);
6844    }
6845
6846    @Override
6847    public final void activityPaused(IBinder token) {
6848        final long origId = Binder.clearCallingIdentity();
6849        synchronized(this) {
6850            ActivityStack stack = ActivityRecord.getStackLocked(token);
6851            if (stack != null) {
6852                stack.activityPausedLocked(token, false);
6853            }
6854        }
6855        Binder.restoreCallingIdentity(origId);
6856    }
6857
6858    @Override
6859    public final void activityStopped(IBinder token, Bundle icicle,
6860            PersistableBundle persistentState, CharSequence description) {
6861        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6862
6863        // Refuse possible leaked file descriptors
6864        if (icicle != null && icicle.hasFileDescriptors()) {
6865            throw new IllegalArgumentException("File descriptors passed in Bundle");
6866        }
6867
6868        final long origId = Binder.clearCallingIdentity();
6869
6870        synchronized (this) {
6871            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6872            if (r != null) {
6873                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6874            }
6875        }
6876
6877        trimApplications();
6878
6879        Binder.restoreCallingIdentity(origId);
6880    }
6881
6882    @Override
6883    public final void activityDestroyed(IBinder token) {
6884        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6885        synchronized (this) {
6886            ActivityStack stack = ActivityRecord.getStackLocked(token);
6887            if (stack != null) {
6888                stack.activityDestroyedLocked(token, "activityDestroyed");
6889            }
6890        }
6891    }
6892
6893    @Override
6894    public final void activityRelaunched(IBinder token) {
6895        final long origId = Binder.clearCallingIdentity();
6896        synchronized (this) {
6897            mStackSupervisor.activityRelaunchedLocked(token);
6898        }
6899        Binder.restoreCallingIdentity(origId);
6900    }
6901
6902    @Override
6903    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6904            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6905        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6906                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6907        synchronized (this) {
6908            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6909            if (record == null) {
6910                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6911                        + "found for: " + token);
6912            }
6913            record.setSizeConfigurations(horizontalSizeConfiguration,
6914                    verticalSizeConfigurations, smallestSizeConfigurations);
6915        }
6916    }
6917
6918    @Override
6919    public final void backgroundResourcesReleased(IBinder token) {
6920        final long origId = Binder.clearCallingIdentity();
6921        try {
6922            synchronized (this) {
6923                ActivityStack stack = ActivityRecord.getStackLocked(token);
6924                if (stack != null) {
6925                    stack.backgroundResourcesReleased();
6926                }
6927            }
6928        } finally {
6929            Binder.restoreCallingIdentity(origId);
6930        }
6931    }
6932
6933    @Override
6934    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6935        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6936    }
6937
6938    @Override
6939    public final void notifyEnterAnimationComplete(IBinder token) {
6940        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6941    }
6942
6943    @Override
6944    public String getCallingPackage(IBinder token) {
6945        synchronized (this) {
6946            ActivityRecord r = getCallingRecordLocked(token);
6947            return r != null ? r.info.packageName : null;
6948        }
6949    }
6950
6951    @Override
6952    public ComponentName getCallingActivity(IBinder token) {
6953        synchronized (this) {
6954            ActivityRecord r = getCallingRecordLocked(token);
6955            return r != null ? r.intent.getComponent() : null;
6956        }
6957    }
6958
6959    private ActivityRecord getCallingRecordLocked(IBinder token) {
6960        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6961        if (r == null) {
6962            return null;
6963        }
6964        return r.resultTo;
6965    }
6966
6967    @Override
6968    public ComponentName getActivityClassForToken(IBinder token) {
6969        synchronized(this) {
6970            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6971            if (r == null) {
6972                return null;
6973            }
6974            return r.intent.getComponent();
6975        }
6976    }
6977
6978    @Override
6979    public String getPackageForToken(IBinder token) {
6980        synchronized(this) {
6981            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6982            if (r == null) {
6983                return null;
6984            }
6985            return r.packageName;
6986        }
6987    }
6988
6989    @Override
6990    public boolean isRootVoiceInteraction(IBinder token) {
6991        synchronized(this) {
6992            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6993            if (r == null) {
6994                return false;
6995            }
6996            return r.rootVoiceInteraction;
6997        }
6998    }
6999
7000    @Override
7001    public IIntentSender getIntentSender(int type,
7002            String packageName, IBinder token, String resultWho,
7003            int requestCode, Intent[] intents, String[] resolvedTypes,
7004            int flags, Bundle bOptions, int userId) {
7005        enforceNotIsolatedCaller("getIntentSender");
7006        // Refuse possible leaked file descriptors
7007        if (intents != null) {
7008            if (intents.length < 1) {
7009                throw new IllegalArgumentException("Intents array length must be >= 1");
7010            }
7011            for (int i=0; i<intents.length; i++) {
7012                Intent intent = intents[i];
7013                if (intent != null) {
7014                    if (intent.hasFileDescriptors()) {
7015                        throw new IllegalArgumentException("File descriptors passed in Intent");
7016                    }
7017                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7018                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7019                        throw new IllegalArgumentException(
7020                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7021                    }
7022                    intents[i] = new Intent(intent);
7023                }
7024            }
7025            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7026                throw new IllegalArgumentException(
7027                        "Intent array length does not match resolvedTypes length");
7028            }
7029        }
7030        if (bOptions != null) {
7031            if (bOptions.hasFileDescriptors()) {
7032                throw new IllegalArgumentException("File descriptors passed in options");
7033            }
7034        }
7035
7036        synchronized(this) {
7037            int callingUid = Binder.getCallingUid();
7038            int origUserId = userId;
7039            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7040                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7041                    ALLOW_NON_FULL, "getIntentSender", null);
7042            if (origUserId == UserHandle.USER_CURRENT) {
7043                // We don't want to evaluate this until the pending intent is
7044                // actually executed.  However, we do want to always do the
7045                // security checking for it above.
7046                userId = UserHandle.USER_CURRENT;
7047            }
7048            try {
7049                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7050                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7051                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7052                    if (!UserHandle.isSameApp(callingUid, uid)) {
7053                        String msg = "Permission Denial: getIntentSender() from pid="
7054                            + Binder.getCallingPid()
7055                            + ", uid=" + Binder.getCallingUid()
7056                            + ", (need uid=" + uid + ")"
7057                            + " is not allowed to send as package " + packageName;
7058                        Slog.w(TAG, msg);
7059                        throw new SecurityException(msg);
7060                    }
7061                }
7062
7063                return getIntentSenderLocked(type, packageName, callingUid, userId,
7064                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7065
7066            } catch (RemoteException e) {
7067                throw new SecurityException(e);
7068            }
7069        }
7070    }
7071
7072    IIntentSender getIntentSenderLocked(int type, String packageName,
7073            int callingUid, int userId, IBinder token, String resultWho,
7074            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7075            Bundle bOptions) {
7076        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7077        ActivityRecord activity = null;
7078        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7079            activity = ActivityRecord.isInStackLocked(token);
7080            if (activity == null) {
7081                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7082                return null;
7083            }
7084            if (activity.finishing) {
7085                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7086                return null;
7087            }
7088        }
7089
7090        // We're going to be splicing together extras before sending, so we're
7091        // okay poking into any contained extras.
7092        if (intents != null) {
7093            for (int i = 0; i < intents.length; i++) {
7094                intents[i].setDefusable(true);
7095            }
7096        }
7097        Bundle.setDefusable(bOptions, true);
7098
7099        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7100        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7101        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7102        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7103                |PendingIntent.FLAG_UPDATE_CURRENT);
7104
7105        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7106                type, packageName, activity, resultWho,
7107                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7108        WeakReference<PendingIntentRecord> ref;
7109        ref = mIntentSenderRecords.get(key);
7110        PendingIntentRecord rec = ref != null ? ref.get() : null;
7111        if (rec != null) {
7112            if (!cancelCurrent) {
7113                if (updateCurrent) {
7114                    if (rec.key.requestIntent != null) {
7115                        rec.key.requestIntent.replaceExtras(intents != null ?
7116                                intents[intents.length - 1] : null);
7117                    }
7118                    if (intents != null) {
7119                        intents[intents.length-1] = rec.key.requestIntent;
7120                        rec.key.allIntents = intents;
7121                        rec.key.allResolvedTypes = resolvedTypes;
7122                    } else {
7123                        rec.key.allIntents = null;
7124                        rec.key.allResolvedTypes = null;
7125                    }
7126                }
7127                return rec;
7128            }
7129            rec.canceled = true;
7130            mIntentSenderRecords.remove(key);
7131        }
7132        if (noCreate) {
7133            return rec;
7134        }
7135        rec = new PendingIntentRecord(this, key, callingUid);
7136        mIntentSenderRecords.put(key, rec.ref);
7137        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7138            if (activity.pendingResults == null) {
7139                activity.pendingResults
7140                        = new HashSet<WeakReference<PendingIntentRecord>>();
7141            }
7142            activity.pendingResults.add(rec.ref);
7143        }
7144        return rec;
7145    }
7146
7147    @Override
7148    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7149            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7150        if (target instanceof PendingIntentRecord) {
7151            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7152                    finishedReceiver, requiredPermission, options);
7153        } else {
7154            if (intent == null) {
7155                // Weird case: someone has given us their own custom IIntentSender, and now
7156                // they have someone else trying to send to it but of course this isn't
7157                // really a PendingIntent, so there is no base Intent, and the caller isn't
7158                // supplying an Intent... but we never want to dispatch a null Intent to
7159                // a receiver, so um...  let's make something up.
7160                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7161                intent = new Intent(Intent.ACTION_MAIN);
7162            }
7163            try {
7164                target.send(code, intent, resolvedType, null, requiredPermission, options);
7165            } catch (RemoteException e) {
7166            }
7167            // Platform code can rely on getting a result back when the send is done, but if
7168            // this intent sender is from outside of the system we can't rely on it doing that.
7169            // So instead we don't give it the result receiver, and instead just directly
7170            // report the finish immediately.
7171            if (finishedReceiver != null) {
7172                try {
7173                    finishedReceiver.performReceive(intent, 0,
7174                            null, null, false, false, UserHandle.getCallingUserId());
7175                } catch (RemoteException e) {
7176                }
7177            }
7178            return 0;
7179        }
7180    }
7181
7182    /**
7183     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7184     *
7185     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7186     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7187     */
7188    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7189        if (DEBUG_WHITELISTS) {
7190            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7191                    + targetUid + ", " + duration + ")");
7192        }
7193        synchronized (mPidsSelfLocked) {
7194            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7195            if (pr == null) {
7196                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7197                return;
7198            }
7199            if (!pr.whitelistManager) {
7200                if (DEBUG_WHITELISTS) {
7201                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7202                            + callerPid + " is not allowed");
7203                }
7204                return;
7205            }
7206        }
7207
7208        final long token = Binder.clearCallingIdentity();
7209        try {
7210            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7211                    true, "pe from uid:" + callerUid);
7212        } finally {
7213            Binder.restoreCallingIdentity(token);
7214        }
7215    }
7216
7217    @Override
7218    public void cancelIntentSender(IIntentSender sender) {
7219        if (!(sender instanceof PendingIntentRecord)) {
7220            return;
7221        }
7222        synchronized(this) {
7223            PendingIntentRecord rec = (PendingIntentRecord)sender;
7224            try {
7225                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7226                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7227                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7228                    String msg = "Permission Denial: cancelIntentSender() from pid="
7229                        + Binder.getCallingPid()
7230                        + ", uid=" + Binder.getCallingUid()
7231                        + " is not allowed to cancel packges "
7232                        + rec.key.packageName;
7233                    Slog.w(TAG, msg);
7234                    throw new SecurityException(msg);
7235                }
7236            } catch (RemoteException e) {
7237                throw new SecurityException(e);
7238            }
7239            cancelIntentSenderLocked(rec, true);
7240        }
7241    }
7242
7243    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7244        rec.canceled = true;
7245        mIntentSenderRecords.remove(rec.key);
7246        if (cleanActivity && rec.key.activity != null) {
7247            rec.key.activity.pendingResults.remove(rec.ref);
7248        }
7249    }
7250
7251    @Override
7252    public String getPackageForIntentSender(IIntentSender pendingResult) {
7253        if (!(pendingResult instanceof PendingIntentRecord)) {
7254            return null;
7255        }
7256        try {
7257            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7258            return res.key.packageName;
7259        } catch (ClassCastException e) {
7260        }
7261        return null;
7262    }
7263
7264    @Override
7265    public int getUidForIntentSender(IIntentSender sender) {
7266        if (sender instanceof PendingIntentRecord) {
7267            try {
7268                PendingIntentRecord res = (PendingIntentRecord)sender;
7269                return res.uid;
7270            } catch (ClassCastException e) {
7271            }
7272        }
7273        return -1;
7274    }
7275
7276    @Override
7277    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7278        if (!(pendingResult instanceof PendingIntentRecord)) {
7279            return false;
7280        }
7281        try {
7282            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7283            if (res.key.allIntents == null) {
7284                return false;
7285            }
7286            for (int i=0; i<res.key.allIntents.length; i++) {
7287                Intent intent = res.key.allIntents[i];
7288                if (intent.getPackage() != null && intent.getComponent() != null) {
7289                    return false;
7290                }
7291            }
7292            return true;
7293        } catch (ClassCastException e) {
7294        }
7295        return false;
7296    }
7297
7298    @Override
7299    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7300        if (!(pendingResult instanceof PendingIntentRecord)) {
7301            return false;
7302        }
7303        try {
7304            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7305            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7306                return true;
7307            }
7308            return false;
7309        } catch (ClassCastException e) {
7310        }
7311        return false;
7312    }
7313
7314    @Override
7315    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7316        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7317                "getIntentForIntentSender()");
7318        if (!(pendingResult instanceof PendingIntentRecord)) {
7319            return null;
7320        }
7321        try {
7322            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7323            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7324        } catch (ClassCastException e) {
7325        }
7326        return null;
7327    }
7328
7329    @Override
7330    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7331        if (!(pendingResult instanceof PendingIntentRecord)) {
7332            return null;
7333        }
7334        try {
7335            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7336            synchronized (this) {
7337                return getTagForIntentSenderLocked(res, prefix);
7338            }
7339        } catch (ClassCastException e) {
7340        }
7341        return null;
7342    }
7343
7344    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7345        final Intent intent = res.key.requestIntent;
7346        if (intent != null) {
7347            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7348                    || res.lastTagPrefix.equals(prefix))) {
7349                return res.lastTag;
7350            }
7351            res.lastTagPrefix = prefix;
7352            final StringBuilder sb = new StringBuilder(128);
7353            if (prefix != null) {
7354                sb.append(prefix);
7355            }
7356            if (intent.getAction() != null) {
7357                sb.append(intent.getAction());
7358            } else if (intent.getComponent() != null) {
7359                intent.getComponent().appendShortString(sb);
7360            } else {
7361                sb.append("?");
7362            }
7363            return res.lastTag = sb.toString();
7364        }
7365        return null;
7366    }
7367
7368    @Override
7369    public void setProcessLimit(int max) {
7370        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7371                "setProcessLimit()");
7372        synchronized (this) {
7373            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7374            mProcessLimitOverride = max;
7375        }
7376        trimApplications();
7377    }
7378
7379    @Override
7380    public int getProcessLimit() {
7381        synchronized (this) {
7382            return mProcessLimitOverride;
7383        }
7384    }
7385
7386    void foregroundTokenDied(ForegroundToken token) {
7387        synchronized (ActivityManagerService.this) {
7388            synchronized (mPidsSelfLocked) {
7389                ForegroundToken cur
7390                    = mForegroundProcesses.get(token.pid);
7391                if (cur != token) {
7392                    return;
7393                }
7394                mForegroundProcesses.remove(token.pid);
7395                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7396                if (pr == null) {
7397                    return;
7398                }
7399                pr.forcingToForeground = null;
7400                updateProcessForegroundLocked(pr, false, false);
7401            }
7402            updateOomAdjLocked();
7403        }
7404    }
7405
7406    @Override
7407    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7408        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7409                "setProcessForeground()");
7410        synchronized(this) {
7411            boolean changed = false;
7412
7413            synchronized (mPidsSelfLocked) {
7414                ProcessRecord pr = mPidsSelfLocked.get(pid);
7415                if (pr == null && isForeground) {
7416                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7417                    return;
7418                }
7419                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7420                if (oldToken != null) {
7421                    oldToken.token.unlinkToDeath(oldToken, 0);
7422                    mForegroundProcesses.remove(pid);
7423                    if (pr != null) {
7424                        pr.forcingToForeground = null;
7425                    }
7426                    changed = true;
7427                }
7428                if (isForeground && token != null) {
7429                    ForegroundToken newToken = new ForegroundToken() {
7430                        @Override
7431                        public void binderDied() {
7432                            foregroundTokenDied(this);
7433                        }
7434                    };
7435                    newToken.pid = pid;
7436                    newToken.token = token;
7437                    try {
7438                        token.linkToDeath(newToken, 0);
7439                        mForegroundProcesses.put(pid, newToken);
7440                        pr.forcingToForeground = token;
7441                        changed = true;
7442                    } catch (RemoteException e) {
7443                        // If the process died while doing this, we will later
7444                        // do the cleanup with the process death link.
7445                    }
7446                }
7447            }
7448
7449            if (changed) {
7450                updateOomAdjLocked();
7451            }
7452        }
7453    }
7454
7455    @Override
7456    public boolean isAppForeground(int uid) throws RemoteException {
7457        synchronized (this) {
7458            UidRecord uidRec = mActiveUids.get(uid);
7459            if (uidRec == null || uidRec.idle) {
7460                return false;
7461            }
7462            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7463        }
7464    }
7465
7466    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7467    // be guarded by permission checking.
7468    int getUidState(int uid) {
7469        synchronized (this) {
7470            UidRecord uidRec = mActiveUids.get(uid);
7471            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7472        }
7473    }
7474
7475    @Override
7476    public boolean isInMultiWindowMode(IBinder token) {
7477        final long origId = Binder.clearCallingIdentity();
7478        try {
7479            synchronized(this) {
7480                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7481                if (r == null) {
7482                    return false;
7483                }
7484                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7485                return !r.task.mFullscreen;
7486            }
7487        } finally {
7488            Binder.restoreCallingIdentity(origId);
7489        }
7490    }
7491
7492    @Override
7493    public boolean isInPictureInPictureMode(IBinder token) {
7494        final long origId = Binder.clearCallingIdentity();
7495        try {
7496            synchronized(this) {
7497                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7498                if (stack == null) {
7499                    return false;
7500                }
7501                return stack.mStackId == PINNED_STACK_ID;
7502            }
7503        } finally {
7504            Binder.restoreCallingIdentity(origId);
7505        }
7506    }
7507
7508    @Override
7509    public void enterPictureInPictureMode(IBinder token) {
7510        final long origId = Binder.clearCallingIdentity();
7511        try {
7512            synchronized(this) {
7513                if (!mSupportsPictureInPicture) {
7514                    throw new IllegalStateException("enterPictureInPictureMode: "
7515                            + "Device doesn't support picture-in-picture mode.");
7516                }
7517
7518                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7519
7520                if (r == null) {
7521                    throw new IllegalStateException("enterPictureInPictureMode: "
7522                            + "Can't find activity for token=" + token);
7523                }
7524
7525                if (!r.supportsPictureInPicture()) {
7526                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7527                            + "Picture-In-Picture not supported for r=" + r);
7528                }
7529
7530                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7531                // current bounds.
7532                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7533                final Rect bounds = (pinnedStack != null)
7534                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7535
7536                mStackSupervisor.moveActivityToPinnedStackLocked(
7537                        r, "enterPictureInPictureMode", bounds);
7538            }
7539        } finally {
7540            Binder.restoreCallingIdentity(origId);
7541        }
7542    }
7543
7544    // =========================================================
7545    // PROCESS INFO
7546    // =========================================================
7547
7548    static class ProcessInfoService extends IProcessInfoService.Stub {
7549        final ActivityManagerService mActivityManagerService;
7550        ProcessInfoService(ActivityManagerService activityManagerService) {
7551            mActivityManagerService = activityManagerService;
7552        }
7553
7554        @Override
7555        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7556            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7557                    /*in*/ pids, /*out*/ states, null);
7558        }
7559
7560        @Override
7561        public void getProcessStatesAndOomScoresFromPids(
7562                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7563            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7564                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7565        }
7566    }
7567
7568    /**
7569     * For each PID in the given input array, write the current process state
7570     * for that process into the states array, or -1 to indicate that no
7571     * process with the given PID exists. If scores array is provided, write
7572     * the oom score for the process into the scores array, with INVALID_ADJ
7573     * indicating the PID doesn't exist.
7574     */
7575    public void getProcessStatesAndOomScoresForPIDs(
7576            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7577        if (scores != null) {
7578            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7579                    "getProcessStatesAndOomScoresForPIDs()");
7580        }
7581
7582        if (pids == null) {
7583            throw new NullPointerException("pids");
7584        } else if (states == null) {
7585            throw new NullPointerException("states");
7586        } else if (pids.length != states.length) {
7587            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7588        } else if (scores != null && pids.length != scores.length) {
7589            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7590        }
7591
7592        synchronized (mPidsSelfLocked) {
7593            for (int i = 0; i < pids.length; i++) {
7594                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7595                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7596                        pr.curProcState;
7597                if (scores != null) {
7598                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7599                }
7600            }
7601        }
7602    }
7603
7604    // =========================================================
7605    // PERMISSIONS
7606    // =========================================================
7607
7608    static class PermissionController extends IPermissionController.Stub {
7609        ActivityManagerService mActivityManagerService;
7610        PermissionController(ActivityManagerService activityManagerService) {
7611            mActivityManagerService = activityManagerService;
7612        }
7613
7614        @Override
7615        public boolean checkPermission(String permission, int pid, int uid) {
7616            return mActivityManagerService.checkPermission(permission, pid,
7617                    uid) == PackageManager.PERMISSION_GRANTED;
7618        }
7619
7620        @Override
7621        public String[] getPackagesForUid(int uid) {
7622            return mActivityManagerService.mContext.getPackageManager()
7623                    .getPackagesForUid(uid);
7624        }
7625
7626        @Override
7627        public boolean isRuntimePermission(String permission) {
7628            try {
7629                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7630                        .getPermissionInfo(permission, 0);
7631                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7632            } catch (NameNotFoundException nnfe) {
7633                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7634            }
7635            return false;
7636        }
7637    }
7638
7639    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7640        @Override
7641        public int checkComponentPermission(String permission, int pid, int uid,
7642                int owningUid, boolean exported) {
7643            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7644                    owningUid, exported);
7645        }
7646
7647        @Override
7648        public Object getAMSLock() {
7649            return ActivityManagerService.this;
7650        }
7651    }
7652
7653    /**
7654     * This can be called with or without the global lock held.
7655     */
7656    int checkComponentPermission(String permission, int pid, int uid,
7657            int owningUid, boolean exported) {
7658        if (pid == MY_PID) {
7659            return PackageManager.PERMISSION_GRANTED;
7660        }
7661        return ActivityManager.checkComponentPermission(permission, uid,
7662                owningUid, exported);
7663    }
7664
7665    /**
7666     * As the only public entry point for permissions checking, this method
7667     * can enforce the semantic that requesting a check on a null global
7668     * permission is automatically denied.  (Internally a null permission
7669     * string is used when calling {@link #checkComponentPermission} in cases
7670     * when only uid-based security is needed.)
7671     *
7672     * This can be called with or without the global lock held.
7673     */
7674    @Override
7675    public int checkPermission(String permission, int pid, int uid) {
7676        if (permission == null) {
7677            return PackageManager.PERMISSION_DENIED;
7678        }
7679        return checkComponentPermission(permission, pid, uid, -1, true);
7680    }
7681
7682    @Override
7683    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7684        if (permission == null) {
7685            return PackageManager.PERMISSION_DENIED;
7686        }
7687
7688        // We might be performing an operation on behalf of an indirect binder
7689        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7690        // client identity accordingly before proceeding.
7691        Identity tlsIdentity = sCallerIdentity.get();
7692        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7693            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7694                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7695            uid = tlsIdentity.uid;
7696            pid = tlsIdentity.pid;
7697        }
7698
7699        return checkComponentPermission(permission, pid, uid, -1, true);
7700    }
7701
7702    /**
7703     * Binder IPC calls go through the public entry point.
7704     * This can be called with or without the global lock held.
7705     */
7706    int checkCallingPermission(String permission) {
7707        return checkPermission(permission,
7708                Binder.getCallingPid(),
7709                UserHandle.getAppId(Binder.getCallingUid()));
7710    }
7711
7712    /**
7713     * This can be called with or without the global lock held.
7714     */
7715    void enforceCallingPermission(String permission, String func) {
7716        if (checkCallingPermission(permission)
7717                == PackageManager.PERMISSION_GRANTED) {
7718            return;
7719        }
7720
7721        String msg = "Permission Denial: " + func + " from pid="
7722                + Binder.getCallingPid()
7723                + ", uid=" + Binder.getCallingUid()
7724                + " requires " + permission;
7725        Slog.w(TAG, msg);
7726        throw new SecurityException(msg);
7727    }
7728
7729    /**
7730     * Determine if UID is holding permissions required to access {@link Uri} in
7731     * the given {@link ProviderInfo}. Final permission checking is always done
7732     * in {@link ContentProvider}.
7733     */
7734    private final boolean checkHoldingPermissionsLocked(
7735            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7736        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7737                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7738        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7739            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7740                    != PERMISSION_GRANTED) {
7741                return false;
7742            }
7743        }
7744        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7745    }
7746
7747    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7748            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7749        if (pi.applicationInfo.uid == uid) {
7750            return true;
7751        } else if (!pi.exported) {
7752            return false;
7753        }
7754
7755        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7756        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7757        try {
7758            // check if target holds top-level <provider> permissions
7759            if (!readMet && pi.readPermission != null && considerUidPermissions
7760                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7761                readMet = true;
7762            }
7763            if (!writeMet && pi.writePermission != null && considerUidPermissions
7764                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7765                writeMet = true;
7766            }
7767
7768            // track if unprotected read/write is allowed; any denied
7769            // <path-permission> below removes this ability
7770            boolean allowDefaultRead = pi.readPermission == null;
7771            boolean allowDefaultWrite = pi.writePermission == null;
7772
7773            // check if target holds any <path-permission> that match uri
7774            final PathPermission[] pps = pi.pathPermissions;
7775            if (pps != null) {
7776                final String path = grantUri.uri.getPath();
7777                int i = pps.length;
7778                while (i > 0 && (!readMet || !writeMet)) {
7779                    i--;
7780                    PathPermission pp = pps[i];
7781                    if (pp.match(path)) {
7782                        if (!readMet) {
7783                            final String pprperm = pp.getReadPermission();
7784                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7785                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7786                                    + ": match=" + pp.match(path)
7787                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7788                            if (pprperm != null) {
7789                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7790                                        == PERMISSION_GRANTED) {
7791                                    readMet = true;
7792                                } else {
7793                                    allowDefaultRead = false;
7794                                }
7795                            }
7796                        }
7797                        if (!writeMet) {
7798                            final String ppwperm = pp.getWritePermission();
7799                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7800                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7801                                    + ": match=" + pp.match(path)
7802                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7803                            if (ppwperm != null) {
7804                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7805                                        == PERMISSION_GRANTED) {
7806                                    writeMet = true;
7807                                } else {
7808                                    allowDefaultWrite = false;
7809                                }
7810                            }
7811                        }
7812                    }
7813                }
7814            }
7815
7816            // grant unprotected <provider> read/write, if not blocked by
7817            // <path-permission> above
7818            if (allowDefaultRead) readMet = true;
7819            if (allowDefaultWrite) writeMet = true;
7820
7821        } catch (RemoteException e) {
7822            return false;
7823        }
7824
7825        return readMet && writeMet;
7826    }
7827
7828    public int getAppStartMode(int uid, String packageName) {
7829        synchronized (this) {
7830            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7831        }
7832    }
7833
7834    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7835            boolean allowWhenForeground) {
7836        UidRecord uidRec = mActiveUids.get(uid);
7837        if (!mLenientBackgroundCheck) {
7838            if (!allowWhenForeground || uidRec == null
7839                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7840                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7841                        packageName) != AppOpsManager.MODE_ALLOWED) {
7842                    return ActivityManager.APP_START_MODE_DELAYED;
7843                }
7844            }
7845
7846        } else if (uidRec == null || uidRec.idle) {
7847            if (callingPid >= 0) {
7848                ProcessRecord proc;
7849                synchronized (mPidsSelfLocked) {
7850                    proc = mPidsSelfLocked.get(callingPid);
7851                }
7852                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7853                    // Whoever is instigating this is in the foreground, so we will allow it
7854                    // to go through.
7855                    return ActivityManager.APP_START_MODE_NORMAL;
7856                }
7857            }
7858            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7859                    != AppOpsManager.MODE_ALLOWED) {
7860                return ActivityManager.APP_START_MODE_DELAYED;
7861            }
7862        }
7863        return ActivityManager.APP_START_MODE_NORMAL;
7864    }
7865
7866    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7867        ProviderInfo pi = null;
7868        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7869        if (cpr != null) {
7870            pi = cpr.info;
7871        } else {
7872            try {
7873                pi = AppGlobals.getPackageManager().resolveContentProvider(
7874                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7875                        userHandle);
7876            } catch (RemoteException ex) {
7877            }
7878        }
7879        return pi;
7880    }
7881
7882    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7883        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7884        if (targetUris != null) {
7885            return targetUris.get(grantUri);
7886        }
7887        return null;
7888    }
7889
7890    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7891            String targetPkg, int targetUid, GrantUri grantUri) {
7892        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7893        if (targetUris == null) {
7894            targetUris = Maps.newArrayMap();
7895            mGrantedUriPermissions.put(targetUid, targetUris);
7896        }
7897
7898        UriPermission perm = targetUris.get(grantUri);
7899        if (perm == null) {
7900            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7901            targetUris.put(grantUri, perm);
7902        }
7903
7904        return perm;
7905    }
7906
7907    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7908            final int modeFlags) {
7909        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7910        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7911                : UriPermission.STRENGTH_OWNED;
7912
7913        // Root gets to do everything.
7914        if (uid == 0) {
7915            return true;
7916        }
7917
7918        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7919        if (perms == null) return false;
7920
7921        // First look for exact match
7922        final UriPermission exactPerm = perms.get(grantUri);
7923        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7924            return true;
7925        }
7926
7927        // No exact match, look for prefixes
7928        final int N = perms.size();
7929        for (int i = 0; i < N; i++) {
7930            final UriPermission perm = perms.valueAt(i);
7931            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7932                    && perm.getStrength(modeFlags) >= minStrength) {
7933                return true;
7934            }
7935        }
7936
7937        return false;
7938    }
7939
7940    /**
7941     * @param uri This uri must NOT contain an embedded userId.
7942     * @param userId The userId in which the uri is to be resolved.
7943     */
7944    @Override
7945    public int checkUriPermission(Uri uri, int pid, int uid,
7946            final int modeFlags, int userId, IBinder callerToken) {
7947        enforceNotIsolatedCaller("checkUriPermission");
7948
7949        // Another redirected-binder-call permissions check as in
7950        // {@link checkPermissionWithToken}.
7951        Identity tlsIdentity = sCallerIdentity.get();
7952        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7953            uid = tlsIdentity.uid;
7954            pid = tlsIdentity.pid;
7955        }
7956
7957        // Our own process gets to do everything.
7958        if (pid == MY_PID) {
7959            return PackageManager.PERMISSION_GRANTED;
7960        }
7961        synchronized (this) {
7962            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7963                    ? PackageManager.PERMISSION_GRANTED
7964                    : PackageManager.PERMISSION_DENIED;
7965        }
7966    }
7967
7968    /**
7969     * Check if the targetPkg can be granted permission to access uri by
7970     * the callingUid using the given modeFlags.  Throws a security exception
7971     * if callingUid is not allowed to do this.  Returns the uid of the target
7972     * if the URI permission grant should be performed; returns -1 if it is not
7973     * needed (for example targetPkg already has permission to access the URI).
7974     * If you already know the uid of the target, you can supply it in
7975     * lastTargetUid else set that to -1.
7976     */
7977    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7978            final int modeFlags, int lastTargetUid) {
7979        if (!Intent.isAccessUriMode(modeFlags)) {
7980            return -1;
7981        }
7982
7983        if (targetPkg != null) {
7984            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7985                    "Checking grant " + targetPkg + " permission to " + grantUri);
7986        }
7987
7988        final IPackageManager pm = AppGlobals.getPackageManager();
7989
7990        // If this is not a content: uri, we can't do anything with it.
7991        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7992            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7993                    "Can't grant URI permission for non-content URI: " + grantUri);
7994            return -1;
7995        }
7996
7997        final String authority = grantUri.uri.getAuthority();
7998        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
7999                MATCH_DEBUG_TRIAGED_MISSING);
8000        if (pi == null) {
8001            Slog.w(TAG, "No content provider found for permission check: " +
8002                    grantUri.uri.toSafeString());
8003            return -1;
8004        }
8005
8006        int targetUid = lastTargetUid;
8007        if (targetUid < 0 && targetPkg != null) {
8008            try {
8009                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8010                        UserHandle.getUserId(callingUid));
8011                if (targetUid < 0) {
8012                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8013                            "Can't grant URI permission no uid for: " + targetPkg);
8014                    return -1;
8015                }
8016            } catch (RemoteException ex) {
8017                return -1;
8018            }
8019        }
8020
8021        if (targetUid >= 0) {
8022            // First...  does the target actually need this permission?
8023            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8024                // No need to grant the target this permission.
8025                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8026                        "Target " + targetPkg + " already has full permission to " + grantUri);
8027                return -1;
8028            }
8029        } else {
8030            // First...  there is no target package, so can anyone access it?
8031            boolean allowed = pi.exported;
8032            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8033                if (pi.readPermission != null) {
8034                    allowed = false;
8035                }
8036            }
8037            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8038                if (pi.writePermission != null) {
8039                    allowed = false;
8040                }
8041            }
8042            if (allowed) {
8043                return -1;
8044            }
8045        }
8046
8047        /* There is a special cross user grant if:
8048         * - The target is on another user.
8049         * - Apps on the current user can access the uri without any uid permissions.
8050         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8051         * grant uri permissions.
8052         */
8053        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8054                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8055                modeFlags, false /*without considering the uid permissions*/);
8056
8057        // Second...  is the provider allowing granting of URI permissions?
8058        if (!specialCrossUserGrant) {
8059            if (!pi.grantUriPermissions) {
8060                throw new SecurityException("Provider " + pi.packageName
8061                        + "/" + pi.name
8062                        + " does not allow granting of Uri permissions (uri "
8063                        + grantUri + ")");
8064            }
8065            if (pi.uriPermissionPatterns != null) {
8066                final int N = pi.uriPermissionPatterns.length;
8067                boolean allowed = false;
8068                for (int i=0; i<N; i++) {
8069                    if (pi.uriPermissionPatterns[i] != null
8070                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8071                        allowed = true;
8072                        break;
8073                    }
8074                }
8075                if (!allowed) {
8076                    throw new SecurityException("Provider " + pi.packageName
8077                            + "/" + pi.name
8078                            + " does not allow granting of permission to path of Uri "
8079                            + grantUri);
8080                }
8081            }
8082        }
8083
8084        // Third...  does the caller itself have permission to access
8085        // this uri?
8086        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8087            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8088                // Require they hold a strong enough Uri permission
8089                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8090                    throw new SecurityException("Uid " + callingUid
8091                            + " does not have permission to uri " + grantUri);
8092                }
8093            }
8094        }
8095        return targetUid;
8096    }
8097
8098    /**
8099     * @param uri This uri must NOT contain an embedded userId.
8100     * @param userId The userId in which the uri is to be resolved.
8101     */
8102    @Override
8103    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8104            final int modeFlags, int userId) {
8105        enforceNotIsolatedCaller("checkGrantUriPermission");
8106        synchronized(this) {
8107            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8108                    new GrantUri(userId, uri, false), modeFlags, -1);
8109        }
8110    }
8111
8112    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8113            final int modeFlags, UriPermissionOwner owner) {
8114        if (!Intent.isAccessUriMode(modeFlags)) {
8115            return;
8116        }
8117
8118        // So here we are: the caller has the assumed permission
8119        // to the uri, and the target doesn't.  Let's now give this to
8120        // the target.
8121
8122        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8123                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8124
8125        final String authority = grantUri.uri.getAuthority();
8126        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8127                MATCH_DEBUG_TRIAGED_MISSING);
8128        if (pi == null) {
8129            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8130            return;
8131        }
8132
8133        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8134            grantUri.prefix = true;
8135        }
8136        final UriPermission perm = findOrCreateUriPermissionLocked(
8137                pi.packageName, targetPkg, targetUid, grantUri);
8138        perm.grantModes(modeFlags, owner);
8139    }
8140
8141    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8142            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8143        if (targetPkg == null) {
8144            throw new NullPointerException("targetPkg");
8145        }
8146        int targetUid;
8147        final IPackageManager pm = AppGlobals.getPackageManager();
8148        try {
8149            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8150        } catch (RemoteException ex) {
8151            return;
8152        }
8153
8154        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8155                targetUid);
8156        if (targetUid < 0) {
8157            return;
8158        }
8159
8160        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8161                owner);
8162    }
8163
8164    static class NeededUriGrants extends ArrayList<GrantUri> {
8165        final String targetPkg;
8166        final int targetUid;
8167        final int flags;
8168
8169        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8170            this.targetPkg = targetPkg;
8171            this.targetUid = targetUid;
8172            this.flags = flags;
8173        }
8174    }
8175
8176    /**
8177     * Like checkGrantUriPermissionLocked, but takes an Intent.
8178     */
8179    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8180            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8181        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8182                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8183                + " clip=" + (intent != null ? intent.getClipData() : null)
8184                + " from " + intent + "; flags=0x"
8185                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8186
8187        if (targetPkg == null) {
8188            throw new NullPointerException("targetPkg");
8189        }
8190
8191        if (intent == null) {
8192            return null;
8193        }
8194        Uri data = intent.getData();
8195        ClipData clip = intent.getClipData();
8196        if (data == null && clip == null) {
8197            return null;
8198        }
8199        // Default userId for uris in the intent (if they don't specify it themselves)
8200        int contentUserHint = intent.getContentUserHint();
8201        if (contentUserHint == UserHandle.USER_CURRENT) {
8202            contentUserHint = UserHandle.getUserId(callingUid);
8203        }
8204        final IPackageManager pm = AppGlobals.getPackageManager();
8205        int targetUid;
8206        if (needed != null) {
8207            targetUid = needed.targetUid;
8208        } else {
8209            try {
8210                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8211                        targetUserId);
8212            } catch (RemoteException ex) {
8213                return null;
8214            }
8215            if (targetUid < 0) {
8216                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8217                        "Can't grant URI permission no uid for: " + targetPkg
8218                        + " on user " + targetUserId);
8219                return null;
8220            }
8221        }
8222        if (data != null) {
8223            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8224            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8225                    targetUid);
8226            if (targetUid > 0) {
8227                if (needed == null) {
8228                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8229                }
8230                needed.add(grantUri);
8231            }
8232        }
8233        if (clip != null) {
8234            for (int i=0; i<clip.getItemCount(); i++) {
8235                Uri uri = clip.getItemAt(i).getUri();
8236                if (uri != null) {
8237                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8238                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8239                            targetUid);
8240                    if (targetUid > 0) {
8241                        if (needed == null) {
8242                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8243                        }
8244                        needed.add(grantUri);
8245                    }
8246                } else {
8247                    Intent clipIntent = clip.getItemAt(i).getIntent();
8248                    if (clipIntent != null) {
8249                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8250                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8251                        if (newNeeded != null) {
8252                            needed = newNeeded;
8253                        }
8254                    }
8255                }
8256            }
8257        }
8258
8259        return needed;
8260    }
8261
8262    /**
8263     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8264     */
8265    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8266            UriPermissionOwner owner) {
8267        if (needed != null) {
8268            for (int i=0; i<needed.size(); i++) {
8269                GrantUri grantUri = needed.get(i);
8270                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8271                        grantUri, needed.flags, owner);
8272            }
8273        }
8274    }
8275
8276    void grantUriPermissionFromIntentLocked(int callingUid,
8277            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8278        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8279                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8280        if (needed == null) {
8281            return;
8282        }
8283
8284        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8285    }
8286
8287    /**
8288     * @param uri This uri must NOT contain an embedded userId.
8289     * @param userId The userId in which the uri is to be resolved.
8290     */
8291    @Override
8292    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8293            final int modeFlags, int userId) {
8294        enforceNotIsolatedCaller("grantUriPermission");
8295        GrantUri grantUri = new GrantUri(userId, uri, false);
8296        synchronized(this) {
8297            final ProcessRecord r = getRecordForAppLocked(caller);
8298            if (r == null) {
8299                throw new SecurityException("Unable to find app for caller "
8300                        + caller
8301                        + " when granting permission to uri " + grantUri);
8302            }
8303            if (targetPkg == null) {
8304                throw new IllegalArgumentException("null target");
8305            }
8306            if (grantUri == null) {
8307                throw new IllegalArgumentException("null uri");
8308            }
8309
8310            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8311                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8312                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8313                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8314
8315            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8316                    UserHandle.getUserId(r.uid));
8317        }
8318    }
8319
8320    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8321        if (perm.modeFlags == 0) {
8322            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8323                    perm.targetUid);
8324            if (perms != null) {
8325                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8326                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8327
8328                perms.remove(perm.uri);
8329                if (perms.isEmpty()) {
8330                    mGrantedUriPermissions.remove(perm.targetUid);
8331                }
8332            }
8333        }
8334    }
8335
8336    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8337        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8338                "Revoking all granted permissions to " + grantUri);
8339
8340        final IPackageManager pm = AppGlobals.getPackageManager();
8341        final String authority = grantUri.uri.getAuthority();
8342        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8343                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8344        if (pi == null) {
8345            Slog.w(TAG, "No content provider found for permission revoke: "
8346                    + grantUri.toSafeString());
8347            return;
8348        }
8349
8350        // Does the caller have this permission on the URI?
8351        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8352            // If they don't have direct access to the URI, then revoke any
8353            // ownerless URI permissions that have been granted to them.
8354            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8355            if (perms != null) {
8356                boolean persistChanged = false;
8357                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8358                    final UriPermission perm = it.next();
8359                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8360                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8361                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8362                                "Revoking non-owned " + perm.targetUid
8363                                + " permission to " + perm.uri);
8364                        persistChanged |= perm.revokeModes(
8365                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8366                        if (perm.modeFlags == 0) {
8367                            it.remove();
8368                        }
8369                    }
8370                }
8371                if (perms.isEmpty()) {
8372                    mGrantedUriPermissions.remove(callingUid);
8373                }
8374                if (persistChanged) {
8375                    schedulePersistUriGrants();
8376                }
8377            }
8378            return;
8379        }
8380
8381        boolean persistChanged = false;
8382
8383        // Go through all of the permissions and remove any that match.
8384        int N = mGrantedUriPermissions.size();
8385        for (int i = 0; i < N; i++) {
8386            final int targetUid = mGrantedUriPermissions.keyAt(i);
8387            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8388
8389            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8390                final UriPermission perm = it.next();
8391                if (perm.uri.sourceUserId == grantUri.sourceUserId
8392                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8393                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8394                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8395                    persistChanged |= perm.revokeModes(
8396                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8397                    if (perm.modeFlags == 0) {
8398                        it.remove();
8399                    }
8400                }
8401            }
8402
8403            if (perms.isEmpty()) {
8404                mGrantedUriPermissions.remove(targetUid);
8405                N--;
8406                i--;
8407            }
8408        }
8409
8410        if (persistChanged) {
8411            schedulePersistUriGrants();
8412        }
8413    }
8414
8415    /**
8416     * @param uri This uri must NOT contain an embedded userId.
8417     * @param userId The userId in which the uri is to be resolved.
8418     */
8419    @Override
8420    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8421            int userId) {
8422        enforceNotIsolatedCaller("revokeUriPermission");
8423        synchronized(this) {
8424            final ProcessRecord r = getRecordForAppLocked(caller);
8425            if (r == null) {
8426                throw new SecurityException("Unable to find app for caller "
8427                        + caller
8428                        + " when revoking permission to uri " + uri);
8429            }
8430            if (uri == null) {
8431                Slog.w(TAG, "revokeUriPermission: null uri");
8432                return;
8433            }
8434
8435            if (!Intent.isAccessUriMode(modeFlags)) {
8436                return;
8437            }
8438
8439            final String authority = uri.getAuthority();
8440            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8441                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8442            if (pi == null) {
8443                Slog.w(TAG, "No content provider found for permission revoke: "
8444                        + uri.toSafeString());
8445                return;
8446            }
8447
8448            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8449        }
8450    }
8451
8452    /**
8453     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8454     * given package.
8455     *
8456     * @param packageName Package name to match, or {@code null} to apply to all
8457     *            packages.
8458     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8459     *            to all users.
8460     * @param persistable If persistable grants should be removed.
8461     */
8462    private void removeUriPermissionsForPackageLocked(
8463            String packageName, int userHandle, boolean persistable) {
8464        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8465            throw new IllegalArgumentException("Must narrow by either package or user");
8466        }
8467
8468        boolean persistChanged = false;
8469
8470        int N = mGrantedUriPermissions.size();
8471        for (int i = 0; i < N; i++) {
8472            final int targetUid = mGrantedUriPermissions.keyAt(i);
8473            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8474
8475            // Only inspect grants matching user
8476            if (userHandle == UserHandle.USER_ALL
8477                    || userHandle == UserHandle.getUserId(targetUid)) {
8478                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8479                    final UriPermission perm = it.next();
8480
8481                    // Only inspect grants matching package
8482                    if (packageName == null || perm.sourcePkg.equals(packageName)
8483                            || perm.targetPkg.equals(packageName)) {
8484                        persistChanged |= perm.revokeModes(persistable
8485                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8486
8487                        // Only remove when no modes remain; any persisted grants
8488                        // will keep this alive.
8489                        if (perm.modeFlags == 0) {
8490                            it.remove();
8491                        }
8492                    }
8493                }
8494
8495                if (perms.isEmpty()) {
8496                    mGrantedUriPermissions.remove(targetUid);
8497                    N--;
8498                    i--;
8499                }
8500            }
8501        }
8502
8503        if (persistChanged) {
8504            schedulePersistUriGrants();
8505        }
8506    }
8507
8508    @Override
8509    public IBinder newUriPermissionOwner(String name) {
8510        enforceNotIsolatedCaller("newUriPermissionOwner");
8511        synchronized(this) {
8512            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8513            return owner.getExternalTokenLocked();
8514        }
8515    }
8516
8517    @Override
8518    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8519        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8520        synchronized(this) {
8521            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8522            if (r == null) {
8523                throw new IllegalArgumentException("Activity does not exist; token="
8524                        + activityToken);
8525            }
8526            return r.getUriPermissionsLocked().getExternalTokenLocked();
8527        }
8528    }
8529    /**
8530     * @param uri This uri must NOT contain an embedded userId.
8531     * @param sourceUserId The userId in which the uri is to be resolved.
8532     * @param targetUserId The userId of the app that receives the grant.
8533     */
8534    @Override
8535    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8536            final int modeFlags, int sourceUserId, int targetUserId) {
8537        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8538                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8539                "grantUriPermissionFromOwner", null);
8540        synchronized(this) {
8541            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8542            if (owner == null) {
8543                throw new IllegalArgumentException("Unknown owner: " + token);
8544            }
8545            if (fromUid != Binder.getCallingUid()) {
8546                if (Binder.getCallingUid() != Process.myUid()) {
8547                    // Only system code can grant URI permissions on behalf
8548                    // of other users.
8549                    throw new SecurityException("nice try");
8550                }
8551            }
8552            if (targetPkg == null) {
8553                throw new IllegalArgumentException("null target");
8554            }
8555            if (uri == null) {
8556                throw new IllegalArgumentException("null uri");
8557            }
8558
8559            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8560                    modeFlags, owner, targetUserId);
8561        }
8562    }
8563
8564    /**
8565     * @param uri This uri must NOT contain an embedded userId.
8566     * @param userId The userId in which the uri is to be resolved.
8567     */
8568    @Override
8569    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8570        synchronized(this) {
8571            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8572            if (owner == null) {
8573                throw new IllegalArgumentException("Unknown owner: " + token);
8574            }
8575
8576            if (uri == null) {
8577                owner.removeUriPermissionsLocked(mode);
8578            } else {
8579                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8580            }
8581        }
8582    }
8583
8584    private void schedulePersistUriGrants() {
8585        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8586            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8587                    10 * DateUtils.SECOND_IN_MILLIS);
8588        }
8589    }
8590
8591    private void writeGrantedUriPermissions() {
8592        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8593
8594        // Snapshot permissions so we can persist without lock
8595        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8596        synchronized (this) {
8597            final int size = mGrantedUriPermissions.size();
8598            for (int i = 0; i < size; i++) {
8599                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8600                for (UriPermission perm : perms.values()) {
8601                    if (perm.persistedModeFlags != 0) {
8602                        persist.add(perm.snapshot());
8603                    }
8604                }
8605            }
8606        }
8607
8608        FileOutputStream fos = null;
8609        try {
8610            fos = mGrantFile.startWrite();
8611
8612            XmlSerializer out = new FastXmlSerializer();
8613            out.setOutput(fos, StandardCharsets.UTF_8.name());
8614            out.startDocument(null, true);
8615            out.startTag(null, TAG_URI_GRANTS);
8616            for (UriPermission.Snapshot perm : persist) {
8617                out.startTag(null, TAG_URI_GRANT);
8618                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8619                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8620                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8621                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8622                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8623                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8624                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8625                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8626                out.endTag(null, TAG_URI_GRANT);
8627            }
8628            out.endTag(null, TAG_URI_GRANTS);
8629            out.endDocument();
8630
8631            mGrantFile.finishWrite(fos);
8632        } catch (IOException e) {
8633            if (fos != null) {
8634                mGrantFile.failWrite(fos);
8635            }
8636        }
8637    }
8638
8639    private void readGrantedUriPermissionsLocked() {
8640        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8641
8642        final long now = System.currentTimeMillis();
8643
8644        FileInputStream fis = null;
8645        try {
8646            fis = mGrantFile.openRead();
8647            final XmlPullParser in = Xml.newPullParser();
8648            in.setInput(fis, StandardCharsets.UTF_8.name());
8649
8650            int type;
8651            while ((type = in.next()) != END_DOCUMENT) {
8652                final String tag = in.getName();
8653                if (type == START_TAG) {
8654                    if (TAG_URI_GRANT.equals(tag)) {
8655                        final int sourceUserId;
8656                        final int targetUserId;
8657                        final int userHandle = readIntAttribute(in,
8658                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8659                        if (userHandle != UserHandle.USER_NULL) {
8660                            // For backwards compatibility.
8661                            sourceUserId = userHandle;
8662                            targetUserId = userHandle;
8663                        } else {
8664                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8665                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8666                        }
8667                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8668                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8669                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8670                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8671                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8672                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8673
8674                        // Sanity check that provider still belongs to source package
8675                        // Both direct boot aware and unaware packages are fine as we
8676                        // will do filtering at query time to avoid multiple parsing.
8677                        final ProviderInfo pi = getProviderInfoLocked(
8678                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8679                                        | MATCH_DIRECT_BOOT_UNAWARE);
8680                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8681                            int targetUid = -1;
8682                            try {
8683                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8684                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8685                            } catch (RemoteException e) {
8686                            }
8687                            if (targetUid != -1) {
8688                                final UriPermission perm = findOrCreateUriPermissionLocked(
8689                                        sourcePkg, targetPkg, targetUid,
8690                                        new GrantUri(sourceUserId, uri, prefix));
8691                                perm.initPersistedModes(modeFlags, createdTime);
8692                            }
8693                        } else {
8694                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8695                                    + " but instead found " + pi);
8696                        }
8697                    }
8698                }
8699            }
8700        } catch (FileNotFoundException e) {
8701            // Missing grants is okay
8702        } catch (IOException e) {
8703            Slog.wtf(TAG, "Failed reading Uri grants", e);
8704        } catch (XmlPullParserException e) {
8705            Slog.wtf(TAG, "Failed reading Uri grants", e);
8706        } finally {
8707            IoUtils.closeQuietly(fis);
8708        }
8709    }
8710
8711    /**
8712     * @param uri This uri must NOT contain an embedded userId.
8713     * @param userId The userId in which the uri is to be resolved.
8714     */
8715    @Override
8716    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8717        enforceNotIsolatedCaller("takePersistableUriPermission");
8718
8719        Preconditions.checkFlagsArgument(modeFlags,
8720                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8721
8722        synchronized (this) {
8723            final int callingUid = Binder.getCallingUid();
8724            boolean persistChanged = false;
8725            GrantUri grantUri = new GrantUri(userId, uri, false);
8726
8727            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8728                    new GrantUri(userId, uri, false));
8729            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8730                    new GrantUri(userId, uri, true));
8731
8732            final boolean exactValid = (exactPerm != null)
8733                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8734            final boolean prefixValid = (prefixPerm != null)
8735                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8736
8737            if (!(exactValid || prefixValid)) {
8738                throw new SecurityException("No persistable permission grants found for UID "
8739                        + callingUid + " and Uri " + grantUri.toSafeString());
8740            }
8741
8742            if (exactValid) {
8743                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8744            }
8745            if (prefixValid) {
8746                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8747            }
8748
8749            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8750
8751            if (persistChanged) {
8752                schedulePersistUriGrants();
8753            }
8754        }
8755    }
8756
8757    /**
8758     * @param uri This uri must NOT contain an embedded userId.
8759     * @param userId The userId in which the uri is to be resolved.
8760     */
8761    @Override
8762    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8763        enforceNotIsolatedCaller("releasePersistableUriPermission");
8764
8765        Preconditions.checkFlagsArgument(modeFlags,
8766                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8767
8768        synchronized (this) {
8769            final int callingUid = Binder.getCallingUid();
8770            boolean persistChanged = false;
8771
8772            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8773                    new GrantUri(userId, uri, false));
8774            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8775                    new GrantUri(userId, uri, true));
8776            if (exactPerm == null && prefixPerm == null) {
8777                throw new SecurityException("No permission grants found for UID " + callingUid
8778                        + " and Uri " + uri.toSafeString());
8779            }
8780
8781            if (exactPerm != null) {
8782                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8783                removeUriPermissionIfNeededLocked(exactPerm);
8784            }
8785            if (prefixPerm != null) {
8786                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8787                removeUriPermissionIfNeededLocked(prefixPerm);
8788            }
8789
8790            if (persistChanged) {
8791                schedulePersistUriGrants();
8792            }
8793        }
8794    }
8795
8796    /**
8797     * Prune any older {@link UriPermission} for the given UID until outstanding
8798     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8799     *
8800     * @return if any mutations occured that require persisting.
8801     */
8802    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8803        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8804        if (perms == null) return false;
8805        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8806
8807        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8808        for (UriPermission perm : perms.values()) {
8809            if (perm.persistedModeFlags != 0) {
8810                persisted.add(perm);
8811            }
8812        }
8813
8814        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8815        if (trimCount <= 0) return false;
8816
8817        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8818        for (int i = 0; i < trimCount; i++) {
8819            final UriPermission perm = persisted.get(i);
8820
8821            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8822                    "Trimming grant created at " + perm.persistedCreateTime);
8823
8824            perm.releasePersistableModes(~0);
8825            removeUriPermissionIfNeededLocked(perm);
8826        }
8827
8828        return true;
8829    }
8830
8831    @Override
8832    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8833            String packageName, boolean incoming) {
8834        enforceNotIsolatedCaller("getPersistedUriPermissions");
8835        Preconditions.checkNotNull(packageName, "packageName");
8836
8837        final int callingUid = Binder.getCallingUid();
8838        final int callingUserId = UserHandle.getUserId(callingUid);
8839        final IPackageManager pm = AppGlobals.getPackageManager();
8840        try {
8841            final int packageUid = pm.getPackageUid(packageName,
8842                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8843            if (packageUid != callingUid) {
8844                throw new SecurityException(
8845                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8846            }
8847        } catch (RemoteException e) {
8848            throw new SecurityException("Failed to verify package name ownership");
8849        }
8850
8851        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8852        synchronized (this) {
8853            if (incoming) {
8854                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8855                        callingUid);
8856                if (perms == null) {
8857                    Slog.w(TAG, "No permission grants found for " + packageName);
8858                } else {
8859                    for (UriPermission perm : perms.values()) {
8860                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8861                            result.add(perm.buildPersistedPublicApiObject());
8862                        }
8863                    }
8864                }
8865            } else {
8866                final int size = mGrantedUriPermissions.size();
8867                for (int i = 0; i < size; i++) {
8868                    final ArrayMap<GrantUri, UriPermission> perms =
8869                            mGrantedUriPermissions.valueAt(i);
8870                    for (UriPermission perm : perms.values()) {
8871                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8872                            result.add(perm.buildPersistedPublicApiObject());
8873                        }
8874                    }
8875                }
8876            }
8877        }
8878        return new ParceledListSlice<android.content.UriPermission>(result);
8879    }
8880
8881    @Override
8882    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8883            String packageName, int userId) {
8884        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8885                "getGrantedUriPermissions");
8886
8887        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8888        synchronized (this) {
8889            final int size = mGrantedUriPermissions.size();
8890            for (int i = 0; i < size; i++) {
8891                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8892                for (UriPermission perm : perms.values()) {
8893                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8894                            && perm.persistedModeFlags != 0) {
8895                        result.add(perm.buildPersistedPublicApiObject());
8896                    }
8897                }
8898            }
8899        }
8900        return new ParceledListSlice<android.content.UriPermission>(result);
8901    }
8902
8903    @Override
8904    public void clearGrantedUriPermissions(String packageName, int userId) {
8905        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8906                "clearGrantedUriPermissions");
8907        removeUriPermissionsForPackageLocked(packageName, userId, true);
8908    }
8909
8910    @Override
8911    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8912        synchronized (this) {
8913            ProcessRecord app =
8914                who != null ? getRecordForAppLocked(who) : null;
8915            if (app == null) return;
8916
8917            Message msg = Message.obtain();
8918            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8919            msg.obj = app;
8920            msg.arg1 = waiting ? 1 : 0;
8921            mUiHandler.sendMessage(msg);
8922        }
8923    }
8924
8925    @Override
8926    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8927        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8928        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8929        outInfo.availMem = Process.getFreeMemory();
8930        outInfo.totalMem = Process.getTotalMemory();
8931        outInfo.threshold = homeAppMem;
8932        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8933        outInfo.hiddenAppThreshold = cachedAppMem;
8934        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8935                ProcessList.SERVICE_ADJ);
8936        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8937                ProcessList.VISIBLE_APP_ADJ);
8938        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8939                ProcessList.FOREGROUND_APP_ADJ);
8940    }
8941
8942    // =========================================================
8943    // TASK MANAGEMENT
8944    // =========================================================
8945
8946    @Override
8947    public List<IAppTask> getAppTasks(String callingPackage) {
8948        int callingUid = Binder.getCallingUid();
8949        long ident = Binder.clearCallingIdentity();
8950
8951        synchronized(this) {
8952            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8953            try {
8954                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8955
8956                final int N = mRecentTasks.size();
8957                for (int i = 0; i < N; i++) {
8958                    TaskRecord tr = mRecentTasks.get(i);
8959                    // Skip tasks that do not match the caller.  We don't need to verify
8960                    // callingPackage, because we are also limiting to callingUid and know
8961                    // that will limit to the correct security sandbox.
8962                    if (tr.effectiveUid != callingUid) {
8963                        continue;
8964                    }
8965                    Intent intent = tr.getBaseIntent();
8966                    if (intent == null ||
8967                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8968                        continue;
8969                    }
8970                    ActivityManager.RecentTaskInfo taskInfo =
8971                            createRecentTaskInfoFromTaskRecord(tr);
8972                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8973                    list.add(taskImpl);
8974                }
8975            } finally {
8976                Binder.restoreCallingIdentity(ident);
8977            }
8978            return list;
8979        }
8980    }
8981
8982    @Override
8983    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8984        final int callingUid = Binder.getCallingUid();
8985        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8986
8987        synchronized(this) {
8988            if (DEBUG_ALL) Slog.v(
8989                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8990
8991            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8992                    callingUid);
8993
8994            // TODO: Improve with MRU list from all ActivityStacks.
8995            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8996        }
8997
8998        return list;
8999    }
9000
9001    /**
9002     * Creates a new RecentTaskInfo from a TaskRecord.
9003     */
9004    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9005        // Update the task description to reflect any changes in the task stack
9006        tr.updateTaskDescription();
9007
9008        // Compose the recent task info
9009        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9010        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9011        rti.persistentId = tr.taskId;
9012        rti.baseIntent = new Intent(tr.getBaseIntent());
9013        rti.origActivity = tr.origActivity;
9014        rti.realActivity = tr.realActivity;
9015        rti.description = tr.lastDescription;
9016        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9017        rti.userId = tr.userId;
9018        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9019        rti.firstActiveTime = tr.firstActiveTime;
9020        rti.lastActiveTime = tr.lastActiveTime;
9021        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9022        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9023        rti.numActivities = 0;
9024        if (tr.mBounds != null) {
9025            rti.bounds = new Rect(tr.mBounds);
9026        }
9027        rti.isDockable = tr.canGoInDockedStack();
9028        rti.resizeMode = tr.mResizeMode;
9029
9030        ActivityRecord base = null;
9031        ActivityRecord top = null;
9032        ActivityRecord tmp;
9033
9034        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9035            tmp = tr.mActivities.get(i);
9036            if (tmp.finishing) {
9037                continue;
9038            }
9039            base = tmp;
9040            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9041                top = base;
9042            }
9043            rti.numActivities++;
9044        }
9045
9046        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9047        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9048
9049        return rti;
9050    }
9051
9052    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9053        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9054                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9055        if (!allowed) {
9056            if (checkPermission(android.Manifest.permission.GET_TASKS,
9057                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9058                // Temporary compatibility: some existing apps on the system image may
9059                // still be requesting the old permission and not switched to the new
9060                // one; if so, we'll still allow them full access.  This means we need
9061                // to see if they are holding the old permission and are a system app.
9062                try {
9063                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9064                        allowed = true;
9065                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9066                                + " is using old GET_TASKS but privileged; allowing");
9067                    }
9068                } catch (RemoteException e) {
9069                }
9070            }
9071        }
9072        if (!allowed) {
9073            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9074                    + " does not hold REAL_GET_TASKS; limiting output");
9075        }
9076        return allowed;
9077    }
9078
9079    @Override
9080    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9081        final int callingUid = Binder.getCallingUid();
9082        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9083                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9084
9085        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9086        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9087        synchronized (this) {
9088            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9089                    callingUid);
9090            final boolean detailed = checkCallingPermission(
9091                    android.Manifest.permission.GET_DETAILED_TASKS)
9092                    == PackageManager.PERMISSION_GRANTED;
9093
9094            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9095                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9096                return Collections.emptyList();
9097            }
9098            mRecentTasks.loadUserRecentsLocked(userId);
9099
9100            final int recentsCount = mRecentTasks.size();
9101            ArrayList<ActivityManager.RecentTaskInfo> res =
9102                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9103
9104            final Set<Integer> includedUsers;
9105            if (includeProfiles) {
9106                includedUsers = mUserController.getProfileIds(userId);
9107            } else {
9108                includedUsers = new HashSet<>();
9109            }
9110            includedUsers.add(Integer.valueOf(userId));
9111
9112            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9113                TaskRecord tr = mRecentTasks.get(i);
9114                // Only add calling user or related users recent tasks
9115                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9116                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9117                    continue;
9118                }
9119
9120                if (tr.realActivitySuspended) {
9121                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9122                    continue;
9123                }
9124
9125                // Return the entry if desired by the caller.  We always return
9126                // the first entry, because callers always expect this to be the
9127                // foreground app.  We may filter others if the caller has
9128                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9129                // we should exclude the entry.
9130
9131                if (i == 0
9132                        || withExcluded
9133                        || (tr.intent == null)
9134                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9135                                == 0)) {
9136                    if (!allowed) {
9137                        // If the caller doesn't have the GET_TASKS permission, then only
9138                        // allow them to see a small subset of tasks -- their own and home.
9139                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9140                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9141                            continue;
9142                        }
9143                    }
9144                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9145                        if (tr.stack != null && tr.stack.isHomeStack()) {
9146                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9147                                    "Skipping, home stack task: " + tr);
9148                            continue;
9149                        }
9150                    }
9151                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9152                        final ActivityStack stack = tr.stack;
9153                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9154                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9155                                    "Skipping, top task in docked stack: " + tr);
9156                            continue;
9157                        }
9158                    }
9159                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9160                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9161                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9162                                    "Skipping, pinned stack task: " + tr);
9163                            continue;
9164                        }
9165                    }
9166                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9167                        // Don't include auto remove tasks that are finished or finishing.
9168                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9169                                "Skipping, auto-remove without activity: " + tr);
9170                        continue;
9171                    }
9172                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9173                            && !tr.isAvailable) {
9174                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9175                                "Skipping, unavail real act: " + tr);
9176                        continue;
9177                    }
9178
9179                    if (!tr.mUserSetupComplete) {
9180                        // Don't include task launched while user is not done setting-up.
9181                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9182                                "Skipping, user setup not complete: " + tr);
9183                        continue;
9184                    }
9185
9186                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9187                    if (!detailed) {
9188                        rti.baseIntent.replaceExtras((Bundle)null);
9189                    }
9190
9191                    res.add(rti);
9192                    maxNum--;
9193                }
9194            }
9195            return res;
9196        }
9197    }
9198
9199    @Override
9200    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9201        synchronized (this) {
9202            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9203                    "getTaskThumbnail()");
9204            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9205                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9206            if (tr != null) {
9207                return tr.getTaskThumbnailLocked();
9208            }
9209        }
9210        return null;
9211    }
9212
9213    @Override
9214    public int addAppTask(IBinder activityToken, Intent intent,
9215            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9216        final int callingUid = Binder.getCallingUid();
9217        final long callingIdent = Binder.clearCallingIdentity();
9218
9219        try {
9220            synchronized (this) {
9221                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9222                if (r == null) {
9223                    throw new IllegalArgumentException("Activity does not exist; token="
9224                            + activityToken);
9225                }
9226                ComponentName comp = intent.getComponent();
9227                if (comp == null) {
9228                    throw new IllegalArgumentException("Intent " + intent
9229                            + " must specify explicit component");
9230                }
9231                if (thumbnail.getWidth() != mThumbnailWidth
9232                        || thumbnail.getHeight() != mThumbnailHeight) {
9233                    throw new IllegalArgumentException("Bad thumbnail size: got "
9234                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9235                            + mThumbnailWidth + "x" + mThumbnailHeight);
9236                }
9237                if (intent.getSelector() != null) {
9238                    intent.setSelector(null);
9239                }
9240                if (intent.getSourceBounds() != null) {
9241                    intent.setSourceBounds(null);
9242                }
9243                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9244                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9245                        // The caller has added this as an auto-remove task...  that makes no
9246                        // sense, so turn off auto-remove.
9247                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9248                    }
9249                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9250                    // Must be a new task.
9251                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9252                }
9253                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9254                    mLastAddedTaskActivity = null;
9255                }
9256                ActivityInfo ainfo = mLastAddedTaskActivity;
9257                if (ainfo == null) {
9258                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9259                            comp, 0, UserHandle.getUserId(callingUid));
9260                    if (ainfo.applicationInfo.uid != callingUid) {
9261                        throw new SecurityException(
9262                                "Can't add task for another application: target uid="
9263                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9264                    }
9265                }
9266
9267                // Use the full screen as the context for the task thumbnail
9268                final Point displaySize = new Point();
9269                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9270                r.task.stack.getDisplaySize(displaySize);
9271                thumbnailInfo.taskWidth = displaySize.x;
9272                thumbnailInfo.taskHeight = displaySize.y;
9273                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9274
9275                TaskRecord task = new TaskRecord(this,
9276                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9277                        ainfo, intent, description, thumbnailInfo);
9278
9279                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9280                if (trimIdx >= 0) {
9281                    // If this would have caused a trim, then we'll abort because that
9282                    // means it would be added at the end of the list but then just removed.
9283                    return INVALID_TASK_ID;
9284                }
9285
9286                final int N = mRecentTasks.size();
9287                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9288                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9289                    tr.removedFromRecents();
9290                }
9291
9292                task.inRecents = true;
9293                mRecentTasks.add(task);
9294                r.task.stack.addTask(task, false, "addAppTask");
9295
9296                task.setLastThumbnailLocked(thumbnail);
9297                task.freeLastThumbnail();
9298
9299                return task.taskId;
9300            }
9301        } finally {
9302            Binder.restoreCallingIdentity(callingIdent);
9303        }
9304    }
9305
9306    @Override
9307    public Point getAppTaskThumbnailSize() {
9308        synchronized (this) {
9309            return new Point(mThumbnailWidth,  mThumbnailHeight);
9310        }
9311    }
9312
9313    @Override
9314    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9315        synchronized (this) {
9316            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9317            if (r != null) {
9318                r.setTaskDescription(td);
9319                r.task.updateTaskDescription();
9320            }
9321        }
9322    }
9323
9324    @Override
9325    public void setTaskResizeable(int taskId, int resizeableMode) {
9326        synchronized (this) {
9327            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9328                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9329            if (task == null) {
9330                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9331                return;
9332            }
9333            if (task.mResizeMode != resizeableMode) {
9334                task.mResizeMode = resizeableMode;
9335                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9336                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9337                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9338            }
9339        }
9340    }
9341
9342    @Override
9343    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9344        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9345        long ident = Binder.clearCallingIdentity();
9346        try {
9347            synchronized (this) {
9348                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9349                if (task == null) {
9350                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9351                    return;
9352                }
9353                int stackId = task.stack.mStackId;
9354                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9355                // in crop windows resize mode or if the task size is affected by the docked stack
9356                // changing size. No need to update configuration.
9357                if (bounds != null && task.inCropWindowsResizeMode()
9358                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9359                    mWindowManager.scrollTask(task.taskId, bounds);
9360                    return;
9361                }
9362
9363                // Place the task in the right stack if it isn't there already based on
9364                // the requested bounds.
9365                // The stack transition logic is:
9366                // - a null bounds on a freeform task moves that task to fullscreen
9367                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9368                //   that task to freeform
9369                // - otherwise the task is not moved
9370                if (!StackId.isTaskResizeAllowed(stackId)) {
9371                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9372                }
9373                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9374                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9375                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9376                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9377                }
9378                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9379                if (stackId != task.stack.mStackId) {
9380                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9381                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9382                    preserveWindow = false;
9383                }
9384
9385                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9386                        false /* deferResume */);
9387            }
9388        } finally {
9389            Binder.restoreCallingIdentity(ident);
9390        }
9391    }
9392
9393    @Override
9394    public Rect getTaskBounds(int taskId) {
9395        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9396        long ident = Binder.clearCallingIdentity();
9397        Rect rect = new Rect();
9398        try {
9399            synchronized (this) {
9400                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9401                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9402                if (task == null) {
9403                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9404                    return rect;
9405                }
9406                if (task.stack != null) {
9407                    // Return the bounds from window manager since it will be adjusted for various
9408                    // things like the presense of a docked stack for tasks that aren't resizeable.
9409                    mWindowManager.getTaskBounds(task.taskId, rect);
9410                } else {
9411                    // Task isn't in window manager yet since it isn't associated with a stack.
9412                    // Return the persist value from activity manager
9413                    if (task.mBounds != null) {
9414                        rect.set(task.mBounds);
9415                    } else if (task.mLastNonFullscreenBounds != null) {
9416                        rect.set(task.mLastNonFullscreenBounds);
9417                    }
9418                }
9419            }
9420        } finally {
9421            Binder.restoreCallingIdentity(ident);
9422        }
9423        return rect;
9424    }
9425
9426    @Override
9427    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9428        if (userId != UserHandle.getCallingUserId()) {
9429            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9430                    "getTaskDescriptionIcon");
9431        }
9432        final File passedIconFile = new File(filePath);
9433        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9434                passedIconFile.getName());
9435        if (!legitIconFile.getPath().equals(filePath)
9436                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9437            throw new IllegalArgumentException("Bad file path: " + filePath
9438                    + " passed for userId " + userId);
9439        }
9440        return mRecentTasks.getTaskDescriptionIcon(filePath);
9441    }
9442
9443    @Override
9444    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9445            throws RemoteException {
9446        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9447                opts.getCustomInPlaceResId() == 0) {
9448            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9449                    "with valid animation");
9450        }
9451        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9452        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9453                opts.getCustomInPlaceResId());
9454        mWindowManager.executeAppTransition();
9455    }
9456
9457    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9458            boolean removeFromRecents) {
9459        if (removeFromRecents) {
9460            mRecentTasks.remove(tr);
9461            tr.removedFromRecents();
9462        }
9463        ComponentName component = tr.getBaseIntent().getComponent();
9464        if (component == null) {
9465            Slog.w(TAG, "No component for base intent of task: " + tr);
9466            return;
9467        }
9468
9469        // Find any running services associated with this app and stop if needed.
9470        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9471
9472        if (!killProcess) {
9473            return;
9474        }
9475
9476        // Determine if the process(es) for this task should be killed.
9477        final String pkg = component.getPackageName();
9478        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9479        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9480        for (int i = 0; i < pmap.size(); i++) {
9481
9482            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9483            for (int j = 0; j < uids.size(); j++) {
9484                ProcessRecord proc = uids.valueAt(j);
9485                if (proc.userId != tr.userId) {
9486                    // Don't kill process for a different user.
9487                    continue;
9488                }
9489                if (proc == mHomeProcess) {
9490                    // Don't kill the home process along with tasks from the same package.
9491                    continue;
9492                }
9493                if (!proc.pkgList.containsKey(pkg)) {
9494                    // Don't kill process that is not associated with this task.
9495                    continue;
9496                }
9497
9498                for (int k = 0; k < proc.activities.size(); k++) {
9499                    TaskRecord otherTask = proc.activities.get(k).task;
9500                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9501                        // Don't kill process(es) that has an activity in a different task that is
9502                        // also in recents.
9503                        return;
9504                    }
9505                }
9506
9507                if (proc.foregroundServices) {
9508                    // Don't kill process(es) with foreground service.
9509                    return;
9510                }
9511
9512                // Add process to kill list.
9513                procsToKill.add(proc);
9514            }
9515        }
9516
9517        // Kill the running processes.
9518        for (int i = 0; i < procsToKill.size(); i++) {
9519            ProcessRecord pr = procsToKill.get(i);
9520            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9521                    && pr.curReceiver == null) {
9522                pr.kill("remove task", true);
9523            } else {
9524                // We delay killing processes that are not in the background or running a receiver.
9525                pr.waitingToKill = "remove task";
9526            }
9527        }
9528    }
9529
9530    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9531        // Remove all tasks with activities in the specified package from the list of recent tasks
9532        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9533            TaskRecord tr = mRecentTasks.get(i);
9534            if (tr.userId != userId) continue;
9535
9536            ComponentName cn = tr.intent.getComponent();
9537            if (cn != null && cn.getPackageName().equals(packageName)) {
9538                // If the package name matches, remove the task.
9539                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9540            }
9541        }
9542    }
9543
9544    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9545            int userId) {
9546
9547        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9548            TaskRecord tr = mRecentTasks.get(i);
9549            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9550                continue;
9551            }
9552
9553            ComponentName cn = tr.intent.getComponent();
9554            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9555                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9556            if (sameComponent) {
9557                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9558            }
9559        }
9560    }
9561
9562    /**
9563     * Removes the task with the specified task id.
9564     *
9565     * @param taskId Identifier of the task to be removed.
9566     * @param killProcess Kill any process associated with the task if possible.
9567     * @param removeFromRecents Whether to also remove the task from recents.
9568     * @return Returns true if the given task was found and removed.
9569     */
9570    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9571            boolean removeFromRecents) {
9572        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9573                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9574        if (tr != null) {
9575            tr.removeTaskActivitiesLocked();
9576            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9577            if (tr.isPersistable) {
9578                notifyTaskPersisterLocked(null, true);
9579            }
9580            return true;
9581        }
9582        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9583        return false;
9584    }
9585
9586    @Override
9587    public void removeStack(int stackId) {
9588        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9589        if (stackId == HOME_STACK_ID) {
9590            throw new IllegalArgumentException("Removing home stack is not allowed.");
9591        }
9592
9593        synchronized (this) {
9594            final long ident = Binder.clearCallingIdentity();
9595            try {
9596                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9597                if (stack == null) {
9598                    return;
9599                }
9600                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9601                for (int i = tasks.size() - 1; i >= 0; i--) {
9602                    removeTaskByIdLocked(
9603                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9604                }
9605            } finally {
9606                Binder.restoreCallingIdentity(ident);
9607            }
9608        }
9609    }
9610
9611    @Override
9612    public boolean removeTask(int taskId) {
9613        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9614        synchronized (this) {
9615            final long ident = Binder.clearCallingIdentity();
9616            try {
9617                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9618            } finally {
9619                Binder.restoreCallingIdentity(ident);
9620            }
9621        }
9622    }
9623
9624    /**
9625     * TODO: Add mController hook
9626     */
9627    @Override
9628    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9629        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9630
9631        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9632        synchronized(this) {
9633            moveTaskToFrontLocked(taskId, flags, bOptions);
9634        }
9635    }
9636
9637    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9638        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9639
9640        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9641                Binder.getCallingUid(), -1, -1, "Task to front")) {
9642            ActivityOptions.abort(options);
9643            return;
9644        }
9645        final long origId = Binder.clearCallingIdentity();
9646        try {
9647            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9648            if (task == null) {
9649                Slog.d(TAG, "Could not find task for id: "+ taskId);
9650                return;
9651            }
9652            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9653                mStackSupervisor.showLockTaskToast();
9654                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9655                return;
9656            }
9657            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9658            if (prev != null && prev.isRecentsActivity()) {
9659                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9660            }
9661            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9662                    false /* forceNonResizable */);
9663        } finally {
9664            Binder.restoreCallingIdentity(origId);
9665        }
9666        ActivityOptions.abort(options);
9667    }
9668
9669    /**
9670     * Moves an activity, and all of the other activities within the same task, to the bottom
9671     * of the history stack.  The activity's order within the task is unchanged.
9672     *
9673     * @param token A reference to the activity we wish to move
9674     * @param nonRoot If false then this only works if the activity is the root
9675     *                of a task; if true it will work for any activity in a task.
9676     * @return Returns true if the move completed, false if not.
9677     */
9678    @Override
9679    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9680        enforceNotIsolatedCaller("moveActivityTaskToBack");
9681        synchronized(this) {
9682            final long origId = Binder.clearCallingIdentity();
9683            try {
9684                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9685                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9686                if (task != null) {
9687                    if (mStackSupervisor.isLockedTask(task)) {
9688                        mStackSupervisor.showLockTaskToast();
9689                        return false;
9690                    }
9691                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9692                }
9693            } finally {
9694                Binder.restoreCallingIdentity(origId);
9695            }
9696        }
9697        return false;
9698    }
9699
9700    @Override
9701    public void moveTaskBackwards(int task) {
9702        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9703                "moveTaskBackwards()");
9704
9705        synchronized(this) {
9706            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9707                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9708                return;
9709            }
9710            final long origId = Binder.clearCallingIdentity();
9711            moveTaskBackwardsLocked(task);
9712            Binder.restoreCallingIdentity(origId);
9713        }
9714    }
9715
9716    private final void moveTaskBackwardsLocked(int task) {
9717        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9718    }
9719
9720    @Override
9721    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9722            IActivityContainerCallback callback) throws RemoteException {
9723        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9724        synchronized (this) {
9725            if (parentActivityToken == null) {
9726                throw new IllegalArgumentException("parent token must not be null");
9727            }
9728            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9729            if (r == null) {
9730                return null;
9731            }
9732            if (callback == null) {
9733                throw new IllegalArgumentException("callback must not be null");
9734            }
9735            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9736        }
9737    }
9738
9739    @Override
9740    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9741        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9742        synchronized (this) {
9743            mStackSupervisor.deleteActivityContainer(container);
9744        }
9745    }
9746
9747    @Override
9748    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9749        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9750        synchronized (this) {
9751            final int stackId = mStackSupervisor.getNextStackId();
9752            final ActivityStack stack =
9753                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9754            if (stack == null) {
9755                return null;
9756            }
9757            return stack.mActivityContainer;
9758        }
9759    }
9760
9761    @Override
9762    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9763        synchronized (this) {
9764            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9765            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9766                return stack.mActivityContainer.getDisplayId();
9767            }
9768            return Display.DEFAULT_DISPLAY;
9769        }
9770    }
9771
9772    @Override
9773    public int getActivityStackId(IBinder token) throws RemoteException {
9774        synchronized (this) {
9775            ActivityStack stack = ActivityRecord.getStackLocked(token);
9776            if (stack == null) {
9777                return INVALID_STACK_ID;
9778            }
9779            return stack.mStackId;
9780        }
9781    }
9782
9783    @Override
9784    public void exitFreeformMode(IBinder token) throws RemoteException {
9785        synchronized (this) {
9786            long ident = Binder.clearCallingIdentity();
9787            try {
9788                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9789                if (r == null) {
9790                    throw new IllegalArgumentException(
9791                            "exitFreeformMode: No activity record matching token=" + token);
9792                }
9793                final ActivityStack stack = r.getStackLocked(token);
9794                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9795                    throw new IllegalStateException(
9796                            "exitFreeformMode: You can only go fullscreen from freeform.");
9797                }
9798                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9799                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9800                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9801            } finally {
9802                Binder.restoreCallingIdentity(ident);
9803            }
9804        }
9805    }
9806
9807    @Override
9808    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9809        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9810        if (stackId == HOME_STACK_ID) {
9811            throw new IllegalArgumentException(
9812                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9813        }
9814        synchronized (this) {
9815            long ident = Binder.clearCallingIdentity();
9816            try {
9817                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9818                        + " to stackId=" + stackId + " toTop=" + toTop);
9819                if (stackId == DOCKED_STACK_ID) {
9820                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9821                            null /* initialBounds */);
9822                }
9823                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9824                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9825                if (result && stackId == DOCKED_STACK_ID) {
9826                    // If task moved to docked stack - show recents if needed.
9827                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9828                            "moveTaskToDockedStack");
9829                }
9830            } finally {
9831                Binder.restoreCallingIdentity(ident);
9832            }
9833        }
9834    }
9835
9836    @Override
9837    public void swapDockedAndFullscreenStack() throws RemoteException {
9838        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9839        synchronized (this) {
9840            long ident = Binder.clearCallingIdentity();
9841            try {
9842                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9843                        FULLSCREEN_WORKSPACE_STACK_ID);
9844                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9845                        : null;
9846                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9847                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9848                        : null;
9849                if (topTask == null || tasks == null || tasks.size() == 0) {
9850                    Slog.w(TAG,
9851                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9852                    return;
9853                }
9854
9855                // TODO: App transition
9856                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9857
9858                // Defer the resume so resume/pausing while moving stacks is dangerous.
9859                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9860                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9861                        ANIMATE, true /* deferResume */);
9862                final int size = tasks.size();
9863                for (int i = 0; i < size; i++) {
9864                    final int id = tasks.get(i).taskId;
9865                    if (id == topTask.taskId) {
9866                        continue;
9867                    }
9868                    mStackSupervisor.moveTaskToStackLocked(id,
9869                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9870                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9871                }
9872
9873                // Because we deferred the resume, to avoid conflicts with stack switches while
9874                // resuming, we need to do it after all the tasks are moved.
9875                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9876                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9877
9878                mWindowManager.executeAppTransition();
9879            } finally {
9880                Binder.restoreCallingIdentity(ident);
9881            }
9882        }
9883    }
9884
9885    /**
9886     * Moves the input task to the docked stack.
9887     *
9888     * @param taskId Id of task to move.
9889     * @param createMode The mode the docked stack should be created in if it doesn't exist
9890     *                   already. See
9891     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9892     *                   and
9893     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9894     * @param toTop If the task and stack should be moved to the top.
9895     * @param animate Whether we should play an animation for the moving the task
9896     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9897     *                      docked stack. Pass {@code null} to use default bounds.
9898     */
9899    @Override
9900    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9901            Rect initialBounds, boolean moveHomeStackFront) {
9902        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9903        synchronized (this) {
9904            long ident = Binder.clearCallingIdentity();
9905            try {
9906                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9907                        + " to createMode=" + createMode + " toTop=" + toTop);
9908                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9909                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9910                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9911                        animate, DEFER_RESUME);
9912                if (moved) {
9913                    if (moveHomeStackFront) {
9914                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9915                    }
9916                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9917                }
9918                return moved;
9919            } finally {
9920                Binder.restoreCallingIdentity(ident);
9921            }
9922        }
9923    }
9924
9925    /**
9926     * Moves the top activity in the input stackId to the pinned stack.
9927     *
9928     * @param stackId Id of stack to move the top activity to pinned stack.
9929     * @param bounds Bounds to use for pinned stack.
9930     *
9931     * @return True if the top activity of the input stack was successfully moved to the pinned
9932     *          stack.
9933     */
9934    @Override
9935    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9936        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9937        synchronized (this) {
9938            if (!mSupportsPictureInPicture) {
9939                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9940                        + "Device doesn't support picture-in-pciture mode");
9941            }
9942
9943            long ident = Binder.clearCallingIdentity();
9944            try {
9945                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9946            } finally {
9947                Binder.restoreCallingIdentity(ident);
9948            }
9949        }
9950    }
9951
9952    @Override
9953    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9954            boolean preserveWindows, boolean animate, int animationDuration) {
9955        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9956        long ident = Binder.clearCallingIdentity();
9957        try {
9958            synchronized (this) {
9959                if (animate) {
9960                    if (stackId == PINNED_STACK_ID) {
9961                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9962                    } else {
9963                        throw new IllegalArgumentException("Stack: " + stackId
9964                                + " doesn't support animated resize.");
9965                    }
9966                } else {
9967                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9968                            null /* tempTaskInsetBounds */, preserveWindows,
9969                            allowResizeInDockedMode, !DEFER_RESUME);
9970                }
9971            }
9972        } finally {
9973            Binder.restoreCallingIdentity(ident);
9974        }
9975    }
9976
9977    @Override
9978    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9979            Rect tempDockedTaskInsetBounds,
9980            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9981        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9982                "resizeDockedStack()");
9983        long ident = Binder.clearCallingIdentity();
9984        try {
9985            synchronized (this) {
9986                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9987                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9988                        PRESERVE_WINDOWS);
9989            }
9990        } finally {
9991            Binder.restoreCallingIdentity(ident);
9992        }
9993    }
9994
9995    @Override
9996    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9997        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9998                "resizePinnedStack()");
9999        final long ident = Binder.clearCallingIdentity();
10000        try {
10001            synchronized (this) {
10002                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10003            }
10004        } finally {
10005            Binder.restoreCallingIdentity(ident);
10006        }
10007    }
10008
10009    @Override
10010    public void positionTaskInStack(int taskId, int stackId, int position) {
10011        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10012        if (stackId == HOME_STACK_ID) {
10013            throw new IllegalArgumentException(
10014                    "positionTaskInStack: Attempt to change the position of task "
10015                    + taskId + " in/to home stack");
10016        }
10017        synchronized (this) {
10018            long ident = Binder.clearCallingIdentity();
10019            try {
10020                if (DEBUG_STACK) Slog.d(TAG_STACK,
10021                        "positionTaskInStack: positioning task=" + taskId
10022                        + " in stackId=" + stackId + " at position=" + position);
10023                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10024            } finally {
10025                Binder.restoreCallingIdentity(ident);
10026            }
10027        }
10028    }
10029
10030    @Override
10031    public List<StackInfo> getAllStackInfos() {
10032        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10033        long ident = Binder.clearCallingIdentity();
10034        try {
10035            synchronized (this) {
10036                return mStackSupervisor.getAllStackInfosLocked();
10037            }
10038        } finally {
10039            Binder.restoreCallingIdentity(ident);
10040        }
10041    }
10042
10043    @Override
10044    public StackInfo getStackInfo(int stackId) {
10045        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10046        long ident = Binder.clearCallingIdentity();
10047        try {
10048            synchronized (this) {
10049                return mStackSupervisor.getStackInfoLocked(stackId);
10050            }
10051        } finally {
10052            Binder.restoreCallingIdentity(ident);
10053        }
10054    }
10055
10056    @Override
10057    public boolean isInHomeStack(int taskId) {
10058        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10059        long ident = Binder.clearCallingIdentity();
10060        try {
10061            synchronized (this) {
10062                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10063                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10064                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10065            }
10066        } finally {
10067            Binder.restoreCallingIdentity(ident);
10068        }
10069    }
10070
10071    @Override
10072    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10073        synchronized(this) {
10074            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10075        }
10076    }
10077
10078    @Override
10079    public void updateDeviceOwner(String packageName) {
10080        final int callingUid = Binder.getCallingUid();
10081        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10082            throw new SecurityException("updateDeviceOwner called from non-system process");
10083        }
10084        synchronized (this) {
10085            mDeviceOwnerName = packageName;
10086        }
10087    }
10088
10089    @Override
10090    public void updateLockTaskPackages(int userId, String[] packages) {
10091        final int callingUid = Binder.getCallingUid();
10092        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10093            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10094                    "updateLockTaskPackages()");
10095        }
10096        synchronized (this) {
10097            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10098                    Arrays.toString(packages));
10099            mLockTaskPackages.put(userId, packages);
10100            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10101        }
10102    }
10103
10104
10105    void startLockTaskModeLocked(TaskRecord task) {
10106        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10107        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10108            return;
10109        }
10110
10111        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10112        // is initiated by system after the pinning request was shown and locked mode is initiated
10113        // by an authorized app directly
10114        final int callingUid = Binder.getCallingUid();
10115        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10116        long ident = Binder.clearCallingIdentity();
10117        try {
10118            if (!isSystemInitiated) {
10119                task.mLockTaskUid = callingUid;
10120                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10121                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10122                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10123                    StatusBarManagerInternal statusBarManager =
10124                            LocalServices.getService(StatusBarManagerInternal.class);
10125                    if (statusBarManager != null) {
10126                        statusBarManager.showScreenPinningRequest(task.taskId);
10127                    }
10128                    return;
10129                }
10130
10131                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10132                if (stack == null || task != stack.topTask()) {
10133                    throw new IllegalArgumentException("Invalid task, not in foreground");
10134                }
10135            }
10136            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10137                    "Locking fully");
10138            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10139                    ActivityManager.LOCK_TASK_MODE_PINNED :
10140                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10141                    "startLockTask", true);
10142        } finally {
10143            Binder.restoreCallingIdentity(ident);
10144        }
10145    }
10146
10147    @Override
10148    public void startLockTaskMode(int taskId) {
10149        synchronized (this) {
10150            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10151            if (task != null) {
10152                startLockTaskModeLocked(task);
10153            }
10154        }
10155    }
10156
10157    @Override
10158    public void startLockTaskMode(IBinder token) {
10159        synchronized (this) {
10160            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10161            if (r == null) {
10162                return;
10163            }
10164            final TaskRecord task = r.task;
10165            if (task != null) {
10166                startLockTaskModeLocked(task);
10167            }
10168        }
10169    }
10170
10171    @Override
10172    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10173        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10174        // This makes inner call to look as if it was initiated by system.
10175        long ident = Binder.clearCallingIdentity();
10176        try {
10177            synchronized (this) {
10178                startLockTaskMode(taskId);
10179            }
10180        } finally {
10181            Binder.restoreCallingIdentity(ident);
10182        }
10183    }
10184
10185    @Override
10186    public void stopLockTaskMode() {
10187        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10188        if (lockTask == null) {
10189            // Our work here is done.
10190            return;
10191        }
10192
10193        final int callingUid = Binder.getCallingUid();
10194        final int lockTaskUid = lockTask.mLockTaskUid;
10195        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10196        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10197            // Done.
10198            return;
10199        } else {
10200            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10201            // It is possible lockTaskMode was started by the system process because
10202            // android:lockTaskMode is set to a locking value in the application manifest
10203            // instead of the app calling startLockTaskMode. In this case
10204            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10205            // {@link TaskRecord.effectiveUid} instead. Also caller with
10206            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10207            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10208                    && callingUid != lockTaskUid
10209                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10210                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10211                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10212            }
10213        }
10214        long ident = Binder.clearCallingIdentity();
10215        try {
10216            Log.d(TAG, "stopLockTaskMode");
10217            // Stop lock task
10218            synchronized (this) {
10219                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10220                        "stopLockTask", true);
10221            }
10222            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10223            if (tm != null) {
10224                tm.showInCallScreen(false);
10225            }
10226        } finally {
10227            Binder.restoreCallingIdentity(ident);
10228        }
10229    }
10230
10231    /**
10232     * This API should be called by SystemUI only when user perform certain action to dismiss
10233     * lock task mode. We should only dismiss pinned lock task mode in this case.
10234     */
10235    @Override
10236    public void stopSystemLockTaskMode() throws RemoteException {
10237        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10238            stopLockTaskMode();
10239        } else {
10240            mStackSupervisor.showLockTaskToast();
10241        }
10242    }
10243
10244    @Override
10245    public boolean isInLockTaskMode() {
10246        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10247    }
10248
10249    @Override
10250    public int getLockTaskModeState() {
10251        synchronized (this) {
10252            return mStackSupervisor.getLockTaskModeState();
10253        }
10254    }
10255
10256    @Override
10257    public void showLockTaskEscapeMessage(IBinder token) {
10258        synchronized (this) {
10259            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10260            if (r == null) {
10261                return;
10262            }
10263            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10264        }
10265    }
10266
10267    // =========================================================
10268    // CONTENT PROVIDERS
10269    // =========================================================
10270
10271    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10272        List<ProviderInfo> providers = null;
10273        try {
10274            providers = AppGlobals.getPackageManager()
10275                    .queryContentProviders(app.processName, app.uid,
10276                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10277                                    | MATCH_DEBUG_TRIAGED_MISSING)
10278                    .getList();
10279        } catch (RemoteException ex) {
10280        }
10281        if (DEBUG_MU) Slog.v(TAG_MU,
10282                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10283        int userId = app.userId;
10284        if (providers != null) {
10285            int N = providers.size();
10286            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10287            for (int i=0; i<N; i++) {
10288                // TODO: keep logic in sync with installEncryptionUnawareProviders
10289                ProviderInfo cpi =
10290                    (ProviderInfo)providers.get(i);
10291                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10292                        cpi.name, cpi.flags);
10293                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10294                    // This is a singleton provider, but a user besides the
10295                    // default user is asking to initialize a process it runs
10296                    // in...  well, no, it doesn't actually run in this process,
10297                    // it runs in the process of the default user.  Get rid of it.
10298                    providers.remove(i);
10299                    N--;
10300                    i--;
10301                    continue;
10302                }
10303
10304                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10305                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10306                if (cpr == null) {
10307                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10308                    mProviderMap.putProviderByClass(comp, cpr);
10309                }
10310                if (DEBUG_MU) Slog.v(TAG_MU,
10311                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10312                app.pubProviders.put(cpi.name, cpr);
10313                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10314                    // Don't add this if it is a platform component that is marked
10315                    // to run in multiple processes, because this is actually
10316                    // part of the framework so doesn't make sense to track as a
10317                    // separate apk in the process.
10318                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10319                            mProcessStats);
10320                }
10321                notifyPackageUse(cpi.applicationInfo.packageName,
10322                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10323            }
10324        }
10325        return providers;
10326    }
10327
10328    /**
10329     * Check if {@link ProcessRecord} has a possible chance at accessing the
10330     * given {@link ProviderInfo}. Final permission checking is always done
10331     * in {@link ContentProvider}.
10332     */
10333    private final String checkContentProviderPermissionLocked(
10334            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10335        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10336        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10337        boolean checkedGrants = false;
10338        if (checkUser) {
10339            // Looking for cross-user grants before enforcing the typical cross-users permissions
10340            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10341            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10342                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10343                    return null;
10344                }
10345                checkedGrants = true;
10346            }
10347            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10348                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10349            if (userId != tmpTargetUserId) {
10350                // When we actually went to determine the final targer user ID, this ended
10351                // up different than our initial check for the authority.  This is because
10352                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10353                // SELF.  So we need to re-check the grants again.
10354                checkedGrants = false;
10355            }
10356        }
10357        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10358                cpi.applicationInfo.uid, cpi.exported)
10359                == PackageManager.PERMISSION_GRANTED) {
10360            return null;
10361        }
10362        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10363                cpi.applicationInfo.uid, cpi.exported)
10364                == PackageManager.PERMISSION_GRANTED) {
10365            return null;
10366        }
10367
10368        PathPermission[] pps = cpi.pathPermissions;
10369        if (pps != null) {
10370            int i = pps.length;
10371            while (i > 0) {
10372                i--;
10373                PathPermission pp = pps[i];
10374                String pprperm = pp.getReadPermission();
10375                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10376                        cpi.applicationInfo.uid, cpi.exported)
10377                        == PackageManager.PERMISSION_GRANTED) {
10378                    return null;
10379                }
10380                String ppwperm = pp.getWritePermission();
10381                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10382                        cpi.applicationInfo.uid, cpi.exported)
10383                        == PackageManager.PERMISSION_GRANTED) {
10384                    return null;
10385                }
10386            }
10387        }
10388        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10389            return null;
10390        }
10391
10392        String msg;
10393        if (!cpi.exported) {
10394            msg = "Permission Denial: opening provider " + cpi.name
10395                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10396                    + ", uid=" + callingUid + ") that is not exported from uid "
10397                    + cpi.applicationInfo.uid;
10398        } else {
10399            msg = "Permission Denial: opening provider " + cpi.name
10400                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10401                    + ", uid=" + callingUid + ") requires "
10402                    + cpi.readPermission + " or " + cpi.writePermission;
10403        }
10404        Slog.w(TAG, msg);
10405        return msg;
10406    }
10407
10408    /**
10409     * Returns if the ContentProvider has granted a uri to callingUid
10410     */
10411    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10412        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10413        if (perms != null) {
10414            for (int i=perms.size()-1; i>=0; i--) {
10415                GrantUri grantUri = perms.keyAt(i);
10416                if (grantUri.sourceUserId == userId || !checkUser) {
10417                    if (matchesProvider(grantUri.uri, cpi)) {
10418                        return true;
10419                    }
10420                }
10421            }
10422        }
10423        return false;
10424    }
10425
10426    /**
10427     * Returns true if the uri authority is one of the authorities specified in the provider.
10428     */
10429    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10430        String uriAuth = uri.getAuthority();
10431        String cpiAuth = cpi.authority;
10432        if (cpiAuth.indexOf(';') == -1) {
10433            return cpiAuth.equals(uriAuth);
10434        }
10435        String[] cpiAuths = cpiAuth.split(";");
10436        int length = cpiAuths.length;
10437        for (int i = 0; i < length; i++) {
10438            if (cpiAuths[i].equals(uriAuth)) return true;
10439        }
10440        return false;
10441    }
10442
10443    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10444            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10445        if (r != null) {
10446            for (int i=0; i<r.conProviders.size(); i++) {
10447                ContentProviderConnection conn = r.conProviders.get(i);
10448                if (conn.provider == cpr) {
10449                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10450                            "Adding provider requested by "
10451                            + r.processName + " from process "
10452                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10453                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10454                    if (stable) {
10455                        conn.stableCount++;
10456                        conn.numStableIncs++;
10457                    } else {
10458                        conn.unstableCount++;
10459                        conn.numUnstableIncs++;
10460                    }
10461                    return conn;
10462                }
10463            }
10464            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10465            if (stable) {
10466                conn.stableCount = 1;
10467                conn.numStableIncs = 1;
10468            } else {
10469                conn.unstableCount = 1;
10470                conn.numUnstableIncs = 1;
10471            }
10472            cpr.connections.add(conn);
10473            r.conProviders.add(conn);
10474            startAssociationLocked(r.uid, r.processName, r.curProcState,
10475                    cpr.uid, cpr.name, cpr.info.processName);
10476            return conn;
10477        }
10478        cpr.addExternalProcessHandleLocked(externalProcessToken);
10479        return null;
10480    }
10481
10482    boolean decProviderCountLocked(ContentProviderConnection conn,
10483            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10484        if (conn != null) {
10485            cpr = conn.provider;
10486            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10487                    "Removing provider requested by "
10488                    + conn.client.processName + " from process "
10489                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10490                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10491            if (stable) {
10492                conn.stableCount--;
10493            } else {
10494                conn.unstableCount--;
10495            }
10496            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10497                cpr.connections.remove(conn);
10498                conn.client.conProviders.remove(conn);
10499                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10500                    // The client is more important than last activity -- note the time this
10501                    // is happening, so we keep the old provider process around a bit as last
10502                    // activity to avoid thrashing it.
10503                    if (cpr.proc != null) {
10504                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10505                    }
10506                }
10507                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10508                return true;
10509            }
10510            return false;
10511        }
10512        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10513        return false;
10514    }
10515
10516    private void checkTime(long startTime, String where) {
10517        long now = SystemClock.uptimeMillis();
10518        if ((now-startTime) > 50) {
10519            // If we are taking more than 50ms, log about it.
10520            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10521        }
10522    }
10523
10524    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10525            PROC_SPACE_TERM,
10526            PROC_SPACE_TERM|PROC_PARENS,
10527            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10528    };
10529
10530    private final long[] mProcessStateStatsLongs = new long[1];
10531
10532    boolean isProcessAliveLocked(ProcessRecord proc) {
10533        if (proc.procStatFile == null) {
10534            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10535        }
10536        mProcessStateStatsLongs[0] = 0;
10537        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10538                mProcessStateStatsLongs, null)) {
10539            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10540            return false;
10541        }
10542        final long state = mProcessStateStatsLongs[0];
10543        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10544                + (char)state);
10545        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10546    }
10547
10548    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10549            String name, IBinder token, boolean stable, int userId) {
10550        ContentProviderRecord cpr;
10551        ContentProviderConnection conn = null;
10552        ProviderInfo cpi = null;
10553
10554        synchronized(this) {
10555            long startTime = SystemClock.uptimeMillis();
10556
10557            ProcessRecord r = null;
10558            if (caller != null) {
10559                r = getRecordForAppLocked(caller);
10560                if (r == null) {
10561                    throw new SecurityException(
10562                            "Unable to find app for caller " + caller
10563                          + " (pid=" + Binder.getCallingPid()
10564                          + ") when getting content provider " + name);
10565                }
10566            }
10567
10568            boolean checkCrossUser = true;
10569
10570            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10571
10572            // First check if this content provider has been published...
10573            cpr = mProviderMap.getProviderByName(name, userId);
10574            // If that didn't work, check if it exists for user 0 and then
10575            // verify that it's a singleton provider before using it.
10576            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10577                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10578                if (cpr != null) {
10579                    cpi = cpr.info;
10580                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10581                            cpi.name, cpi.flags)
10582                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10583                        userId = UserHandle.USER_SYSTEM;
10584                        checkCrossUser = false;
10585                    } else {
10586                        cpr = null;
10587                        cpi = null;
10588                    }
10589                }
10590            }
10591
10592            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10593            if (providerRunning) {
10594                cpi = cpr.info;
10595                String msg;
10596                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10597                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10598                        != null) {
10599                    throw new SecurityException(msg);
10600                }
10601                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10602
10603                if (r != null && cpr.canRunHere(r)) {
10604                    // This provider has been published or is in the process
10605                    // of being published...  but it is also allowed to run
10606                    // in the caller's process, so don't make a connection
10607                    // and just let the caller instantiate its own instance.
10608                    ContentProviderHolder holder = cpr.newHolder(null);
10609                    // don't give caller the provider object, it needs
10610                    // to make its own.
10611                    holder.provider = null;
10612                    return holder;
10613                }
10614
10615                final long origId = Binder.clearCallingIdentity();
10616
10617                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10618
10619                // In this case the provider instance already exists, so we can
10620                // return it right away.
10621                conn = incProviderCountLocked(r, cpr, token, stable);
10622                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10623                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10624                        // If this is a perceptible app accessing the provider,
10625                        // make sure to count it as being accessed and thus
10626                        // back up on the LRU list.  This is good because
10627                        // content providers are often expensive to start.
10628                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10629                        updateLruProcessLocked(cpr.proc, false, null);
10630                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10631                    }
10632                }
10633
10634                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10635                final int verifiedAdj = cpr.proc.verifiedAdj;
10636                boolean success = updateOomAdjLocked(cpr.proc);
10637                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10638                // if the process has been successfully adjusted.  So to reduce races with
10639                // it, we will check whether the process still exists.  Note that this doesn't
10640                // completely get rid of races with LMK killing the process, but should make
10641                // them much smaller.
10642                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10643                    success = false;
10644                }
10645                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10646                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10647                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10648                // NOTE: there is still a race here where a signal could be
10649                // pending on the process even though we managed to update its
10650                // adj level.  Not sure what to do about this, but at least
10651                // the race is now smaller.
10652                if (!success) {
10653                    // Uh oh...  it looks like the provider's process
10654                    // has been killed on us.  We need to wait for a new
10655                    // process to be started, and make sure its death
10656                    // doesn't kill our process.
10657                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10658                            + " is crashing; detaching " + r);
10659                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10660                    checkTime(startTime, "getContentProviderImpl: before appDied");
10661                    appDiedLocked(cpr.proc);
10662                    checkTime(startTime, "getContentProviderImpl: after appDied");
10663                    if (!lastRef) {
10664                        // This wasn't the last ref our process had on
10665                        // the provider...  we have now been killed, bail.
10666                        return null;
10667                    }
10668                    providerRunning = false;
10669                    conn = null;
10670                } else {
10671                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10672                }
10673
10674                Binder.restoreCallingIdentity(origId);
10675            }
10676
10677            if (!providerRunning) {
10678                try {
10679                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10680                    cpi = AppGlobals.getPackageManager().
10681                        resolveContentProvider(name,
10682                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10683                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10684                } catch (RemoteException ex) {
10685                }
10686                if (cpi == null) {
10687                    return null;
10688                }
10689                // If the provider is a singleton AND
10690                // (it's a call within the same user || the provider is a
10691                // privileged app)
10692                // Then allow connecting to the singleton provider
10693                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10694                        cpi.name, cpi.flags)
10695                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10696                if (singleton) {
10697                    userId = UserHandle.USER_SYSTEM;
10698                }
10699                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10700                checkTime(startTime, "getContentProviderImpl: got app info for user");
10701
10702                String msg;
10703                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10704                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10705                        != null) {
10706                    throw new SecurityException(msg);
10707                }
10708                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10709
10710                if (!mProcessesReady
10711                        && !cpi.processName.equals("system")) {
10712                    // If this content provider does not run in the system
10713                    // process, and the system is not yet ready to run other
10714                    // processes, then fail fast instead of hanging.
10715                    throw new IllegalArgumentException(
10716                            "Attempt to launch content provider before system ready");
10717                }
10718
10719                // Make sure that the user who owns this provider is running.  If not,
10720                // we don't want to allow it to run.
10721                if (!mUserController.isUserRunningLocked(userId, 0)) {
10722                    Slog.w(TAG, "Unable to launch app "
10723                            + cpi.applicationInfo.packageName + "/"
10724                            + cpi.applicationInfo.uid + " for provider "
10725                            + name + ": user " + userId + " is stopped");
10726                    return null;
10727                }
10728
10729                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10730                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10731                cpr = mProviderMap.getProviderByClass(comp, userId);
10732                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10733                final boolean firstClass = cpr == null;
10734                if (firstClass) {
10735                    final long ident = Binder.clearCallingIdentity();
10736
10737                    // If permissions need a review before any of the app components can run,
10738                    // we return no provider and launch a review activity if the calling app
10739                    // is in the foreground.
10740                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10741                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10742                            return null;
10743                        }
10744                    }
10745
10746                    try {
10747                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10748                        ApplicationInfo ai =
10749                            AppGlobals.getPackageManager().
10750                                getApplicationInfo(
10751                                        cpi.applicationInfo.packageName,
10752                                        STOCK_PM_FLAGS, userId);
10753                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10754                        if (ai == null) {
10755                            Slog.w(TAG, "No package info for content provider "
10756                                    + cpi.name);
10757                            return null;
10758                        }
10759                        ai = getAppInfoForUser(ai, userId);
10760                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10761                    } catch (RemoteException ex) {
10762                        // pm is in same process, this will never happen.
10763                    } finally {
10764                        Binder.restoreCallingIdentity(ident);
10765                    }
10766                }
10767
10768                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10769
10770                if (r != null && cpr.canRunHere(r)) {
10771                    // If this is a multiprocess provider, then just return its
10772                    // info and allow the caller to instantiate it.  Only do
10773                    // this if the provider is the same user as the caller's
10774                    // process, or can run as root (so can be in any process).
10775                    return cpr.newHolder(null);
10776                }
10777
10778                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10779                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10780                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10781
10782                // This is single process, and our app is now connecting to it.
10783                // See if we are already in the process of launching this
10784                // provider.
10785                final int N = mLaunchingProviders.size();
10786                int i;
10787                for (i = 0; i < N; i++) {
10788                    if (mLaunchingProviders.get(i) == cpr) {
10789                        break;
10790                    }
10791                }
10792
10793                // If the provider is not already being launched, then get it
10794                // started.
10795                if (i >= N) {
10796                    final long origId = Binder.clearCallingIdentity();
10797
10798                    try {
10799                        // Content provider is now in use, its package can't be stopped.
10800                        try {
10801                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10802                            AppGlobals.getPackageManager().setPackageStoppedState(
10803                                    cpr.appInfo.packageName, false, userId);
10804                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10805                        } catch (RemoteException e) {
10806                        } catch (IllegalArgumentException e) {
10807                            Slog.w(TAG, "Failed trying to unstop package "
10808                                    + cpr.appInfo.packageName + ": " + e);
10809                        }
10810
10811                        // Use existing process if already started
10812                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10813                        ProcessRecord proc = getProcessRecordLocked(
10814                                cpi.processName, cpr.appInfo.uid, false);
10815                        if (proc != null && proc.thread != null && !proc.killed) {
10816                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10817                                    "Installing in existing process " + proc);
10818                            if (!proc.pubProviders.containsKey(cpi.name)) {
10819                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10820                                proc.pubProviders.put(cpi.name, cpr);
10821                                try {
10822                                    proc.thread.scheduleInstallProvider(cpi);
10823                                } catch (RemoteException e) {
10824                                }
10825                            }
10826                        } else {
10827                            checkTime(startTime, "getContentProviderImpl: before start process");
10828                            proc = startProcessLocked(cpi.processName,
10829                                    cpr.appInfo, false, 0, "content provider",
10830                                    new ComponentName(cpi.applicationInfo.packageName,
10831                                            cpi.name), false, false, false);
10832                            checkTime(startTime, "getContentProviderImpl: after start process");
10833                            if (proc == null) {
10834                                Slog.w(TAG, "Unable to launch app "
10835                                        + cpi.applicationInfo.packageName + "/"
10836                                        + cpi.applicationInfo.uid + " for provider "
10837                                        + name + ": process is bad");
10838                                return null;
10839                            }
10840                        }
10841                        cpr.launchingApp = proc;
10842                        mLaunchingProviders.add(cpr);
10843                    } finally {
10844                        Binder.restoreCallingIdentity(origId);
10845                    }
10846                }
10847
10848                checkTime(startTime, "getContentProviderImpl: updating data structures");
10849
10850                // Make sure the provider is published (the same provider class
10851                // may be published under multiple names).
10852                if (firstClass) {
10853                    mProviderMap.putProviderByClass(comp, cpr);
10854                }
10855
10856                mProviderMap.putProviderByName(name, cpr);
10857                conn = incProviderCountLocked(r, cpr, token, stable);
10858                if (conn != null) {
10859                    conn.waiting = true;
10860                }
10861            }
10862            checkTime(startTime, "getContentProviderImpl: done!");
10863        }
10864
10865        // Wait for the provider to be published...
10866        synchronized (cpr) {
10867            while (cpr.provider == null) {
10868                if (cpr.launchingApp == null) {
10869                    Slog.w(TAG, "Unable to launch app "
10870                            + cpi.applicationInfo.packageName + "/"
10871                            + cpi.applicationInfo.uid + " for provider "
10872                            + name + ": launching app became null");
10873                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10874                            UserHandle.getUserId(cpi.applicationInfo.uid),
10875                            cpi.applicationInfo.packageName,
10876                            cpi.applicationInfo.uid, name);
10877                    return null;
10878                }
10879                try {
10880                    if (DEBUG_MU) Slog.v(TAG_MU,
10881                            "Waiting to start provider " + cpr
10882                            + " launchingApp=" + cpr.launchingApp);
10883                    if (conn != null) {
10884                        conn.waiting = true;
10885                    }
10886                    cpr.wait();
10887                } catch (InterruptedException ex) {
10888                } finally {
10889                    if (conn != null) {
10890                        conn.waiting = false;
10891                    }
10892                }
10893            }
10894        }
10895        return cpr != null ? cpr.newHolder(conn) : null;
10896    }
10897
10898    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10899            ProcessRecord r, final int userId) {
10900        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10901                cpi.packageName, userId)) {
10902
10903            final boolean callerForeground = r == null || r.setSchedGroup
10904                    != ProcessList.SCHED_GROUP_BACKGROUND;
10905
10906            // Show a permission review UI only for starting from a foreground app
10907            if (!callerForeground) {
10908                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10909                        + cpi.packageName + " requires a permissions review");
10910                return false;
10911            }
10912
10913            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10914            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10915                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10916            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10917
10918            if (DEBUG_PERMISSIONS_REVIEW) {
10919                Slog.i(TAG, "u" + userId + " Launching permission review "
10920                        + "for package " + cpi.packageName);
10921            }
10922
10923            final UserHandle userHandle = new UserHandle(userId);
10924            mHandler.post(new Runnable() {
10925                @Override
10926                public void run() {
10927                    mContext.startActivityAsUser(intent, userHandle);
10928                }
10929            });
10930
10931            return false;
10932        }
10933
10934        return true;
10935    }
10936
10937    PackageManagerInternal getPackageManagerInternalLocked() {
10938        if (mPackageManagerInt == null) {
10939            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10940        }
10941        return mPackageManagerInt;
10942    }
10943
10944    @Override
10945    public final ContentProviderHolder getContentProvider(
10946            IApplicationThread caller, String name, int userId, boolean stable) {
10947        enforceNotIsolatedCaller("getContentProvider");
10948        if (caller == null) {
10949            String msg = "null IApplicationThread when getting content provider "
10950                    + name;
10951            Slog.w(TAG, msg);
10952            throw new SecurityException(msg);
10953        }
10954        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10955        // with cross-user grant.
10956        return getContentProviderImpl(caller, name, null, stable, userId);
10957    }
10958
10959    public ContentProviderHolder getContentProviderExternal(
10960            String name, int userId, IBinder token) {
10961        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10962            "Do not have permission in call getContentProviderExternal()");
10963        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10964                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10965        return getContentProviderExternalUnchecked(name, token, userId);
10966    }
10967
10968    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10969            IBinder token, int userId) {
10970        return getContentProviderImpl(null, name, token, true, userId);
10971    }
10972
10973    /**
10974     * Drop a content provider from a ProcessRecord's bookkeeping
10975     */
10976    public void removeContentProvider(IBinder connection, boolean stable) {
10977        enforceNotIsolatedCaller("removeContentProvider");
10978        long ident = Binder.clearCallingIdentity();
10979        try {
10980            synchronized (this) {
10981                ContentProviderConnection conn;
10982                try {
10983                    conn = (ContentProviderConnection)connection;
10984                } catch (ClassCastException e) {
10985                    String msg ="removeContentProvider: " + connection
10986                            + " not a ContentProviderConnection";
10987                    Slog.w(TAG, msg);
10988                    throw new IllegalArgumentException(msg);
10989                }
10990                if (conn == null) {
10991                    throw new NullPointerException("connection is null");
10992                }
10993                if (decProviderCountLocked(conn, null, null, stable)) {
10994                    updateOomAdjLocked();
10995                }
10996            }
10997        } finally {
10998            Binder.restoreCallingIdentity(ident);
10999        }
11000    }
11001
11002    public void removeContentProviderExternal(String name, IBinder token) {
11003        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11004            "Do not have permission in call removeContentProviderExternal()");
11005        int userId = UserHandle.getCallingUserId();
11006        long ident = Binder.clearCallingIdentity();
11007        try {
11008            removeContentProviderExternalUnchecked(name, token, userId);
11009        } finally {
11010            Binder.restoreCallingIdentity(ident);
11011        }
11012    }
11013
11014    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11015        synchronized (this) {
11016            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11017            if(cpr == null) {
11018                //remove from mProvidersByClass
11019                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11020                return;
11021            }
11022
11023            //update content provider record entry info
11024            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11025            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11026            if (localCpr.hasExternalProcessHandles()) {
11027                if (localCpr.removeExternalProcessHandleLocked(token)) {
11028                    updateOomAdjLocked();
11029                } else {
11030                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11031                            + " with no external reference for token: "
11032                            + token + ".");
11033                }
11034            } else {
11035                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11036                        + " with no external references.");
11037            }
11038        }
11039    }
11040
11041    public final void publishContentProviders(IApplicationThread caller,
11042            List<ContentProviderHolder> providers) {
11043        if (providers == null) {
11044            return;
11045        }
11046
11047        enforceNotIsolatedCaller("publishContentProviders");
11048        synchronized (this) {
11049            final ProcessRecord r = getRecordForAppLocked(caller);
11050            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11051            if (r == null) {
11052                throw new SecurityException(
11053                        "Unable to find app for caller " + caller
11054                      + " (pid=" + Binder.getCallingPid()
11055                      + ") when publishing content providers");
11056            }
11057
11058            final long origId = Binder.clearCallingIdentity();
11059
11060            final int N = providers.size();
11061            for (int i = 0; i < N; i++) {
11062                ContentProviderHolder src = providers.get(i);
11063                if (src == null || src.info == null || src.provider == null) {
11064                    continue;
11065                }
11066                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11067                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11068                if (dst != null) {
11069                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11070                    mProviderMap.putProviderByClass(comp, dst);
11071                    String names[] = dst.info.authority.split(";");
11072                    for (int j = 0; j < names.length; j++) {
11073                        mProviderMap.putProviderByName(names[j], dst);
11074                    }
11075
11076                    int launchingCount = mLaunchingProviders.size();
11077                    int j;
11078                    boolean wasInLaunchingProviders = false;
11079                    for (j = 0; j < launchingCount; j++) {
11080                        if (mLaunchingProviders.get(j) == dst) {
11081                            mLaunchingProviders.remove(j);
11082                            wasInLaunchingProviders = true;
11083                            j--;
11084                            launchingCount--;
11085                        }
11086                    }
11087                    if (wasInLaunchingProviders) {
11088                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11089                    }
11090                    synchronized (dst) {
11091                        dst.provider = src.provider;
11092                        dst.proc = r;
11093                        dst.notifyAll();
11094                    }
11095                    updateOomAdjLocked(r);
11096                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11097                            src.info.authority);
11098                }
11099            }
11100
11101            Binder.restoreCallingIdentity(origId);
11102        }
11103    }
11104
11105    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11106        ContentProviderConnection conn;
11107        try {
11108            conn = (ContentProviderConnection)connection;
11109        } catch (ClassCastException e) {
11110            String msg ="refContentProvider: " + connection
11111                    + " not a ContentProviderConnection";
11112            Slog.w(TAG, msg);
11113            throw new IllegalArgumentException(msg);
11114        }
11115        if (conn == null) {
11116            throw new NullPointerException("connection is null");
11117        }
11118
11119        synchronized (this) {
11120            if (stable > 0) {
11121                conn.numStableIncs += stable;
11122            }
11123            stable = conn.stableCount + stable;
11124            if (stable < 0) {
11125                throw new IllegalStateException("stableCount < 0: " + stable);
11126            }
11127
11128            if (unstable > 0) {
11129                conn.numUnstableIncs += unstable;
11130            }
11131            unstable = conn.unstableCount + unstable;
11132            if (unstable < 0) {
11133                throw new IllegalStateException("unstableCount < 0: " + unstable);
11134            }
11135
11136            if ((stable+unstable) <= 0) {
11137                throw new IllegalStateException("ref counts can't go to zero here: stable="
11138                        + stable + " unstable=" + unstable);
11139            }
11140            conn.stableCount = stable;
11141            conn.unstableCount = unstable;
11142            return !conn.dead;
11143        }
11144    }
11145
11146    public void unstableProviderDied(IBinder connection) {
11147        ContentProviderConnection conn;
11148        try {
11149            conn = (ContentProviderConnection)connection;
11150        } catch (ClassCastException e) {
11151            String msg ="refContentProvider: " + connection
11152                    + " not a ContentProviderConnection";
11153            Slog.w(TAG, msg);
11154            throw new IllegalArgumentException(msg);
11155        }
11156        if (conn == null) {
11157            throw new NullPointerException("connection is null");
11158        }
11159
11160        // Safely retrieve the content provider associated with the connection.
11161        IContentProvider provider;
11162        synchronized (this) {
11163            provider = conn.provider.provider;
11164        }
11165
11166        if (provider == null) {
11167            // Um, yeah, we're way ahead of you.
11168            return;
11169        }
11170
11171        // Make sure the caller is being honest with us.
11172        if (provider.asBinder().pingBinder()) {
11173            // Er, no, still looks good to us.
11174            synchronized (this) {
11175                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11176                        + " says " + conn + " died, but we don't agree");
11177                return;
11178            }
11179        }
11180
11181        // Well look at that!  It's dead!
11182        synchronized (this) {
11183            if (conn.provider.provider != provider) {
11184                // But something changed...  good enough.
11185                return;
11186            }
11187
11188            ProcessRecord proc = conn.provider.proc;
11189            if (proc == null || proc.thread == null) {
11190                // Seems like the process is already cleaned up.
11191                return;
11192            }
11193
11194            // As far as we're concerned, this is just like receiving a
11195            // death notification...  just a bit prematurely.
11196            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11197                    + ") early provider death");
11198            final long ident = Binder.clearCallingIdentity();
11199            try {
11200                appDiedLocked(proc);
11201            } finally {
11202                Binder.restoreCallingIdentity(ident);
11203            }
11204        }
11205    }
11206
11207    @Override
11208    public void appNotRespondingViaProvider(IBinder connection) {
11209        enforceCallingPermission(
11210                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11211
11212        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11213        if (conn == null) {
11214            Slog.w(TAG, "ContentProviderConnection is null");
11215            return;
11216        }
11217
11218        final ProcessRecord host = conn.provider.proc;
11219        if (host == null) {
11220            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11221            return;
11222        }
11223
11224        mHandler.post(new Runnable() {
11225            @Override
11226            public void run() {
11227                mAppErrors.appNotResponding(host, null, null, false,
11228                        "ContentProvider not responding");
11229            }
11230        });
11231    }
11232
11233    public final void installSystemProviders() {
11234        List<ProviderInfo> providers;
11235        synchronized (this) {
11236            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11237            providers = generateApplicationProvidersLocked(app);
11238            if (providers != null) {
11239                for (int i=providers.size()-1; i>=0; i--) {
11240                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11241                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11242                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11243                                + ": not system .apk");
11244                        providers.remove(i);
11245                    }
11246                }
11247            }
11248        }
11249        if (providers != null) {
11250            mSystemThread.installSystemProviders(providers);
11251        }
11252
11253        mCoreSettingsObserver = new CoreSettingsObserver(this);
11254        mFontScaleSettingObserver = new FontScaleSettingObserver();
11255
11256        //mUsageStatsService.monitorPackages();
11257    }
11258
11259    private void startPersistentApps(int matchFlags) {
11260        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11261
11262        synchronized (this) {
11263            try {
11264                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11265                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11266                for (ApplicationInfo app : apps) {
11267                    if (!"android".equals(app.packageName)) {
11268                        addAppLocked(app, false, null /* ABI override */);
11269                    }
11270                }
11271            } catch (RemoteException ex) {
11272            }
11273        }
11274    }
11275
11276    /**
11277     * When a user is unlocked, we need to install encryption-unaware providers
11278     * belonging to any running apps.
11279     */
11280    private void installEncryptionUnawareProviders(int userId) {
11281        // We're only interested in providers that are encryption unaware, and
11282        // we don't care about uninstalled apps, since there's no way they're
11283        // running at this point.
11284        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11285
11286        synchronized (this) {
11287            final int NP = mProcessNames.getMap().size();
11288            for (int ip = 0; ip < NP; ip++) {
11289                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11290                final int NA = apps.size();
11291                for (int ia = 0; ia < NA; ia++) {
11292                    final ProcessRecord app = apps.valueAt(ia);
11293                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11294
11295                    final int NG = app.pkgList.size();
11296                    for (int ig = 0; ig < NG; ig++) {
11297                        try {
11298                            final String pkgName = app.pkgList.keyAt(ig);
11299                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11300                                    .getPackageInfo(pkgName, matchFlags, userId);
11301                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11302                                for (ProviderInfo pi : pkgInfo.providers) {
11303                                    // TODO: keep in sync with generateApplicationProvidersLocked
11304                                    final boolean processMatch = Objects.equals(pi.processName,
11305                                            app.processName) || pi.multiprocess;
11306                                    final boolean userMatch = isSingleton(pi.processName,
11307                                            pi.applicationInfo, pi.name, pi.flags)
11308                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11309                                    if (processMatch && userMatch) {
11310                                        Log.v(TAG, "Installing " + pi);
11311                                        app.thread.scheduleInstallProvider(pi);
11312                                    } else {
11313                                        Log.v(TAG, "Skipping " + pi);
11314                                    }
11315                                }
11316                            }
11317                        } catch (RemoteException ignored) {
11318                        }
11319                    }
11320                }
11321            }
11322        }
11323    }
11324
11325    /**
11326     * Allows apps to retrieve the MIME type of a URI.
11327     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11328     * users, then it does not need permission to access the ContentProvider.
11329     * Either, it needs cross-user uri grants.
11330     *
11331     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11332     *
11333     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11334     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11335     */
11336    public String getProviderMimeType(Uri uri, int userId) {
11337        enforceNotIsolatedCaller("getProviderMimeType");
11338        final String name = uri.getAuthority();
11339        int callingUid = Binder.getCallingUid();
11340        int callingPid = Binder.getCallingPid();
11341        long ident = 0;
11342        boolean clearedIdentity = false;
11343        synchronized (this) {
11344            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11345        }
11346        if (canClearIdentity(callingPid, callingUid, userId)) {
11347            clearedIdentity = true;
11348            ident = Binder.clearCallingIdentity();
11349        }
11350        ContentProviderHolder holder = null;
11351        try {
11352            holder = getContentProviderExternalUnchecked(name, null, userId);
11353            if (holder != null) {
11354                return holder.provider.getType(uri);
11355            }
11356        } catch (RemoteException e) {
11357            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11358            return null;
11359        } catch (Exception e) {
11360            Log.w(TAG, "Exception while determining type of " + uri, e);
11361            return null;
11362        } finally {
11363            // We need to clear the identity to call removeContentProviderExternalUnchecked
11364            if (!clearedIdentity) {
11365                ident = Binder.clearCallingIdentity();
11366            }
11367            try {
11368                if (holder != null) {
11369                    removeContentProviderExternalUnchecked(name, null, userId);
11370                }
11371            } finally {
11372                Binder.restoreCallingIdentity(ident);
11373            }
11374        }
11375
11376        return null;
11377    }
11378
11379    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11380        if (UserHandle.getUserId(callingUid) == userId) {
11381            return true;
11382        }
11383        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11384                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11385                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11386                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11387                return true;
11388        }
11389        return false;
11390    }
11391
11392    // =========================================================
11393    // GLOBAL MANAGEMENT
11394    // =========================================================
11395
11396    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11397            boolean isolated, int isolatedUid) {
11398        String proc = customProcess != null ? customProcess : info.processName;
11399        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11400        final int userId = UserHandle.getUserId(info.uid);
11401        int uid = info.uid;
11402        if (isolated) {
11403            if (isolatedUid == 0) {
11404                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11405                while (true) {
11406                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11407                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11408                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11409                    }
11410                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11411                    mNextIsolatedProcessUid++;
11412                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11413                        // No process for this uid, use it.
11414                        break;
11415                    }
11416                    stepsLeft--;
11417                    if (stepsLeft <= 0) {
11418                        return null;
11419                    }
11420                }
11421            } else {
11422                // Special case for startIsolatedProcess (internal only), where
11423                // the uid of the isolated process is specified by the caller.
11424                uid = isolatedUid;
11425            }
11426        }
11427        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11428        if (!mBooted && !mBooting
11429                && userId == UserHandle.USER_SYSTEM
11430                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11431            r.persistent = true;
11432        }
11433        addProcessNameLocked(r);
11434        return r;
11435    }
11436
11437    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11438            String abiOverride) {
11439        ProcessRecord app;
11440        if (!isolated) {
11441            app = getProcessRecordLocked(info.processName, info.uid, true);
11442        } else {
11443            app = null;
11444        }
11445
11446        if (app == null) {
11447            app = newProcessRecordLocked(info, null, isolated, 0);
11448            updateLruProcessLocked(app, false, null);
11449            updateOomAdjLocked();
11450        }
11451
11452        // This package really, really can not be stopped.
11453        try {
11454            AppGlobals.getPackageManager().setPackageStoppedState(
11455                    info.packageName, false, UserHandle.getUserId(app.uid));
11456        } catch (RemoteException e) {
11457        } catch (IllegalArgumentException e) {
11458            Slog.w(TAG, "Failed trying to unstop package "
11459                    + info.packageName + ": " + e);
11460        }
11461
11462        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11463            app.persistent = true;
11464            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11465        }
11466        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11467            mPersistentStartingProcesses.add(app);
11468            startProcessLocked(app, "added application", app.processName, abiOverride,
11469                    null /* entryPoint */, null /* entryPointArgs */);
11470        }
11471
11472        return app;
11473    }
11474
11475    public void unhandledBack() {
11476        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11477                "unhandledBack()");
11478
11479        synchronized(this) {
11480            final long origId = Binder.clearCallingIdentity();
11481            try {
11482                getFocusedStack().unhandledBackLocked();
11483            } finally {
11484                Binder.restoreCallingIdentity(origId);
11485            }
11486        }
11487    }
11488
11489    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11490        enforceNotIsolatedCaller("openContentUri");
11491        final int userId = UserHandle.getCallingUserId();
11492        String name = uri.getAuthority();
11493        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11494        ParcelFileDescriptor pfd = null;
11495        if (cph != null) {
11496            // We record the binder invoker's uid in thread-local storage before
11497            // going to the content provider to open the file.  Later, in the code
11498            // that handles all permissions checks, we look for this uid and use
11499            // that rather than the Activity Manager's own uid.  The effect is that
11500            // we do the check against the caller's permissions even though it looks
11501            // to the content provider like the Activity Manager itself is making
11502            // the request.
11503            Binder token = new Binder();
11504            sCallerIdentity.set(new Identity(
11505                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11506            try {
11507                pfd = cph.provider.openFile(null, uri, "r", null, token);
11508            } catch (FileNotFoundException e) {
11509                // do nothing; pfd will be returned null
11510            } finally {
11511                // Ensure that whatever happens, we clean up the identity state
11512                sCallerIdentity.remove();
11513                // Ensure we're done with the provider.
11514                removeContentProviderExternalUnchecked(name, null, userId);
11515            }
11516        } else {
11517            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11518        }
11519        return pfd;
11520    }
11521
11522    // Actually is sleeping or shutting down or whatever else in the future
11523    // is an inactive state.
11524    boolean isSleepingOrShuttingDownLocked() {
11525        return isSleepingLocked() || mShuttingDown;
11526    }
11527
11528    boolean isShuttingDownLocked() {
11529        return mShuttingDown;
11530    }
11531
11532    boolean isSleepingLocked() {
11533        return mSleeping;
11534    }
11535
11536    void onWakefulnessChanged(int wakefulness) {
11537        synchronized(this) {
11538            mWakefulness = wakefulness;
11539            updateSleepIfNeededLocked();
11540        }
11541    }
11542
11543    void finishRunningVoiceLocked() {
11544        if (mRunningVoice != null) {
11545            mRunningVoice = null;
11546            mVoiceWakeLock.release();
11547            updateSleepIfNeededLocked();
11548        }
11549    }
11550
11551    void startTimeTrackingFocusedActivityLocked() {
11552        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11553            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11554        }
11555    }
11556
11557    void updateSleepIfNeededLocked() {
11558        if (mSleeping && !shouldSleepLocked()) {
11559            mSleeping = false;
11560            startTimeTrackingFocusedActivityLocked();
11561            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11562            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11563            updateOomAdjLocked();
11564        } else if (!mSleeping && shouldSleepLocked()) {
11565            mSleeping = true;
11566            if (mCurAppTimeTracker != null) {
11567                mCurAppTimeTracker.stop();
11568            }
11569            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11570            mStackSupervisor.goingToSleepLocked();
11571            updateOomAdjLocked();
11572
11573            // Initialize the wake times of all processes.
11574            checkExcessivePowerUsageLocked(false);
11575            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11576            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11577            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11578        }
11579    }
11580
11581    private boolean shouldSleepLocked() {
11582        // Resume applications while running a voice interactor.
11583        if (mRunningVoice != null) {
11584            return false;
11585        }
11586
11587        // TODO: Transform the lock screen state into a sleep token instead.
11588        switch (mWakefulness) {
11589            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11590            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11591            case PowerManagerInternal.WAKEFULNESS_DOZING:
11592                // Pause applications whenever the lock screen is shown or any sleep
11593                // tokens have been acquired.
11594                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11595            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11596            default:
11597                // If we're asleep then pause applications unconditionally.
11598                return true;
11599        }
11600    }
11601
11602    /** Pokes the task persister. */
11603    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11604        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11605    }
11606
11607    /** Notifies all listeners when the task stack has changed. */
11608    void notifyTaskStackChangedLocked() {
11609        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11610        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11611        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11612        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11613    }
11614
11615    /** Notifies all listeners when an Activity is pinned. */
11616    void notifyActivityPinnedLocked() {
11617        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11618        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11619    }
11620
11621    /**
11622     * Notifies all listeners when an attempt was made to start an an activity that is already
11623     * running in the pinned stack and the activity was not actually started, but the task is
11624     * either brought to the front or a new Intent is delivered to it.
11625     */
11626    void notifyPinnedActivityRestartAttemptLocked() {
11627        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11628        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11629    }
11630
11631    /** Notifies all listeners when the pinned stack animation ends. */
11632    @Override
11633    public void notifyPinnedStackAnimationEnded() {
11634        synchronized (this) {
11635            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11636            mHandler.obtainMessage(
11637                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11638        }
11639    }
11640
11641    @Override
11642    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11643        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11644    }
11645
11646    @Override
11647    public boolean shutdown(int timeout) {
11648        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11649                != PackageManager.PERMISSION_GRANTED) {
11650            throw new SecurityException("Requires permission "
11651                    + android.Manifest.permission.SHUTDOWN);
11652        }
11653
11654        boolean timedout = false;
11655
11656        synchronized(this) {
11657            mShuttingDown = true;
11658            updateEventDispatchingLocked();
11659            timedout = mStackSupervisor.shutdownLocked(timeout);
11660        }
11661
11662        mAppOpsService.shutdown();
11663        if (mUsageStatsService != null) {
11664            mUsageStatsService.prepareShutdown();
11665        }
11666        mBatteryStatsService.shutdown();
11667        synchronized (this) {
11668            mProcessStats.shutdownLocked();
11669            notifyTaskPersisterLocked(null, true);
11670        }
11671
11672        return timedout;
11673    }
11674
11675    public final void activitySlept(IBinder token) {
11676        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11677
11678        final long origId = Binder.clearCallingIdentity();
11679
11680        synchronized (this) {
11681            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11682            if (r != null) {
11683                mStackSupervisor.activitySleptLocked(r);
11684            }
11685        }
11686
11687        Binder.restoreCallingIdentity(origId);
11688    }
11689
11690    private String lockScreenShownToString() {
11691        switch (mLockScreenShown) {
11692            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11693            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11694            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11695            default: return "Unknown=" + mLockScreenShown;
11696        }
11697    }
11698
11699    void logLockScreen(String msg) {
11700        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11701                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11702                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11703                + " mSleeping=" + mSleeping);
11704    }
11705
11706    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11707        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11708        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11709        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11710            boolean wasRunningVoice = mRunningVoice != null;
11711            mRunningVoice = session;
11712            if (!wasRunningVoice) {
11713                mVoiceWakeLock.acquire();
11714                updateSleepIfNeededLocked();
11715            }
11716        }
11717    }
11718
11719    private void updateEventDispatchingLocked() {
11720        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11721    }
11722
11723    public void setLockScreenShown(boolean showing, boolean occluded) {
11724        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11725                != PackageManager.PERMISSION_GRANTED) {
11726            throw new SecurityException("Requires permission "
11727                    + android.Manifest.permission.DEVICE_POWER);
11728        }
11729
11730        synchronized(this) {
11731            long ident = Binder.clearCallingIdentity();
11732            try {
11733                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11734                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11735                if (showing && occluded) {
11736                    // The lock screen is currently showing, but is occluded by a window that can
11737                    // show on top of the lock screen. In this can we want to dismiss the docked
11738                    // stack since it will be complicated/risky to try to put the activity on top
11739                    // of the lock screen in the right fullscreen configuration.
11740                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11741                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11742                }
11743
11744                updateSleepIfNeededLocked();
11745            } finally {
11746                Binder.restoreCallingIdentity(ident);
11747            }
11748        }
11749    }
11750
11751    @Override
11752    public void notifyLockedProfile(@UserIdInt int userId) {
11753        try {
11754            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11755                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11756            }
11757        } catch (RemoteException ex) {
11758            throw new SecurityException("Fail to check is caller a privileged app", ex);
11759        }
11760
11761        synchronized (this) {
11762            if (mStackSupervisor.isUserLockedProfile(userId)) {
11763                final long ident = Binder.clearCallingIdentity();
11764                try {
11765                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11766                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11767                        // If there is no device lock, we will show the profile's credential page.
11768                        mActivityStarter.showConfirmDeviceCredential(userId);
11769                    } else {
11770                        // Showing launcher to avoid user entering credential twice.
11771                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11772                    }
11773                } finally {
11774                    Binder.restoreCallingIdentity(ident);
11775                }
11776            }
11777        }
11778    }
11779
11780    @Override
11781    public void startConfirmDeviceCredentialIntent(Intent intent) {
11782        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11783        synchronized (this) {
11784            final long ident = Binder.clearCallingIdentity();
11785            try {
11786                mActivityStarter.startConfirmCredentialIntent(intent);
11787            } finally {
11788                Binder.restoreCallingIdentity(ident);
11789            }
11790        }
11791    }
11792
11793    @Override
11794    public void stopAppSwitches() {
11795        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11796                != PackageManager.PERMISSION_GRANTED) {
11797            throw new SecurityException("viewquires permission "
11798                    + android.Manifest.permission.STOP_APP_SWITCHES);
11799        }
11800
11801        synchronized(this) {
11802            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11803                    + APP_SWITCH_DELAY_TIME;
11804            mDidAppSwitch = false;
11805            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11806            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11807            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11808        }
11809    }
11810
11811    public void resumeAppSwitches() {
11812        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11813                != PackageManager.PERMISSION_GRANTED) {
11814            throw new SecurityException("Requires permission "
11815                    + android.Manifest.permission.STOP_APP_SWITCHES);
11816        }
11817
11818        synchronized(this) {
11819            // Note that we don't execute any pending app switches... we will
11820            // let those wait until either the timeout, or the next start
11821            // activity request.
11822            mAppSwitchesAllowedTime = 0;
11823        }
11824    }
11825
11826    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11827            int callingPid, int callingUid, String name) {
11828        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11829            return true;
11830        }
11831
11832        int perm = checkComponentPermission(
11833                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11834                sourceUid, -1, true);
11835        if (perm == PackageManager.PERMISSION_GRANTED) {
11836            return true;
11837        }
11838
11839        // If the actual IPC caller is different from the logical source, then
11840        // also see if they are allowed to control app switches.
11841        if (callingUid != -1 && callingUid != sourceUid) {
11842            perm = checkComponentPermission(
11843                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11844                    callingUid, -1, true);
11845            if (perm == PackageManager.PERMISSION_GRANTED) {
11846                return true;
11847            }
11848        }
11849
11850        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11851        return false;
11852    }
11853
11854    public void setDebugApp(String packageName, boolean waitForDebugger,
11855            boolean persistent) {
11856        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11857                "setDebugApp()");
11858
11859        long ident = Binder.clearCallingIdentity();
11860        try {
11861            // Note that this is not really thread safe if there are multiple
11862            // callers into it at the same time, but that's not a situation we
11863            // care about.
11864            if (persistent) {
11865                final ContentResolver resolver = mContext.getContentResolver();
11866                Settings.Global.putString(
11867                    resolver, Settings.Global.DEBUG_APP,
11868                    packageName);
11869                Settings.Global.putInt(
11870                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11871                    waitForDebugger ? 1 : 0);
11872            }
11873
11874            synchronized (this) {
11875                if (!persistent) {
11876                    mOrigDebugApp = mDebugApp;
11877                    mOrigWaitForDebugger = mWaitForDebugger;
11878                }
11879                mDebugApp = packageName;
11880                mWaitForDebugger = waitForDebugger;
11881                mDebugTransient = !persistent;
11882                if (packageName != null) {
11883                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11884                            false, UserHandle.USER_ALL, "set debug app");
11885                }
11886            }
11887        } finally {
11888            Binder.restoreCallingIdentity(ident);
11889        }
11890    }
11891
11892    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11893        synchronized (this) {
11894            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11895            if (!isDebuggable) {
11896                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11897                    throw new SecurityException("Process not debuggable: " + app.packageName);
11898                }
11899            }
11900
11901            mTrackAllocationApp = processName;
11902        }
11903    }
11904
11905    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11906        synchronized (this) {
11907            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11908            if (!isDebuggable) {
11909                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11910                    throw new SecurityException("Process not debuggable: " + app.packageName);
11911                }
11912            }
11913            mProfileApp = processName;
11914            mProfileFile = profilerInfo.profileFile;
11915            if (mProfileFd != null) {
11916                try {
11917                    mProfileFd.close();
11918                } catch (IOException e) {
11919                }
11920                mProfileFd = null;
11921            }
11922            mProfileFd = profilerInfo.profileFd;
11923            mSamplingInterval = profilerInfo.samplingInterval;
11924            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11925            mProfileType = 0;
11926        }
11927    }
11928
11929    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11930        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11931        if (!isDebuggable) {
11932            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11933                throw new SecurityException("Process not debuggable: " + app.packageName);
11934            }
11935        }
11936        mNativeDebuggingApp = processName;
11937    }
11938
11939    @Override
11940    public void setAlwaysFinish(boolean enabled) {
11941        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11942                "setAlwaysFinish()");
11943
11944        long ident = Binder.clearCallingIdentity();
11945        try {
11946            Settings.Global.putInt(
11947                    mContext.getContentResolver(),
11948                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11949
11950            synchronized (this) {
11951                mAlwaysFinishActivities = enabled;
11952            }
11953        } finally {
11954            Binder.restoreCallingIdentity(ident);
11955        }
11956    }
11957
11958    @Override
11959    public void setLenientBackgroundCheck(boolean enabled) {
11960        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11961                "setLenientBackgroundCheck()");
11962
11963        long ident = Binder.clearCallingIdentity();
11964        try {
11965            Settings.Global.putInt(
11966                    mContext.getContentResolver(),
11967                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11968
11969            synchronized (this) {
11970                mLenientBackgroundCheck = enabled;
11971            }
11972        } finally {
11973            Binder.restoreCallingIdentity(ident);
11974        }
11975    }
11976
11977    @Override
11978    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11979        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11980                "setActivityController()");
11981        synchronized (this) {
11982            mController = controller;
11983            mControllerIsAMonkey = imAMonkey;
11984            Watchdog.getInstance().setActivityController(controller);
11985        }
11986    }
11987
11988    @Override
11989    public void setUserIsMonkey(boolean userIsMonkey) {
11990        synchronized (this) {
11991            synchronized (mPidsSelfLocked) {
11992                final int callingPid = Binder.getCallingPid();
11993                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11994                if (precessRecord == null) {
11995                    throw new SecurityException("Unknown process: " + callingPid);
11996                }
11997                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11998                    throw new SecurityException("Only an instrumentation process "
11999                            + "with a UiAutomation can call setUserIsMonkey");
12000                }
12001            }
12002            mUserIsMonkey = userIsMonkey;
12003        }
12004    }
12005
12006    @Override
12007    public boolean isUserAMonkey() {
12008        synchronized (this) {
12009            // If there is a controller also implies the user is a monkey.
12010            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12011        }
12012    }
12013
12014    public void requestBugReport(int bugreportType) {
12015        String service = null;
12016        switch (bugreportType) {
12017            case ActivityManager.BUGREPORT_OPTION_FULL:
12018                service = "bugreport";
12019                break;
12020            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12021                service = "bugreportplus";
12022                break;
12023            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12024                service = "bugreportremote";
12025                break;
12026        }
12027        if (service == null) {
12028            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12029                    + bugreportType);
12030        }
12031        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12032        SystemProperties.set("ctl.start", service);
12033    }
12034
12035    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12036        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12037    }
12038
12039    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12040        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12041            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12042        }
12043        return KEY_DISPATCHING_TIMEOUT;
12044    }
12045
12046    @Override
12047    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12048        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12049                != PackageManager.PERMISSION_GRANTED) {
12050            throw new SecurityException("Requires permission "
12051                    + android.Manifest.permission.FILTER_EVENTS);
12052        }
12053        ProcessRecord proc;
12054        long timeout;
12055        synchronized (this) {
12056            synchronized (mPidsSelfLocked) {
12057                proc = mPidsSelfLocked.get(pid);
12058            }
12059            timeout = getInputDispatchingTimeoutLocked(proc);
12060        }
12061
12062        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12063            return -1;
12064        }
12065
12066        return timeout;
12067    }
12068
12069    /**
12070     * Handle input dispatching timeouts.
12071     * Returns whether input dispatching should be aborted or not.
12072     */
12073    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12074            final ActivityRecord activity, final ActivityRecord parent,
12075            final boolean aboveSystem, String reason) {
12076        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12077                != PackageManager.PERMISSION_GRANTED) {
12078            throw new SecurityException("Requires permission "
12079                    + android.Manifest.permission.FILTER_EVENTS);
12080        }
12081
12082        final String annotation;
12083        if (reason == null) {
12084            annotation = "Input dispatching timed out";
12085        } else {
12086            annotation = "Input dispatching timed out (" + reason + ")";
12087        }
12088
12089        if (proc != null) {
12090            synchronized (this) {
12091                if (proc.debugging) {
12092                    return false;
12093                }
12094
12095                if (mDidDexOpt) {
12096                    // Give more time since we were dexopting.
12097                    mDidDexOpt = false;
12098                    return false;
12099                }
12100
12101                if (proc.instrumentationClass != null) {
12102                    Bundle info = new Bundle();
12103                    info.putString("shortMsg", "keyDispatchingTimedOut");
12104                    info.putString("longMsg", annotation);
12105                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12106                    return true;
12107                }
12108            }
12109            mHandler.post(new Runnable() {
12110                @Override
12111                public void run() {
12112                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12113                }
12114            });
12115        }
12116
12117        return true;
12118    }
12119
12120    @Override
12121    public Bundle getAssistContextExtras(int requestType) {
12122        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12123                null, null, true /* focused */, true /* newSessionId */,
12124                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12125        if (pae == null) {
12126            return null;
12127        }
12128        synchronized (pae) {
12129            while (!pae.haveResult) {
12130                try {
12131                    pae.wait();
12132                } catch (InterruptedException e) {
12133                }
12134            }
12135        }
12136        synchronized (this) {
12137            buildAssistBundleLocked(pae, pae.result);
12138            mPendingAssistExtras.remove(pae);
12139            mUiHandler.removeCallbacks(pae);
12140        }
12141        return pae.extras;
12142    }
12143
12144    @Override
12145    public boolean isAssistDataAllowedOnCurrentActivity() {
12146        int userId;
12147        synchronized (this) {
12148            userId = mUserController.getCurrentUserIdLocked();
12149            ActivityRecord activity = getFocusedStack().topActivity();
12150            if (activity == null) {
12151                return false;
12152            }
12153            userId = activity.userId;
12154        }
12155        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12156                Context.DEVICE_POLICY_SERVICE);
12157        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12158    }
12159
12160    @Override
12161    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12162        long ident = Binder.clearCallingIdentity();
12163        try {
12164            synchronized (this) {
12165                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12166                ActivityRecord top = getFocusedStack().topActivity();
12167                if (top != caller) {
12168                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12169                            + " is not current top " + top);
12170                    return false;
12171                }
12172                if (!top.nowVisible) {
12173                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12174                            + " is not visible");
12175                    return false;
12176                }
12177            }
12178            AssistUtils utils = new AssistUtils(mContext);
12179            return utils.showSessionForActiveService(args,
12180                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12181        } finally {
12182            Binder.restoreCallingIdentity(ident);
12183        }
12184    }
12185
12186    @Override
12187    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12188            Bundle receiverExtras,
12189            IBinder activityToken, boolean focused, boolean newSessionId) {
12190        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12191                activityToken, focused, newSessionId,
12192                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12193                != null;
12194    }
12195
12196    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12197            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12198            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12199        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12200                "enqueueAssistContext()");
12201        synchronized (this) {
12202            ActivityRecord activity = getFocusedStack().topActivity();
12203            if (activity == null) {
12204                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12205                return null;
12206            }
12207            if (activity.app == null || activity.app.thread == null) {
12208                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12209                return null;
12210            }
12211            if (focused) {
12212                if (activityToken != null) {
12213                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12214                    if (activity != caller) {
12215                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12216                                + " is not current top " + activity);
12217                        return null;
12218                    }
12219                }
12220            } else {
12221                activity = ActivityRecord.forTokenLocked(activityToken);
12222                if (activity == null) {
12223                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12224                            + " couldn't be found");
12225                    return null;
12226                }
12227            }
12228
12229            PendingAssistExtras pae;
12230            Bundle extras = new Bundle();
12231            if (args != null) {
12232                extras.putAll(args);
12233            }
12234            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12235            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12236            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12237                    userHandle);
12238            // Increment the sessionId if necessary
12239            if (newSessionId) {
12240                mViSessionId++;
12241            }
12242            try {
12243                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12244                        requestType, mViSessionId);
12245                mPendingAssistExtras.add(pae);
12246                mUiHandler.postDelayed(pae, timeout);
12247            } catch (RemoteException e) {
12248                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12249                return null;
12250            }
12251            return pae;
12252        }
12253    }
12254
12255    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12256        IResultReceiver receiver;
12257        synchronized (this) {
12258            mPendingAssistExtras.remove(pae);
12259            receiver = pae.receiver;
12260        }
12261        if (receiver != null) {
12262            // Caller wants result sent back to them.
12263            Bundle sendBundle = new Bundle();
12264            // At least return the receiver extras
12265            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12266                    pae.receiverExtras);
12267            try {
12268                pae.receiver.send(0, sendBundle);
12269            } catch (RemoteException e) {
12270            }
12271        }
12272    }
12273
12274    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12275        if (result != null) {
12276            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12277        }
12278        if (pae.hint != null) {
12279            pae.extras.putBoolean(pae.hint, true);
12280        }
12281    }
12282
12283    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12284            AssistContent content, Uri referrer) {
12285        PendingAssistExtras pae = (PendingAssistExtras)token;
12286        synchronized (pae) {
12287            pae.result = extras;
12288            pae.structure = structure;
12289            pae.content = content;
12290            if (referrer != null) {
12291                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12292            }
12293            pae.haveResult = true;
12294            pae.notifyAll();
12295            if (pae.intent == null && pae.receiver == null) {
12296                // Caller is just waiting for the result.
12297                return;
12298            }
12299        }
12300
12301        // We are now ready to launch the assist activity.
12302        IResultReceiver sendReceiver = null;
12303        Bundle sendBundle = null;
12304        synchronized (this) {
12305            buildAssistBundleLocked(pae, extras);
12306            boolean exists = mPendingAssistExtras.remove(pae);
12307            mUiHandler.removeCallbacks(pae);
12308            if (!exists) {
12309                // Timed out.
12310                return;
12311            }
12312            if ((sendReceiver=pae.receiver) != null) {
12313                // Caller wants result sent back to them.
12314                sendBundle = new Bundle();
12315                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12316                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12317                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12318                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12319                        pae.receiverExtras);
12320            }
12321        }
12322        if (sendReceiver != null) {
12323            try {
12324                sendReceiver.send(0, sendBundle);
12325            } catch (RemoteException e) {
12326            }
12327            return;
12328        }
12329
12330        long ident = Binder.clearCallingIdentity();
12331        try {
12332            pae.intent.replaceExtras(pae.extras);
12333            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12334                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12335                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12336            closeSystemDialogs("assist");
12337            try {
12338                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12339            } catch (ActivityNotFoundException e) {
12340                Slog.w(TAG, "No activity to handle assist action.", e);
12341            }
12342        } finally {
12343            Binder.restoreCallingIdentity(ident);
12344        }
12345    }
12346
12347    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12348            Bundle args) {
12349        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12350                true /* focused */, true /* newSessionId */,
12351                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12352    }
12353
12354    public void registerProcessObserver(IProcessObserver observer) {
12355        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12356                "registerProcessObserver()");
12357        synchronized (this) {
12358            mProcessObservers.register(observer);
12359        }
12360    }
12361
12362    @Override
12363    public void unregisterProcessObserver(IProcessObserver observer) {
12364        synchronized (this) {
12365            mProcessObservers.unregister(observer);
12366        }
12367    }
12368
12369    @Override
12370    public void registerUidObserver(IUidObserver observer, int which) {
12371        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12372                "registerUidObserver()");
12373        synchronized (this) {
12374            mUidObservers.register(observer, which);
12375        }
12376    }
12377
12378    @Override
12379    public void unregisterUidObserver(IUidObserver observer) {
12380        synchronized (this) {
12381            mUidObservers.unregister(observer);
12382        }
12383    }
12384
12385    @Override
12386    public boolean convertFromTranslucent(IBinder token) {
12387        final long origId = Binder.clearCallingIdentity();
12388        try {
12389            synchronized (this) {
12390                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12391                if (r == null) {
12392                    return false;
12393                }
12394                final boolean translucentChanged = r.changeWindowTranslucency(true);
12395                if (translucentChanged) {
12396                    r.task.stack.releaseBackgroundResources(r);
12397                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12398                }
12399                mWindowManager.setAppFullscreen(token, true);
12400                return translucentChanged;
12401            }
12402        } finally {
12403            Binder.restoreCallingIdentity(origId);
12404        }
12405    }
12406
12407    @Override
12408    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12409        final long origId = Binder.clearCallingIdentity();
12410        try {
12411            synchronized (this) {
12412                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12413                if (r == null) {
12414                    return false;
12415                }
12416                int index = r.task.mActivities.lastIndexOf(r);
12417                if (index > 0) {
12418                    ActivityRecord under = r.task.mActivities.get(index - 1);
12419                    under.returningOptions = options;
12420                }
12421                final boolean translucentChanged = r.changeWindowTranslucency(false);
12422                if (translucentChanged) {
12423                    r.task.stack.convertActivityToTranslucent(r);
12424                }
12425                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12426                mWindowManager.setAppFullscreen(token, false);
12427                return translucentChanged;
12428            }
12429        } finally {
12430            Binder.restoreCallingIdentity(origId);
12431        }
12432    }
12433
12434    @Override
12435    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12436        final long origId = Binder.clearCallingIdentity();
12437        try {
12438            synchronized (this) {
12439                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12440                if (r != null) {
12441                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12442                }
12443            }
12444            return false;
12445        } finally {
12446            Binder.restoreCallingIdentity(origId);
12447        }
12448    }
12449
12450    @Override
12451    public boolean isBackgroundVisibleBehind(IBinder token) {
12452        final long origId = Binder.clearCallingIdentity();
12453        try {
12454            synchronized (this) {
12455                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12456                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12457                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12458                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12459                return visible;
12460            }
12461        } finally {
12462            Binder.restoreCallingIdentity(origId);
12463        }
12464    }
12465
12466    @Override
12467    public ActivityOptions getActivityOptions(IBinder token) {
12468        final long origId = Binder.clearCallingIdentity();
12469        try {
12470            synchronized (this) {
12471                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12472                if (r != null) {
12473                    final ActivityOptions activityOptions = r.pendingOptions;
12474                    r.pendingOptions = null;
12475                    return activityOptions;
12476                }
12477                return null;
12478            }
12479        } finally {
12480            Binder.restoreCallingIdentity(origId);
12481        }
12482    }
12483
12484    @Override
12485    public void setImmersive(IBinder token, boolean immersive) {
12486        synchronized(this) {
12487            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12488            if (r == null) {
12489                throw new IllegalArgumentException();
12490            }
12491            r.immersive = immersive;
12492
12493            // update associated state if we're frontmost
12494            if (r == mFocusedActivity) {
12495                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12496                applyUpdateLockStateLocked(r);
12497            }
12498        }
12499    }
12500
12501    @Override
12502    public boolean isImmersive(IBinder token) {
12503        synchronized (this) {
12504            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12505            if (r == null) {
12506                throw new IllegalArgumentException();
12507            }
12508            return r.immersive;
12509        }
12510    }
12511
12512    @Override
12513    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12514        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12515            throw new UnsupportedOperationException("VR mode not supported on this device!");
12516        }
12517
12518        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12519
12520        ActivityRecord r;
12521        synchronized (this) {
12522            r = ActivityRecord.isInStackLocked(token);
12523        }
12524
12525        if (r == null) {
12526            throw new IllegalArgumentException();
12527        }
12528
12529        int err;
12530        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12531                VrManagerInternal.NO_ERROR) {
12532            return err;
12533        }
12534
12535        synchronized(this) {
12536            r.requestedVrComponent = (enabled) ? packageName : null;
12537
12538            // Update associated state if this activity is currently focused
12539            if (r == mFocusedActivity) {
12540                applyUpdateVrModeLocked(r);
12541            }
12542            return 0;
12543        }
12544    }
12545
12546    @Override
12547    public boolean isVrModePackageEnabled(ComponentName packageName) {
12548        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12549            throw new UnsupportedOperationException("VR mode not supported on this device!");
12550        }
12551
12552        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12553
12554        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12555                VrManagerInternal.NO_ERROR;
12556    }
12557
12558    public boolean isTopActivityImmersive() {
12559        enforceNotIsolatedCaller("startActivity");
12560        synchronized (this) {
12561            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12562            return (r != null) ? r.immersive : false;
12563        }
12564    }
12565
12566    @Override
12567    public boolean isTopOfTask(IBinder token) {
12568        synchronized (this) {
12569            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12570            if (r == null) {
12571                throw new IllegalArgumentException();
12572            }
12573            return r.task.getTopActivity() == r;
12574        }
12575    }
12576
12577    public final void enterSafeMode() {
12578        synchronized(this) {
12579            // It only makes sense to do this before the system is ready
12580            // and started launching other packages.
12581            if (!mSystemReady) {
12582                try {
12583                    AppGlobals.getPackageManager().enterSafeMode();
12584                } catch (RemoteException e) {
12585                }
12586            }
12587
12588            mSafeMode = true;
12589        }
12590    }
12591
12592    public final void showSafeModeOverlay() {
12593        View v = LayoutInflater.from(mContext).inflate(
12594                com.android.internal.R.layout.safe_mode, null);
12595        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12596        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12597        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12598        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12599        lp.gravity = Gravity.BOTTOM | Gravity.START;
12600        lp.format = v.getBackground().getOpacity();
12601        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12602                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12603        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12604        ((WindowManager)mContext.getSystemService(
12605                Context.WINDOW_SERVICE)).addView(v, lp);
12606    }
12607
12608    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12609        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12610            return;
12611        }
12612        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12613        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12614        synchronized (stats) {
12615            if (mBatteryStatsService.isOnBattery()) {
12616                mBatteryStatsService.enforceCallingPermission();
12617                int MY_UID = Binder.getCallingUid();
12618                final int uid;
12619                if (sender == null) {
12620                    uid = sourceUid;
12621                } else {
12622                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12623                }
12624                BatteryStatsImpl.Uid.Pkg pkg =
12625                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12626                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12627                pkg.noteWakeupAlarmLocked(tag);
12628            }
12629        }
12630    }
12631
12632    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12633        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12634            return;
12635        }
12636        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12637        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12638        synchronized (stats) {
12639            mBatteryStatsService.enforceCallingPermission();
12640            int MY_UID = Binder.getCallingUid();
12641            final int uid;
12642            if (sender == null) {
12643                uid = sourceUid;
12644            } else {
12645                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12646            }
12647            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12648        }
12649    }
12650
12651    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12652        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12653            return;
12654        }
12655        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12656        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12657        synchronized (stats) {
12658            mBatteryStatsService.enforceCallingPermission();
12659            int MY_UID = Binder.getCallingUid();
12660            final int uid;
12661            if (sender == null) {
12662                uid = sourceUid;
12663            } else {
12664                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12665            }
12666            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12667        }
12668    }
12669
12670    public boolean killPids(int[] pids, String pReason, boolean secure) {
12671        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12672            throw new SecurityException("killPids only available to the system");
12673        }
12674        String reason = (pReason == null) ? "Unknown" : pReason;
12675        // XXX Note: don't acquire main activity lock here, because the window
12676        // manager calls in with its locks held.
12677
12678        boolean killed = false;
12679        synchronized (mPidsSelfLocked) {
12680            int worstType = 0;
12681            for (int i=0; i<pids.length; i++) {
12682                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12683                if (proc != null) {
12684                    int type = proc.setAdj;
12685                    if (type > worstType) {
12686                        worstType = type;
12687                    }
12688                }
12689            }
12690
12691            // If the worst oom_adj is somewhere in the cached proc LRU range,
12692            // then constrain it so we will kill all cached procs.
12693            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12694                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12695                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12696            }
12697
12698            // If this is not a secure call, don't let it kill processes that
12699            // are important.
12700            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12701                worstType = ProcessList.SERVICE_ADJ;
12702            }
12703
12704            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12705            for (int i=0; i<pids.length; i++) {
12706                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12707                if (proc == null) {
12708                    continue;
12709                }
12710                int adj = proc.setAdj;
12711                if (adj >= worstType && !proc.killedByAm) {
12712                    proc.kill(reason, true);
12713                    killed = true;
12714                }
12715            }
12716        }
12717        return killed;
12718    }
12719
12720    @Override
12721    public void killUid(int appId, int userId, String reason) {
12722        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12723        synchronized (this) {
12724            final long identity = Binder.clearCallingIdentity();
12725            try {
12726                killPackageProcessesLocked(null, appId, userId,
12727                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12728                        reason != null ? reason : "kill uid");
12729            } finally {
12730                Binder.restoreCallingIdentity(identity);
12731            }
12732        }
12733    }
12734
12735    @Override
12736    public boolean killProcessesBelowForeground(String reason) {
12737        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12738            throw new SecurityException("killProcessesBelowForeground() only available to system");
12739        }
12740
12741        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12742    }
12743
12744    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12745        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12746            throw new SecurityException("killProcessesBelowAdj() only available to system");
12747        }
12748
12749        boolean killed = false;
12750        synchronized (mPidsSelfLocked) {
12751            final int size = mPidsSelfLocked.size();
12752            for (int i = 0; i < size; i++) {
12753                final int pid = mPidsSelfLocked.keyAt(i);
12754                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12755                if (proc == null) continue;
12756
12757                final int adj = proc.setAdj;
12758                if (adj > belowAdj && !proc.killedByAm) {
12759                    proc.kill(reason, true);
12760                    killed = true;
12761                }
12762            }
12763        }
12764        return killed;
12765    }
12766
12767    @Override
12768    public void hang(final IBinder who, boolean allowRestart) {
12769        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12770                != PackageManager.PERMISSION_GRANTED) {
12771            throw new SecurityException("Requires permission "
12772                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12773        }
12774
12775        final IBinder.DeathRecipient death = new DeathRecipient() {
12776            @Override
12777            public void binderDied() {
12778                synchronized (this) {
12779                    notifyAll();
12780                }
12781            }
12782        };
12783
12784        try {
12785            who.linkToDeath(death, 0);
12786        } catch (RemoteException e) {
12787            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12788            return;
12789        }
12790
12791        synchronized (this) {
12792            Watchdog.getInstance().setAllowRestart(allowRestart);
12793            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12794            synchronized (death) {
12795                while (who.isBinderAlive()) {
12796                    try {
12797                        death.wait();
12798                    } catch (InterruptedException e) {
12799                    }
12800                }
12801            }
12802            Watchdog.getInstance().setAllowRestart(true);
12803        }
12804    }
12805
12806    @Override
12807    public void restart() {
12808        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12809                != PackageManager.PERMISSION_GRANTED) {
12810            throw new SecurityException("Requires permission "
12811                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12812        }
12813
12814        Log.i(TAG, "Sending shutdown broadcast...");
12815
12816        BroadcastReceiver br = new BroadcastReceiver() {
12817            @Override public void onReceive(Context context, Intent intent) {
12818                // Now the broadcast is done, finish up the low-level shutdown.
12819                Log.i(TAG, "Shutting down activity manager...");
12820                shutdown(10000);
12821                Log.i(TAG, "Shutdown complete, restarting!");
12822                Process.killProcess(Process.myPid());
12823                System.exit(10);
12824            }
12825        };
12826
12827        // First send the high-level shut down broadcast.
12828        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12829        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12830        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12831        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12832        mContext.sendOrderedBroadcastAsUser(intent,
12833                UserHandle.ALL, null, br, mHandler, 0, null, null);
12834        */
12835        br.onReceive(mContext, intent);
12836    }
12837
12838    private long getLowRamTimeSinceIdle(long now) {
12839        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12840    }
12841
12842    @Override
12843    public void performIdleMaintenance() {
12844        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12845                != PackageManager.PERMISSION_GRANTED) {
12846            throw new SecurityException("Requires permission "
12847                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12848        }
12849
12850        synchronized (this) {
12851            final long now = SystemClock.uptimeMillis();
12852            final long timeSinceLastIdle = now - mLastIdleTime;
12853            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12854            mLastIdleTime = now;
12855            mLowRamTimeSinceLastIdle = 0;
12856            if (mLowRamStartTime != 0) {
12857                mLowRamStartTime = now;
12858            }
12859
12860            StringBuilder sb = new StringBuilder(128);
12861            sb.append("Idle maintenance over ");
12862            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12863            sb.append(" low RAM for ");
12864            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12865            Slog.i(TAG, sb.toString());
12866
12867            // If at least 1/3 of our time since the last idle period has been spent
12868            // with RAM low, then we want to kill processes.
12869            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12870
12871            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12872                ProcessRecord proc = mLruProcesses.get(i);
12873                if (proc.notCachedSinceIdle) {
12874                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12875                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12876                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12877                        if (doKilling && proc.initialIdlePss != 0
12878                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12879                            sb = new StringBuilder(128);
12880                            sb.append("Kill");
12881                            sb.append(proc.processName);
12882                            sb.append(" in idle maint: pss=");
12883                            sb.append(proc.lastPss);
12884                            sb.append(", swapPss=");
12885                            sb.append(proc.lastSwapPss);
12886                            sb.append(", initialPss=");
12887                            sb.append(proc.initialIdlePss);
12888                            sb.append(", period=");
12889                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12890                            sb.append(", lowRamPeriod=");
12891                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12892                            Slog.wtfQuiet(TAG, sb.toString());
12893                            proc.kill("idle maint (pss " + proc.lastPss
12894                                    + " from " + proc.initialIdlePss + ")", true);
12895                        }
12896                    }
12897                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12898                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12899                    proc.notCachedSinceIdle = true;
12900                    proc.initialIdlePss = 0;
12901                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12902                            mTestPssMode, isSleepingLocked(), now);
12903                }
12904            }
12905
12906            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12907            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12908        }
12909    }
12910
12911    @Override
12912    public void sendIdleJobTrigger() {
12913        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12914                != PackageManager.PERMISSION_GRANTED) {
12915            throw new SecurityException("Requires permission "
12916                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12917        }
12918
12919        final long ident = Binder.clearCallingIdentity();
12920        try {
12921            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12922                    .setPackage("android")
12923                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12924            broadcastIntent(null, intent, null, null, 0, null, null, null,
12925                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12926        } finally {
12927            Binder.restoreCallingIdentity(ident);
12928        }
12929    }
12930
12931    private void retrieveSettings() {
12932        final ContentResolver resolver = mContext.getContentResolver();
12933        final boolean freeformWindowManagement =
12934                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12935                        || Settings.Global.getInt(
12936                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12937        final boolean supportsPictureInPicture =
12938                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12939
12940        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12941        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12942        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12943        final boolean alwaysFinishActivities =
12944                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12945        final boolean lenientBackgroundCheck =
12946                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12947        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12948        final boolean forceResizable = Settings.Global.getInt(
12949                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12950        final boolean supportsLeanbackOnly =
12951                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12952
12953        // Transfer any global setting for forcing RTL layout, into a System Property
12954        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12955
12956        final Configuration configuration = new Configuration();
12957        Settings.System.getConfiguration(resolver, configuration);
12958        if (forceRtl) {
12959            // This will take care of setting the correct layout direction flags
12960            configuration.setLayoutDirection(configuration.locale);
12961        }
12962
12963        synchronized (this) {
12964            mDebugApp = mOrigDebugApp = debugApp;
12965            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12966            mAlwaysFinishActivities = alwaysFinishActivities;
12967            mLenientBackgroundCheck = lenientBackgroundCheck;
12968            mSupportsLeanbackOnly = supportsLeanbackOnly;
12969            mForceResizableActivities = forceResizable;
12970            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12971            if (supportsMultiWindow || forceResizable) {
12972                mSupportsMultiWindow = true;
12973                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12974                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12975            } else {
12976                mSupportsMultiWindow = false;
12977                mSupportsFreeformWindowManagement = false;
12978                mSupportsPictureInPicture = false;
12979            }
12980            // This happens before any activities are started, so we can
12981            // change mConfiguration in-place.
12982            updateConfigurationLocked(configuration, null, true);
12983            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12984                    "Initial config: " + mConfiguration);
12985
12986            // Load resources only after the current configuration has been set.
12987            final Resources res = mContext.getResources();
12988            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12989            mThumbnailWidth = res.getDimensionPixelSize(
12990                    com.android.internal.R.dimen.thumbnail_width);
12991            mThumbnailHeight = res.getDimensionPixelSize(
12992                    com.android.internal.R.dimen.thumbnail_height);
12993            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12994                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12995            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12996                    com.android.internal.R.string.config_appsNotReportingCrashes));
12997            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12998                mFullscreenThumbnailScale = (float) res
12999                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13000                    (float) mConfiguration.screenWidthDp;
13001            } else {
13002                mFullscreenThumbnailScale = res.getFraction(
13003                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13004            }
13005        }
13006    }
13007
13008    public boolean testIsSystemReady() {
13009        // no need to synchronize(this) just to read & return the value
13010        return mSystemReady;
13011    }
13012
13013    public void systemReady(final Runnable goingCallback) {
13014        synchronized(this) {
13015            if (mSystemReady) {
13016                // If we're done calling all the receivers, run the next "boot phase" passed in
13017                // by the SystemServer
13018                if (goingCallback != null) {
13019                    goingCallback.run();
13020                }
13021                return;
13022            }
13023
13024            mLocalDeviceIdleController
13025                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13026
13027            // Make sure we have the current profile info, since it is needed for security checks.
13028            mUserController.onSystemReady();
13029            mRecentTasks.onSystemReadyLocked();
13030            mAppOpsService.systemReady();
13031            mSystemReady = true;
13032        }
13033
13034        ArrayList<ProcessRecord> procsToKill = null;
13035        synchronized(mPidsSelfLocked) {
13036            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13037                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13038                if (!isAllowedWhileBooting(proc.info)){
13039                    if (procsToKill == null) {
13040                        procsToKill = new ArrayList<ProcessRecord>();
13041                    }
13042                    procsToKill.add(proc);
13043                }
13044            }
13045        }
13046
13047        synchronized(this) {
13048            if (procsToKill != null) {
13049                for (int i=procsToKill.size()-1; i>=0; i--) {
13050                    ProcessRecord proc = procsToKill.get(i);
13051                    Slog.i(TAG, "Removing system update proc: " + proc);
13052                    removeProcessLocked(proc, true, false, "system update done");
13053                }
13054            }
13055
13056            // Now that we have cleaned up any update processes, we
13057            // are ready to start launching real processes and know that
13058            // we won't trample on them any more.
13059            mProcessesReady = true;
13060        }
13061
13062        Slog.i(TAG, "System now ready");
13063        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13064            SystemClock.uptimeMillis());
13065
13066        synchronized(this) {
13067            // Make sure we have no pre-ready processes sitting around.
13068
13069            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13070                ResolveInfo ri = mContext.getPackageManager()
13071                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13072                                STOCK_PM_FLAGS);
13073                CharSequence errorMsg = null;
13074                if (ri != null) {
13075                    ActivityInfo ai = ri.activityInfo;
13076                    ApplicationInfo app = ai.applicationInfo;
13077                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13078                        mTopAction = Intent.ACTION_FACTORY_TEST;
13079                        mTopData = null;
13080                        mTopComponent = new ComponentName(app.packageName,
13081                                ai.name);
13082                    } else {
13083                        errorMsg = mContext.getResources().getText(
13084                                com.android.internal.R.string.factorytest_not_system);
13085                    }
13086                } else {
13087                    errorMsg = mContext.getResources().getText(
13088                            com.android.internal.R.string.factorytest_no_action);
13089                }
13090                if (errorMsg != null) {
13091                    mTopAction = null;
13092                    mTopData = null;
13093                    mTopComponent = null;
13094                    Message msg = Message.obtain();
13095                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13096                    msg.getData().putCharSequence("msg", errorMsg);
13097                    mUiHandler.sendMessage(msg);
13098                }
13099            }
13100        }
13101
13102        retrieveSettings();
13103        final int currentUserId;
13104        synchronized (this) {
13105            currentUserId = mUserController.getCurrentUserIdLocked();
13106            readGrantedUriPermissionsLocked();
13107        }
13108
13109        if (goingCallback != null) goingCallback.run();
13110
13111        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13112                Integer.toString(currentUserId), currentUserId);
13113        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13114                Integer.toString(currentUserId), currentUserId);
13115        mSystemServiceManager.startUser(currentUserId);
13116
13117        synchronized (this) {
13118            // Only start up encryption-aware persistent apps; once user is
13119            // unlocked we'll come back around and start unaware apps
13120            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13121
13122            // Start up initial activity.
13123            mBooting = true;
13124            // Enable home activity for system user, so that the system can always boot
13125            if (UserManager.isSplitSystemUser()) {
13126                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13127                try {
13128                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13129                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13130                            UserHandle.USER_SYSTEM);
13131                } catch (RemoteException e) {
13132                    throw e.rethrowAsRuntimeException();
13133                }
13134            }
13135            startHomeActivityLocked(currentUserId, "systemReady");
13136
13137            try {
13138                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13139                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13140                            + " data partition or your device will be unstable.");
13141                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13142                }
13143            } catch (RemoteException e) {
13144            }
13145
13146            if (!Build.isBuildConsistent()) {
13147                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13148                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13149            }
13150
13151            long ident = Binder.clearCallingIdentity();
13152            try {
13153                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13154                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13155                        | Intent.FLAG_RECEIVER_FOREGROUND);
13156                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13157                broadcastIntentLocked(null, null, intent,
13158                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13159                        null, false, false, MY_PID, Process.SYSTEM_UID,
13160                        currentUserId);
13161                intent = new Intent(Intent.ACTION_USER_STARTING);
13162                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13163                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13164                broadcastIntentLocked(null, null, intent,
13165                        null, new IIntentReceiver.Stub() {
13166                            @Override
13167                            public void performReceive(Intent intent, int resultCode, String data,
13168                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13169                                    throws RemoteException {
13170                            }
13171                        }, 0, null, null,
13172                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13173                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13174            } catch (Throwable t) {
13175                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13176            } finally {
13177                Binder.restoreCallingIdentity(ident);
13178            }
13179            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13180            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13181        }
13182    }
13183
13184    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13185        synchronized (this) {
13186            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13187        }
13188    }
13189
13190    void skipCurrentReceiverLocked(ProcessRecord app) {
13191        for (BroadcastQueue queue : mBroadcastQueues) {
13192            queue.skipCurrentReceiverLocked(app);
13193        }
13194    }
13195
13196    /**
13197     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13198     * The application process will exit immediately after this call returns.
13199     * @param app object of the crashing app, null for the system server
13200     * @param crashInfo describing the exception
13201     */
13202    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13203        ProcessRecord r = findAppProcess(app, "Crash");
13204        final String processName = app == null ? "system_server"
13205                : (r == null ? "unknown" : r.processName);
13206
13207        handleApplicationCrashInner("crash", r, processName, crashInfo);
13208    }
13209
13210    /* Native crash reporting uses this inner version because it needs to be somewhat
13211     * decoupled from the AM-managed cleanup lifecycle
13212     */
13213    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13214            ApplicationErrorReport.CrashInfo crashInfo) {
13215        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13216                UserHandle.getUserId(Binder.getCallingUid()), processName,
13217                r == null ? -1 : r.info.flags,
13218                crashInfo.exceptionClassName,
13219                crashInfo.exceptionMessage,
13220                crashInfo.throwFileName,
13221                crashInfo.throwLineNumber);
13222
13223        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13224
13225        mAppErrors.crashApplication(r, crashInfo);
13226    }
13227
13228    public void handleApplicationStrictModeViolation(
13229            IBinder app,
13230            int violationMask,
13231            StrictMode.ViolationInfo info) {
13232        ProcessRecord r = findAppProcess(app, "StrictMode");
13233        if (r == null) {
13234            return;
13235        }
13236
13237        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13238            Integer stackFingerprint = info.hashCode();
13239            boolean logIt = true;
13240            synchronized (mAlreadyLoggedViolatedStacks) {
13241                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13242                    logIt = false;
13243                    // TODO: sub-sample into EventLog for these, with
13244                    // the info.durationMillis?  Then we'd get
13245                    // the relative pain numbers, without logging all
13246                    // the stack traces repeatedly.  We'd want to do
13247                    // likewise in the client code, which also does
13248                    // dup suppression, before the Binder call.
13249                } else {
13250                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13251                        mAlreadyLoggedViolatedStacks.clear();
13252                    }
13253                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13254                }
13255            }
13256            if (logIt) {
13257                logStrictModeViolationToDropBox(r, info);
13258            }
13259        }
13260
13261        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13262            AppErrorResult result = new AppErrorResult();
13263            synchronized (this) {
13264                final long origId = Binder.clearCallingIdentity();
13265
13266                Message msg = Message.obtain();
13267                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13268                HashMap<String, Object> data = new HashMap<String, Object>();
13269                data.put("result", result);
13270                data.put("app", r);
13271                data.put("violationMask", violationMask);
13272                data.put("info", info);
13273                msg.obj = data;
13274                mUiHandler.sendMessage(msg);
13275
13276                Binder.restoreCallingIdentity(origId);
13277            }
13278            int res = result.get();
13279            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13280        }
13281    }
13282
13283    // Depending on the policy in effect, there could be a bunch of
13284    // these in quick succession so we try to batch these together to
13285    // minimize disk writes, number of dropbox entries, and maximize
13286    // compression, by having more fewer, larger records.
13287    private void logStrictModeViolationToDropBox(
13288            ProcessRecord process,
13289            StrictMode.ViolationInfo info) {
13290        if (info == null) {
13291            return;
13292        }
13293        final boolean isSystemApp = process == null ||
13294                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13295                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13296        final String processName = process == null ? "unknown" : process.processName;
13297        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13298        final DropBoxManager dbox = (DropBoxManager)
13299                mContext.getSystemService(Context.DROPBOX_SERVICE);
13300
13301        // Exit early if the dropbox isn't configured to accept this report type.
13302        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13303
13304        boolean bufferWasEmpty;
13305        boolean needsFlush;
13306        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13307        synchronized (sb) {
13308            bufferWasEmpty = sb.length() == 0;
13309            appendDropBoxProcessHeaders(process, processName, sb);
13310            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13311            sb.append("System-App: ").append(isSystemApp).append("\n");
13312            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13313            if (info.violationNumThisLoop != 0) {
13314                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13315            }
13316            if (info.numAnimationsRunning != 0) {
13317                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13318            }
13319            if (info.broadcastIntentAction != null) {
13320                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13321            }
13322            if (info.durationMillis != -1) {
13323                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13324            }
13325            if (info.numInstances != -1) {
13326                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13327            }
13328            if (info.tags != null) {
13329                for (String tag : info.tags) {
13330                    sb.append("Span-Tag: ").append(tag).append("\n");
13331                }
13332            }
13333            sb.append("\n");
13334            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13335                sb.append(info.crashInfo.stackTrace);
13336                sb.append("\n");
13337            }
13338            if (info.message != null) {
13339                sb.append(info.message);
13340                sb.append("\n");
13341            }
13342
13343            // Only buffer up to ~64k.  Various logging bits truncate
13344            // things at 128k.
13345            needsFlush = (sb.length() > 64 * 1024);
13346        }
13347
13348        // Flush immediately if the buffer's grown too large, or this
13349        // is a non-system app.  Non-system apps are isolated with a
13350        // different tag & policy and not batched.
13351        //
13352        // Batching is useful during internal testing with
13353        // StrictMode settings turned up high.  Without batching,
13354        // thousands of separate files could be created on boot.
13355        if (!isSystemApp || needsFlush) {
13356            new Thread("Error dump: " + dropboxTag) {
13357                @Override
13358                public void run() {
13359                    String report;
13360                    synchronized (sb) {
13361                        report = sb.toString();
13362                        sb.delete(0, sb.length());
13363                        sb.trimToSize();
13364                    }
13365                    if (report.length() != 0) {
13366                        dbox.addText(dropboxTag, report);
13367                    }
13368                }
13369            }.start();
13370            return;
13371        }
13372
13373        // System app batching:
13374        if (!bufferWasEmpty) {
13375            // An existing dropbox-writing thread is outstanding, so
13376            // we don't need to start it up.  The existing thread will
13377            // catch the buffer appends we just did.
13378            return;
13379        }
13380
13381        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13382        // (After this point, we shouldn't access AMS internal data structures.)
13383        new Thread("Error dump: " + dropboxTag) {
13384            @Override
13385            public void run() {
13386                // 5 second sleep to let stacks arrive and be batched together
13387                try {
13388                    Thread.sleep(5000);  // 5 seconds
13389                } catch (InterruptedException e) {}
13390
13391                String errorReport;
13392                synchronized (mStrictModeBuffer) {
13393                    errorReport = mStrictModeBuffer.toString();
13394                    if (errorReport.length() == 0) {
13395                        return;
13396                    }
13397                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13398                    mStrictModeBuffer.trimToSize();
13399                }
13400                dbox.addText(dropboxTag, errorReport);
13401            }
13402        }.start();
13403    }
13404
13405    /**
13406     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13407     * @param app object of the crashing app, null for the system server
13408     * @param tag reported by the caller
13409     * @param system whether this wtf is coming from the system
13410     * @param crashInfo describing the context of the error
13411     * @return true if the process should exit immediately (WTF is fatal)
13412     */
13413    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13414            final ApplicationErrorReport.CrashInfo crashInfo) {
13415        final int callingUid = Binder.getCallingUid();
13416        final int callingPid = Binder.getCallingPid();
13417
13418        if (system) {
13419            // If this is coming from the system, we could very well have low-level
13420            // system locks held, so we want to do this all asynchronously.  And we
13421            // never want this to become fatal, so there is that too.
13422            mHandler.post(new Runnable() {
13423                @Override public void run() {
13424                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13425                }
13426            });
13427            return false;
13428        }
13429
13430        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13431                crashInfo);
13432
13433        if (r != null && r.pid != Process.myPid() &&
13434                Settings.Global.getInt(mContext.getContentResolver(),
13435                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13436            mAppErrors.crashApplication(r, crashInfo);
13437            return true;
13438        } else {
13439            return false;
13440        }
13441    }
13442
13443    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13444            final ApplicationErrorReport.CrashInfo crashInfo) {
13445        final ProcessRecord r = findAppProcess(app, "WTF");
13446        final String processName = app == null ? "system_server"
13447                : (r == null ? "unknown" : r.processName);
13448
13449        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13450                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13451
13452        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13453
13454        return r;
13455    }
13456
13457    /**
13458     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13459     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13460     */
13461    private ProcessRecord findAppProcess(IBinder app, String reason) {
13462        if (app == null) {
13463            return null;
13464        }
13465
13466        synchronized (this) {
13467            final int NP = mProcessNames.getMap().size();
13468            for (int ip=0; ip<NP; ip++) {
13469                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13470                final int NA = apps.size();
13471                for (int ia=0; ia<NA; ia++) {
13472                    ProcessRecord p = apps.valueAt(ia);
13473                    if (p.thread != null && p.thread.asBinder() == app) {
13474                        return p;
13475                    }
13476                }
13477            }
13478
13479            Slog.w(TAG, "Can't find mystery application for " + reason
13480                    + " from pid=" + Binder.getCallingPid()
13481                    + " uid=" + Binder.getCallingUid() + ": " + app);
13482            return null;
13483        }
13484    }
13485
13486    /**
13487     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13488     * to append various headers to the dropbox log text.
13489     */
13490    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13491            StringBuilder sb) {
13492        // Watchdog thread ends up invoking this function (with
13493        // a null ProcessRecord) to add the stack file to dropbox.
13494        // Do not acquire a lock on this (am) in such cases, as it
13495        // could cause a potential deadlock, if and when watchdog
13496        // is invoked due to unavailability of lock on am and it
13497        // would prevent watchdog from killing system_server.
13498        if (process == null) {
13499            sb.append("Process: ").append(processName).append("\n");
13500            return;
13501        }
13502        // Note: ProcessRecord 'process' is guarded by the service
13503        // instance.  (notably process.pkgList, which could otherwise change
13504        // concurrently during execution of this method)
13505        synchronized (this) {
13506            sb.append("Process: ").append(processName).append("\n");
13507            int flags = process.info.flags;
13508            IPackageManager pm = AppGlobals.getPackageManager();
13509            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13510            for (int ip=0; ip<process.pkgList.size(); ip++) {
13511                String pkg = process.pkgList.keyAt(ip);
13512                sb.append("Package: ").append(pkg);
13513                try {
13514                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13515                    if (pi != null) {
13516                        sb.append(" v").append(pi.versionCode);
13517                        if (pi.versionName != null) {
13518                            sb.append(" (").append(pi.versionName).append(")");
13519                        }
13520                    }
13521                } catch (RemoteException e) {
13522                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13523                }
13524                sb.append("\n");
13525            }
13526        }
13527    }
13528
13529    private static String processClass(ProcessRecord process) {
13530        if (process == null || process.pid == MY_PID) {
13531            return "system_server";
13532        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13533            return "system_app";
13534        } else {
13535            return "data_app";
13536        }
13537    }
13538
13539    private volatile long mWtfClusterStart;
13540    private volatile int mWtfClusterCount;
13541
13542    /**
13543     * Write a description of an error (crash, WTF, ANR) to the drop box.
13544     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13545     * @param process which caused the error, null means the system server
13546     * @param activity which triggered the error, null if unknown
13547     * @param parent activity related to the error, null if unknown
13548     * @param subject line related to the error, null if absent
13549     * @param report in long form describing the error, null if absent
13550     * @param dataFile text file to include in the report, null if none
13551     * @param crashInfo giving an application stack trace, null if absent
13552     */
13553    public void addErrorToDropBox(String eventType,
13554            ProcessRecord process, String processName, ActivityRecord activity,
13555            ActivityRecord parent, String subject,
13556            final String report, final File dataFile,
13557            final ApplicationErrorReport.CrashInfo crashInfo) {
13558        // NOTE -- this must never acquire the ActivityManagerService lock,
13559        // otherwise the watchdog may be prevented from resetting the system.
13560
13561        final String dropboxTag = processClass(process) + "_" + eventType;
13562        final DropBoxManager dbox = (DropBoxManager)
13563                mContext.getSystemService(Context.DROPBOX_SERVICE);
13564
13565        // Exit early if the dropbox isn't configured to accept this report type.
13566        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13567
13568        // Rate-limit how often we're willing to do the heavy lifting below to
13569        // collect and record logs; currently 5 logs per 10 second period.
13570        final long now = SystemClock.elapsedRealtime();
13571        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13572            mWtfClusterStart = now;
13573            mWtfClusterCount = 1;
13574        } else {
13575            if (mWtfClusterCount++ >= 5) return;
13576        }
13577
13578        final StringBuilder sb = new StringBuilder(1024);
13579        appendDropBoxProcessHeaders(process, processName, sb);
13580        if (process != null) {
13581            sb.append("Foreground: ")
13582                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13583                    .append("\n");
13584        }
13585        if (activity != null) {
13586            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13587        }
13588        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13589            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13590        }
13591        if (parent != null && parent != activity) {
13592            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13593        }
13594        if (subject != null) {
13595            sb.append("Subject: ").append(subject).append("\n");
13596        }
13597        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13598        if (Debug.isDebuggerConnected()) {
13599            sb.append("Debugger: Connected\n");
13600        }
13601        sb.append("\n");
13602
13603        // Do the rest in a worker thread to avoid blocking the caller on I/O
13604        // (After this point, we shouldn't access AMS internal data structures.)
13605        Thread worker = new Thread("Error dump: " + dropboxTag) {
13606            @Override
13607            public void run() {
13608                if (report != null) {
13609                    sb.append(report);
13610                }
13611
13612                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13613                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13614                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13615                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13616
13617                if (dataFile != null && maxDataFileSize > 0) {
13618                    try {
13619                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13620                                    "\n\n[[TRUNCATED]]"));
13621                    } catch (IOException e) {
13622                        Slog.e(TAG, "Error reading " + dataFile, e);
13623                    }
13624                }
13625                if (crashInfo != null && crashInfo.stackTrace != null) {
13626                    sb.append(crashInfo.stackTrace);
13627                }
13628
13629                if (lines > 0) {
13630                    sb.append("\n");
13631
13632                    // Merge several logcat streams, and take the last N lines
13633                    InputStreamReader input = null;
13634                    try {
13635                        java.lang.Process logcat = new ProcessBuilder(
13636                                "/system/bin/timeout", "-k", "15s", "10s",
13637                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13638                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13639                                        .redirectErrorStream(true).start();
13640
13641                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13642                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13643                        input = new InputStreamReader(logcat.getInputStream());
13644
13645                        int num;
13646                        char[] buf = new char[8192];
13647                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13648                    } catch (IOException e) {
13649                        Slog.e(TAG, "Error running logcat", e);
13650                    } finally {
13651                        if (input != null) try { input.close(); } catch (IOException e) {}
13652                    }
13653                }
13654
13655                dbox.addText(dropboxTag, sb.toString());
13656            }
13657        };
13658
13659        if (process == null) {
13660            // If process is null, we are being called from some internal code
13661            // and may be about to die -- run this synchronously.
13662            worker.run();
13663        } else {
13664            worker.start();
13665        }
13666    }
13667
13668    @Override
13669    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13670        enforceNotIsolatedCaller("getProcessesInErrorState");
13671        // assume our apps are happy - lazy create the list
13672        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13673
13674        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13675                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13676        int userId = UserHandle.getUserId(Binder.getCallingUid());
13677
13678        synchronized (this) {
13679
13680            // iterate across all processes
13681            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13682                ProcessRecord app = mLruProcesses.get(i);
13683                if (!allUsers && app.userId != userId) {
13684                    continue;
13685                }
13686                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13687                    // This one's in trouble, so we'll generate a report for it
13688                    // crashes are higher priority (in case there's a crash *and* an anr)
13689                    ActivityManager.ProcessErrorStateInfo report = null;
13690                    if (app.crashing) {
13691                        report = app.crashingReport;
13692                    } else if (app.notResponding) {
13693                        report = app.notRespondingReport;
13694                    }
13695
13696                    if (report != null) {
13697                        if (errList == null) {
13698                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13699                        }
13700                        errList.add(report);
13701                    } else {
13702                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13703                                " crashing = " + app.crashing +
13704                                " notResponding = " + app.notResponding);
13705                    }
13706                }
13707            }
13708        }
13709
13710        return errList;
13711    }
13712
13713    static int procStateToImportance(int procState, int memAdj,
13714            ActivityManager.RunningAppProcessInfo currApp) {
13715        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13716        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13717            currApp.lru = memAdj;
13718        } else {
13719            currApp.lru = 0;
13720        }
13721        return imp;
13722    }
13723
13724    private void fillInProcMemInfo(ProcessRecord app,
13725            ActivityManager.RunningAppProcessInfo outInfo) {
13726        outInfo.pid = app.pid;
13727        outInfo.uid = app.info.uid;
13728        if (mHeavyWeightProcess == app) {
13729            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13730        }
13731        if (app.persistent) {
13732            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13733        }
13734        if (app.activities.size() > 0) {
13735            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13736        }
13737        outInfo.lastTrimLevel = app.trimMemoryLevel;
13738        int adj = app.curAdj;
13739        int procState = app.curProcState;
13740        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13741        outInfo.importanceReasonCode = app.adjTypeCode;
13742        outInfo.processState = app.curProcState;
13743    }
13744
13745    @Override
13746    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13747        enforceNotIsolatedCaller("getRunningAppProcesses");
13748
13749        final int callingUid = Binder.getCallingUid();
13750
13751        // Lazy instantiation of list
13752        List<ActivityManager.RunningAppProcessInfo> runList = null;
13753        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13754                callingUid) == PackageManager.PERMISSION_GRANTED;
13755        final int userId = UserHandle.getUserId(callingUid);
13756        final boolean allUids = isGetTasksAllowed(
13757                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13758
13759        synchronized (this) {
13760            // Iterate across all processes
13761            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13762                ProcessRecord app = mLruProcesses.get(i);
13763                if ((!allUsers && app.userId != userId)
13764                        || (!allUids && app.uid != callingUid)) {
13765                    continue;
13766                }
13767                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13768                    // Generate process state info for running application
13769                    ActivityManager.RunningAppProcessInfo currApp =
13770                        new ActivityManager.RunningAppProcessInfo(app.processName,
13771                                app.pid, app.getPackageList());
13772                    fillInProcMemInfo(app, currApp);
13773                    if (app.adjSource instanceof ProcessRecord) {
13774                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13775                        currApp.importanceReasonImportance =
13776                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13777                                        app.adjSourceProcState);
13778                    } else if (app.adjSource instanceof ActivityRecord) {
13779                        ActivityRecord r = (ActivityRecord)app.adjSource;
13780                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13781                    }
13782                    if (app.adjTarget instanceof ComponentName) {
13783                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13784                    }
13785                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13786                    //        + " lru=" + currApp.lru);
13787                    if (runList == null) {
13788                        runList = new ArrayList<>();
13789                    }
13790                    runList.add(currApp);
13791                }
13792            }
13793        }
13794        return runList;
13795    }
13796
13797    @Override
13798    public List<ApplicationInfo> getRunningExternalApplications() {
13799        enforceNotIsolatedCaller("getRunningExternalApplications");
13800        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13801        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13802        if (runningApps != null && runningApps.size() > 0) {
13803            Set<String> extList = new HashSet<String>();
13804            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13805                if (app.pkgList != null) {
13806                    for (String pkg : app.pkgList) {
13807                        extList.add(pkg);
13808                    }
13809                }
13810            }
13811            IPackageManager pm = AppGlobals.getPackageManager();
13812            for (String pkg : extList) {
13813                try {
13814                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13815                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13816                        retList.add(info);
13817                    }
13818                } catch (RemoteException e) {
13819                }
13820            }
13821        }
13822        return retList;
13823    }
13824
13825    @Override
13826    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13827        enforceNotIsolatedCaller("getMyMemoryState");
13828        synchronized (this) {
13829            ProcessRecord proc;
13830            synchronized (mPidsSelfLocked) {
13831                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13832            }
13833            fillInProcMemInfo(proc, outInfo);
13834        }
13835    }
13836
13837    @Override
13838    public int getMemoryTrimLevel() {
13839        enforceNotIsolatedCaller("getMyMemoryState");
13840        synchronized (this) {
13841            return mLastMemoryLevel;
13842        }
13843    }
13844
13845    @Override
13846    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13847            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13848        (new ActivityManagerShellCommand(this, false)).exec(
13849                this, in, out, err, args, resultReceiver);
13850    }
13851
13852    @Override
13853    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13854        if (checkCallingPermission(android.Manifest.permission.DUMP)
13855                != PackageManager.PERMISSION_GRANTED) {
13856            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13857                    + Binder.getCallingPid()
13858                    + ", uid=" + Binder.getCallingUid()
13859                    + " without permission "
13860                    + android.Manifest.permission.DUMP);
13861            return;
13862        }
13863
13864        boolean dumpAll = false;
13865        boolean dumpClient = false;
13866        boolean dumpCheckin = false;
13867        boolean dumpCheckinFormat = false;
13868        String dumpPackage = null;
13869
13870        int opti = 0;
13871        while (opti < args.length) {
13872            String opt = args[opti];
13873            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13874                break;
13875            }
13876            opti++;
13877            if ("-a".equals(opt)) {
13878                dumpAll = true;
13879            } else if ("-c".equals(opt)) {
13880                dumpClient = true;
13881            } else if ("-p".equals(opt)) {
13882                if (opti < args.length) {
13883                    dumpPackage = args[opti];
13884                    opti++;
13885                } else {
13886                    pw.println("Error: -p option requires package argument");
13887                    return;
13888                }
13889                dumpClient = true;
13890            } else if ("--checkin".equals(opt)) {
13891                dumpCheckin = dumpCheckinFormat = true;
13892            } else if ("-C".equals(opt)) {
13893                dumpCheckinFormat = true;
13894            } else if ("-h".equals(opt)) {
13895                ActivityManagerShellCommand.dumpHelp(pw, true);
13896                return;
13897            } else {
13898                pw.println("Unknown argument: " + opt + "; use -h for help");
13899            }
13900        }
13901
13902        long origId = Binder.clearCallingIdentity();
13903        boolean more = false;
13904        // Is the caller requesting to dump a particular piece of data?
13905        if (opti < args.length) {
13906            String cmd = args[opti];
13907            opti++;
13908            if ("activities".equals(cmd) || "a".equals(cmd)) {
13909                synchronized (this) {
13910                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13911                }
13912            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13913                synchronized (this) {
13914                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13915                }
13916            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13917                String[] newArgs;
13918                String name;
13919                if (opti >= args.length) {
13920                    name = null;
13921                    newArgs = EMPTY_STRING_ARRAY;
13922                } else {
13923                    dumpPackage = args[opti];
13924                    opti++;
13925                    newArgs = new String[args.length - opti];
13926                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13927                            args.length - opti);
13928                }
13929                synchronized (this) {
13930                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13931                }
13932            } else if ("broadcast-stats".equals(cmd)) {
13933                String[] newArgs;
13934                String name;
13935                if (opti >= args.length) {
13936                    name = null;
13937                    newArgs = EMPTY_STRING_ARRAY;
13938                } else {
13939                    dumpPackage = args[opti];
13940                    opti++;
13941                    newArgs = new String[args.length - opti];
13942                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13943                            args.length - opti);
13944                }
13945                synchronized (this) {
13946                    if (dumpCheckinFormat) {
13947                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13948                                dumpPackage);
13949                    } else {
13950                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13951                    }
13952                }
13953            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13954                String[] newArgs;
13955                String name;
13956                if (opti >= args.length) {
13957                    name = null;
13958                    newArgs = EMPTY_STRING_ARRAY;
13959                } else {
13960                    dumpPackage = args[opti];
13961                    opti++;
13962                    newArgs = new String[args.length - opti];
13963                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13964                            args.length - opti);
13965                }
13966                synchronized (this) {
13967                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13968                }
13969            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13970                String[] newArgs;
13971                String name;
13972                if (opti >= args.length) {
13973                    name = null;
13974                    newArgs = EMPTY_STRING_ARRAY;
13975                } else {
13976                    dumpPackage = args[opti];
13977                    opti++;
13978                    newArgs = new String[args.length - opti];
13979                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13980                            args.length - opti);
13981                }
13982                synchronized (this) {
13983                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13984                }
13985            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13986                synchronized (this) {
13987                    dumpOomLocked(fd, pw, args, opti, true);
13988                }
13989            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13990                synchronized (this) {
13991                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13992                }
13993            } else if ("provider".equals(cmd)) {
13994                String[] newArgs;
13995                String name;
13996                if (opti >= args.length) {
13997                    name = null;
13998                    newArgs = EMPTY_STRING_ARRAY;
13999                } else {
14000                    name = args[opti];
14001                    opti++;
14002                    newArgs = new String[args.length - opti];
14003                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14004                }
14005                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14006                    pw.println("No providers match: " + name);
14007                    pw.println("Use -h for help.");
14008                }
14009            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14010                synchronized (this) {
14011                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14012                }
14013            } else if ("service".equals(cmd)) {
14014                String[] newArgs;
14015                String name;
14016                if (opti >= args.length) {
14017                    name = null;
14018                    newArgs = EMPTY_STRING_ARRAY;
14019                } else {
14020                    name = args[opti];
14021                    opti++;
14022                    newArgs = new String[args.length - opti];
14023                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14024                            args.length - opti);
14025                }
14026                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14027                    pw.println("No services match: " + name);
14028                    pw.println("Use -h for help.");
14029                }
14030            } else if ("package".equals(cmd)) {
14031                String[] newArgs;
14032                if (opti >= args.length) {
14033                    pw.println("package: no package name specified");
14034                    pw.println("Use -h for help.");
14035                } else {
14036                    dumpPackage = args[opti];
14037                    opti++;
14038                    newArgs = new String[args.length - opti];
14039                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14040                            args.length - opti);
14041                    args = newArgs;
14042                    opti = 0;
14043                    more = true;
14044                }
14045            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14046                synchronized (this) {
14047                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14048                }
14049            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14050                if (dumpClient) {
14051                    ActiveServices.ServiceDumper dumper;
14052                    synchronized (this) {
14053                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14054                                dumpPackage);
14055                    }
14056                    dumper.dumpWithClient();
14057                } else {
14058                    synchronized (this) {
14059                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14060                                dumpPackage).dumpLocked();
14061                    }
14062                }
14063            } else if ("locks".equals(cmd)) {
14064                LockGuard.dump(fd, pw, args);
14065            } else {
14066                // Dumping a single activity?
14067                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14068                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14069                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14070                    if (res < 0) {
14071                        pw.println("Bad activity command, or no activities match: " + cmd);
14072                        pw.println("Use -h for help.");
14073                    }
14074                }
14075            }
14076            if (!more) {
14077                Binder.restoreCallingIdentity(origId);
14078                return;
14079            }
14080        }
14081
14082        // No piece of data specified, dump everything.
14083        if (dumpCheckinFormat) {
14084            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14085        } else if (dumpClient) {
14086            ActiveServices.ServiceDumper sdumper;
14087            synchronized (this) {
14088                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14089                pw.println();
14090                if (dumpAll) {
14091                    pw.println("-------------------------------------------------------------------------------");
14092                }
14093                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14094                pw.println();
14095                if (dumpAll) {
14096                    pw.println("-------------------------------------------------------------------------------");
14097                }
14098                if (dumpAll || dumpPackage != null) {
14099                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14100                    pw.println();
14101                    if (dumpAll) {
14102                        pw.println("-------------------------------------------------------------------------------");
14103                    }
14104                }
14105                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14106                pw.println();
14107                if (dumpAll) {
14108                    pw.println("-------------------------------------------------------------------------------");
14109                }
14110                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14111                pw.println();
14112                if (dumpAll) {
14113                    pw.println("-------------------------------------------------------------------------------");
14114                }
14115                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14116                        dumpPackage);
14117            }
14118            sdumper.dumpWithClient();
14119            pw.println();
14120            synchronized (this) {
14121                if (dumpAll) {
14122                    pw.println("-------------------------------------------------------------------------------");
14123                }
14124                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14125                pw.println();
14126                if (dumpAll) {
14127                    pw.println("-------------------------------------------------------------------------------");
14128                }
14129                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14130                if (mAssociations.size() > 0) {
14131                    pw.println();
14132                    if (dumpAll) {
14133                        pw.println("-------------------------------------------------------------------------------");
14134                    }
14135                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14136                }
14137                pw.println();
14138                if (dumpAll) {
14139                    pw.println("-------------------------------------------------------------------------------");
14140                }
14141                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14142            }
14143
14144        } else {
14145            synchronized (this) {
14146                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14147                pw.println();
14148                if (dumpAll) {
14149                    pw.println("-------------------------------------------------------------------------------");
14150                }
14151                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14152                pw.println();
14153                if (dumpAll) {
14154                    pw.println("-------------------------------------------------------------------------------");
14155                }
14156                if (dumpAll || dumpPackage != null) {
14157                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14158                    pw.println();
14159                    if (dumpAll) {
14160                        pw.println("-------------------------------------------------------------------------------");
14161                    }
14162                }
14163                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14164                pw.println();
14165                if (dumpAll) {
14166                    pw.println("-------------------------------------------------------------------------------");
14167                }
14168                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14169                pw.println();
14170                if (dumpAll) {
14171                    pw.println("-------------------------------------------------------------------------------");
14172                }
14173                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14174                        .dumpLocked();
14175                pw.println();
14176                if (dumpAll) {
14177                    pw.println("-------------------------------------------------------------------------------");
14178                }
14179                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14180                pw.println();
14181                if (dumpAll) {
14182                    pw.println("-------------------------------------------------------------------------------");
14183                }
14184                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14185                if (mAssociations.size() > 0) {
14186                    pw.println();
14187                    if (dumpAll) {
14188                        pw.println("-------------------------------------------------------------------------------");
14189                    }
14190                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14191                }
14192                pw.println();
14193                if (dumpAll) {
14194                    pw.println("-------------------------------------------------------------------------------");
14195                }
14196                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14197            }
14198        }
14199        Binder.restoreCallingIdentity(origId);
14200    }
14201
14202    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14203            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14204        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14205
14206        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14207                dumpPackage);
14208        boolean needSep = printedAnything;
14209
14210        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14211                dumpPackage, needSep, "  mFocusedActivity: ");
14212        if (printed) {
14213            printedAnything = true;
14214            needSep = false;
14215        }
14216
14217        if (dumpPackage == null) {
14218            if (needSep) {
14219                pw.println();
14220            }
14221            needSep = true;
14222            printedAnything = true;
14223            mStackSupervisor.dump(pw, "  ");
14224        }
14225
14226        if (!printedAnything) {
14227            pw.println("  (nothing)");
14228        }
14229    }
14230
14231    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14232            int opti, boolean dumpAll, String dumpPackage) {
14233        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14234
14235        boolean printedAnything = false;
14236
14237        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14238            boolean printedHeader = false;
14239
14240            final int N = mRecentTasks.size();
14241            for (int i=0; i<N; i++) {
14242                TaskRecord tr = mRecentTasks.get(i);
14243                if (dumpPackage != null) {
14244                    if (tr.realActivity == null ||
14245                            !dumpPackage.equals(tr.realActivity)) {
14246                        continue;
14247                    }
14248                }
14249                if (!printedHeader) {
14250                    pw.println("  Recent tasks:");
14251                    printedHeader = true;
14252                    printedAnything = true;
14253                }
14254                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14255                        pw.println(tr);
14256                if (dumpAll) {
14257                    mRecentTasks.get(i).dump(pw, "    ");
14258                }
14259            }
14260        }
14261
14262        if (!printedAnything) {
14263            pw.println("  (nothing)");
14264        }
14265    }
14266
14267    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14268            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14269        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14270
14271        int dumpUid = 0;
14272        if (dumpPackage != null) {
14273            IPackageManager pm = AppGlobals.getPackageManager();
14274            try {
14275                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14276            } catch (RemoteException e) {
14277            }
14278        }
14279
14280        boolean printedAnything = false;
14281
14282        final long now = SystemClock.uptimeMillis();
14283
14284        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14285            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14286                    = mAssociations.valueAt(i1);
14287            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14288                SparseArray<ArrayMap<String, Association>> sourceUids
14289                        = targetComponents.valueAt(i2);
14290                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14291                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14292                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14293                        Association ass = sourceProcesses.valueAt(i4);
14294                        if (dumpPackage != null) {
14295                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14296                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14297                                continue;
14298                            }
14299                        }
14300                        printedAnything = true;
14301                        pw.print("  ");
14302                        pw.print(ass.mTargetProcess);
14303                        pw.print("/");
14304                        UserHandle.formatUid(pw, ass.mTargetUid);
14305                        pw.print(" <- ");
14306                        pw.print(ass.mSourceProcess);
14307                        pw.print("/");
14308                        UserHandle.formatUid(pw, ass.mSourceUid);
14309                        pw.println();
14310                        pw.print("    via ");
14311                        pw.print(ass.mTargetComponent.flattenToShortString());
14312                        pw.println();
14313                        pw.print("    ");
14314                        long dur = ass.mTime;
14315                        if (ass.mNesting > 0) {
14316                            dur += now - ass.mStartTime;
14317                        }
14318                        TimeUtils.formatDuration(dur, pw);
14319                        pw.print(" (");
14320                        pw.print(ass.mCount);
14321                        pw.print(" times)");
14322                        pw.print("  ");
14323                        for (int i=0; i<ass.mStateTimes.length; i++) {
14324                            long amt = ass.mStateTimes[i];
14325                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14326                                amt += now - ass.mLastStateUptime;
14327                            }
14328                            if (amt != 0) {
14329                                pw.print(" ");
14330                                pw.print(ProcessList.makeProcStateString(
14331                                            i + ActivityManager.MIN_PROCESS_STATE));
14332                                pw.print("=");
14333                                TimeUtils.formatDuration(amt, pw);
14334                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14335                                    pw.print("*");
14336                                }
14337                            }
14338                        }
14339                        pw.println();
14340                        if (ass.mNesting > 0) {
14341                            pw.print("    Currently active: ");
14342                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14343                            pw.println();
14344                        }
14345                    }
14346                }
14347            }
14348
14349        }
14350
14351        if (!printedAnything) {
14352            pw.println("  (nothing)");
14353        }
14354    }
14355
14356    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14357            String header, boolean needSep) {
14358        boolean printed = false;
14359        int whichAppId = -1;
14360        if (dumpPackage != null) {
14361            try {
14362                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14363                        dumpPackage, 0);
14364                whichAppId = UserHandle.getAppId(info.uid);
14365            } catch (NameNotFoundException e) {
14366                e.printStackTrace();
14367            }
14368        }
14369        for (int i=0; i<uids.size(); i++) {
14370            UidRecord uidRec = uids.valueAt(i);
14371            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14372                continue;
14373            }
14374            if (!printed) {
14375                printed = true;
14376                if (needSep) {
14377                    pw.println();
14378                }
14379                pw.print("  ");
14380                pw.println(header);
14381                needSep = true;
14382            }
14383            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14384            pw.print(": "); pw.println(uidRec);
14385        }
14386        return printed;
14387    }
14388
14389    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14390            int opti, boolean dumpAll, String dumpPackage) {
14391        boolean needSep = false;
14392        boolean printedAnything = false;
14393        int numPers = 0;
14394
14395        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14396
14397        if (dumpAll) {
14398            final int NP = mProcessNames.getMap().size();
14399            for (int ip=0; ip<NP; ip++) {
14400                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14401                final int NA = procs.size();
14402                for (int ia=0; ia<NA; ia++) {
14403                    ProcessRecord r = procs.valueAt(ia);
14404                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14405                        continue;
14406                    }
14407                    if (!needSep) {
14408                        pw.println("  All known processes:");
14409                        needSep = true;
14410                        printedAnything = true;
14411                    }
14412                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14413                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14414                        pw.print(" "); pw.println(r);
14415                    r.dump(pw, "    ");
14416                    if (r.persistent) {
14417                        numPers++;
14418                    }
14419                }
14420            }
14421        }
14422
14423        if (mIsolatedProcesses.size() > 0) {
14424            boolean printed = false;
14425            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14426                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14427                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14428                    continue;
14429                }
14430                if (!printed) {
14431                    if (needSep) {
14432                        pw.println();
14433                    }
14434                    pw.println("  Isolated process list (sorted by uid):");
14435                    printedAnything = true;
14436                    printed = true;
14437                    needSep = true;
14438                }
14439                pw.println(String.format("%sIsolated #%2d: %s",
14440                        "    ", i, r.toString()));
14441            }
14442        }
14443
14444        if (mActiveUids.size() > 0) {
14445            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14446                printedAnything = needSep = true;
14447            }
14448        }
14449        if (mValidateUids.size() > 0) {
14450            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14451                printedAnything = needSep = true;
14452            }
14453        }
14454
14455        if (mLruProcesses.size() > 0) {
14456            if (needSep) {
14457                pw.println();
14458            }
14459            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14460                    pw.print(" total, non-act at ");
14461                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14462                    pw.print(", non-svc at ");
14463                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14464                    pw.println("):");
14465            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14466            needSep = true;
14467            printedAnything = true;
14468        }
14469
14470        if (dumpAll || dumpPackage != null) {
14471            synchronized (mPidsSelfLocked) {
14472                boolean printed = false;
14473                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14474                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14475                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14476                        continue;
14477                    }
14478                    if (!printed) {
14479                        if (needSep) pw.println();
14480                        needSep = true;
14481                        pw.println("  PID mappings:");
14482                        printed = true;
14483                        printedAnything = true;
14484                    }
14485                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14486                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14487                }
14488            }
14489        }
14490
14491        if (mForegroundProcesses.size() > 0) {
14492            synchronized (mPidsSelfLocked) {
14493                boolean printed = false;
14494                for (int i=0; i<mForegroundProcesses.size(); i++) {
14495                    ProcessRecord r = mPidsSelfLocked.get(
14496                            mForegroundProcesses.valueAt(i).pid);
14497                    if (dumpPackage != null && (r == null
14498                            || !r.pkgList.containsKey(dumpPackage))) {
14499                        continue;
14500                    }
14501                    if (!printed) {
14502                        if (needSep) pw.println();
14503                        needSep = true;
14504                        pw.println("  Foreground Processes:");
14505                        printed = true;
14506                        printedAnything = true;
14507                    }
14508                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14509                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14510                }
14511            }
14512        }
14513
14514        if (mPersistentStartingProcesses.size() > 0) {
14515            if (needSep) pw.println();
14516            needSep = true;
14517            printedAnything = true;
14518            pw.println("  Persisent processes that are starting:");
14519            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14520                    "Starting Norm", "Restarting PERS", dumpPackage);
14521        }
14522
14523        if (mRemovedProcesses.size() > 0) {
14524            if (needSep) pw.println();
14525            needSep = true;
14526            printedAnything = true;
14527            pw.println("  Processes that are being removed:");
14528            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14529                    "Removed Norm", "Removed PERS", dumpPackage);
14530        }
14531
14532        if (mProcessesOnHold.size() > 0) {
14533            if (needSep) pw.println();
14534            needSep = true;
14535            printedAnything = true;
14536            pw.println("  Processes that are on old until the system is ready:");
14537            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14538                    "OnHold Norm", "OnHold PERS", dumpPackage);
14539        }
14540
14541        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14542
14543        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14544        if (needSep) {
14545            printedAnything = true;
14546        }
14547
14548        if (dumpPackage == null) {
14549            pw.println();
14550            needSep = false;
14551            mUserController.dump(pw, dumpAll);
14552        }
14553        if (mHomeProcess != null && (dumpPackage == null
14554                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14555            if (needSep) {
14556                pw.println();
14557                needSep = false;
14558            }
14559            pw.println("  mHomeProcess: " + mHomeProcess);
14560        }
14561        if (mPreviousProcess != null && (dumpPackage == null
14562                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14563            if (needSep) {
14564                pw.println();
14565                needSep = false;
14566            }
14567            pw.println("  mPreviousProcess: " + mPreviousProcess);
14568        }
14569        if (dumpAll) {
14570            StringBuilder sb = new StringBuilder(128);
14571            sb.append("  mPreviousProcessVisibleTime: ");
14572            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14573            pw.println(sb);
14574        }
14575        if (mHeavyWeightProcess != null && (dumpPackage == null
14576                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14577            if (needSep) {
14578                pw.println();
14579                needSep = false;
14580            }
14581            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14582        }
14583        if (dumpPackage == null) {
14584            pw.println("  mConfiguration: " + mConfiguration);
14585        }
14586        if (dumpAll) {
14587            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14588            if (mCompatModePackages.getPackages().size() > 0) {
14589                boolean printed = false;
14590                for (Map.Entry<String, Integer> entry
14591                        : mCompatModePackages.getPackages().entrySet()) {
14592                    String pkg = entry.getKey();
14593                    int mode = entry.getValue();
14594                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14595                        continue;
14596                    }
14597                    if (!printed) {
14598                        pw.println("  mScreenCompatPackages:");
14599                        printed = true;
14600                    }
14601                    pw.print("    "); pw.print(pkg); pw.print(": ");
14602                            pw.print(mode); pw.println();
14603                }
14604            }
14605        }
14606        if (dumpPackage == null) {
14607            pw.println("  mWakefulness="
14608                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14609            pw.println("  mSleepTokens=" + mSleepTokens);
14610            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14611                    + lockScreenShownToString());
14612            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14613            if (mRunningVoice != null) {
14614                pw.println("  mRunningVoice=" + mRunningVoice);
14615                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14616            }
14617        }
14618        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14619                || mOrigWaitForDebugger) {
14620            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14621                    || dumpPackage.equals(mOrigDebugApp)) {
14622                if (needSep) {
14623                    pw.println();
14624                    needSep = false;
14625                }
14626                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14627                        + " mDebugTransient=" + mDebugTransient
14628                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14629            }
14630        }
14631        if (mCurAppTimeTracker != null) {
14632            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14633        }
14634        if (mMemWatchProcesses.getMap().size() > 0) {
14635            pw.println("  Mem watch processes:");
14636            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14637                    = mMemWatchProcesses.getMap();
14638            for (int i=0; i<procs.size(); i++) {
14639                final String proc = procs.keyAt(i);
14640                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14641                for (int j=0; j<uids.size(); j++) {
14642                    if (needSep) {
14643                        pw.println();
14644                        needSep = false;
14645                    }
14646                    StringBuilder sb = new StringBuilder();
14647                    sb.append("    ").append(proc).append('/');
14648                    UserHandle.formatUid(sb, uids.keyAt(j));
14649                    Pair<Long, String> val = uids.valueAt(j);
14650                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14651                    if (val.second != null) {
14652                        sb.append(", report to ").append(val.second);
14653                    }
14654                    pw.println(sb.toString());
14655                }
14656            }
14657            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14658            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14659            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14660                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14661        }
14662        if (mTrackAllocationApp != null) {
14663            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14664                if (needSep) {
14665                    pw.println();
14666                    needSep = false;
14667                }
14668                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14669            }
14670        }
14671        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14672                || mProfileFd != null) {
14673            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14674                if (needSep) {
14675                    pw.println();
14676                    needSep = false;
14677                }
14678                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14679                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14680                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14681                        + mAutoStopProfiler);
14682                pw.println("  mProfileType=" + mProfileType);
14683            }
14684        }
14685        if (mNativeDebuggingApp != null) {
14686            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14687                if (needSep) {
14688                    pw.println();
14689                    needSep = false;
14690                }
14691                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14692            }
14693        }
14694        if (dumpPackage == null) {
14695            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14696                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14697                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14698            }
14699            if (mController != null) {
14700                pw.println("  mController=" + mController
14701                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14702            }
14703            if (dumpAll) {
14704                pw.println("  Total persistent processes: " + numPers);
14705                pw.println("  mProcessesReady=" + mProcessesReady
14706                        + " mSystemReady=" + mSystemReady
14707                        + " mBooted=" + mBooted
14708                        + " mFactoryTest=" + mFactoryTest);
14709                pw.println("  mBooting=" + mBooting
14710                        + " mCallFinishBooting=" + mCallFinishBooting
14711                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14712                pw.print("  mLastPowerCheckRealtime=");
14713                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14714                        pw.println("");
14715                pw.print("  mLastPowerCheckUptime=");
14716                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14717                        pw.println("");
14718                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14719                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14720                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14721                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14722                        + " (" + mLruProcesses.size() + " total)"
14723                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14724                        + " mNumServiceProcs=" + mNumServiceProcs
14725                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14726                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14727                        + " mLastMemoryLevel=" + mLastMemoryLevel
14728                        + " mLastNumProcesses=" + mLastNumProcesses);
14729                long now = SystemClock.uptimeMillis();
14730                pw.print("  mLastIdleTime=");
14731                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14732                        pw.print(" mLowRamSinceLastIdle=");
14733                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14734                        pw.println();
14735            }
14736        }
14737
14738        if (!printedAnything) {
14739            pw.println("  (nothing)");
14740        }
14741    }
14742
14743    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14744            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14745        if (mProcessesToGc.size() > 0) {
14746            boolean printed = false;
14747            long now = SystemClock.uptimeMillis();
14748            for (int i=0; i<mProcessesToGc.size(); i++) {
14749                ProcessRecord proc = mProcessesToGc.get(i);
14750                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14751                    continue;
14752                }
14753                if (!printed) {
14754                    if (needSep) pw.println();
14755                    needSep = true;
14756                    pw.println("  Processes that are waiting to GC:");
14757                    printed = true;
14758                }
14759                pw.print("    Process "); pw.println(proc);
14760                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14761                        pw.print(", last gced=");
14762                        pw.print(now-proc.lastRequestedGc);
14763                        pw.print(" ms ago, last lowMem=");
14764                        pw.print(now-proc.lastLowMemory);
14765                        pw.println(" ms ago");
14766
14767            }
14768        }
14769        return needSep;
14770    }
14771
14772    void printOomLevel(PrintWriter pw, String name, int adj) {
14773        pw.print("    ");
14774        if (adj >= 0) {
14775            pw.print(' ');
14776            if (adj < 10) pw.print(' ');
14777        } else {
14778            if (adj > -10) pw.print(' ');
14779        }
14780        pw.print(adj);
14781        pw.print(": ");
14782        pw.print(name);
14783        pw.print(" (");
14784        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14785        pw.println(")");
14786    }
14787
14788    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14789            int opti, boolean dumpAll) {
14790        boolean needSep = false;
14791
14792        if (mLruProcesses.size() > 0) {
14793            if (needSep) pw.println();
14794            needSep = true;
14795            pw.println("  OOM levels:");
14796            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14797            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14798            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14799            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14800            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14801            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14802            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14803            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14804            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14805            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14806            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14807            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14808            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14809            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14810
14811            if (needSep) pw.println();
14812            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14813                    pw.print(" total, non-act at ");
14814                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14815                    pw.print(", non-svc at ");
14816                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14817                    pw.println("):");
14818            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14819            needSep = true;
14820        }
14821
14822        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14823
14824        pw.println();
14825        pw.println("  mHomeProcess: " + mHomeProcess);
14826        pw.println("  mPreviousProcess: " + mPreviousProcess);
14827        if (mHeavyWeightProcess != null) {
14828            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14829        }
14830
14831        return true;
14832    }
14833
14834    /**
14835     * There are three ways to call this:
14836     *  - no provider specified: dump all the providers
14837     *  - a flattened component name that matched an existing provider was specified as the
14838     *    first arg: dump that one provider
14839     *  - the first arg isn't the flattened component name of an existing provider:
14840     *    dump all providers whose component contains the first arg as a substring
14841     */
14842    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14843            int opti, boolean dumpAll) {
14844        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14845    }
14846
14847    static class ItemMatcher {
14848        ArrayList<ComponentName> components;
14849        ArrayList<String> strings;
14850        ArrayList<Integer> objects;
14851        boolean all;
14852
14853        ItemMatcher() {
14854            all = true;
14855        }
14856
14857        void build(String name) {
14858            ComponentName componentName = ComponentName.unflattenFromString(name);
14859            if (componentName != null) {
14860                if (components == null) {
14861                    components = new ArrayList<ComponentName>();
14862                }
14863                components.add(componentName);
14864                all = false;
14865            } else {
14866                int objectId = 0;
14867                // Not a '/' separated full component name; maybe an object ID?
14868                try {
14869                    objectId = Integer.parseInt(name, 16);
14870                    if (objects == null) {
14871                        objects = new ArrayList<Integer>();
14872                    }
14873                    objects.add(objectId);
14874                    all = false;
14875                } catch (RuntimeException e) {
14876                    // Not an integer; just do string match.
14877                    if (strings == null) {
14878                        strings = new ArrayList<String>();
14879                    }
14880                    strings.add(name);
14881                    all = false;
14882                }
14883            }
14884        }
14885
14886        int build(String[] args, int opti) {
14887            for (; opti<args.length; opti++) {
14888                String name = args[opti];
14889                if ("--".equals(name)) {
14890                    return opti+1;
14891                }
14892                build(name);
14893            }
14894            return opti;
14895        }
14896
14897        boolean match(Object object, ComponentName comp) {
14898            if (all) {
14899                return true;
14900            }
14901            if (components != null) {
14902                for (int i=0; i<components.size(); i++) {
14903                    if (components.get(i).equals(comp)) {
14904                        return true;
14905                    }
14906                }
14907            }
14908            if (objects != null) {
14909                for (int i=0; i<objects.size(); i++) {
14910                    if (System.identityHashCode(object) == objects.get(i)) {
14911                        return true;
14912                    }
14913                }
14914            }
14915            if (strings != null) {
14916                String flat = comp.flattenToString();
14917                for (int i=0; i<strings.size(); i++) {
14918                    if (flat.contains(strings.get(i))) {
14919                        return true;
14920                    }
14921                }
14922            }
14923            return false;
14924        }
14925    }
14926
14927    /**
14928     * There are three things that cmd can be:
14929     *  - a flattened component name that matches an existing activity
14930     *  - the cmd arg isn't the flattened component name of an existing activity:
14931     *    dump all activity whose component contains the cmd as a substring
14932     *  - A hex number of the ActivityRecord object instance.
14933     */
14934    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14935            int opti, boolean dumpAll) {
14936        ArrayList<ActivityRecord> activities;
14937
14938        synchronized (this) {
14939            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14940        }
14941
14942        if (activities.size() <= 0) {
14943            return false;
14944        }
14945
14946        String[] newArgs = new String[args.length - opti];
14947        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14948
14949        TaskRecord lastTask = null;
14950        boolean needSep = false;
14951        for (int i=activities.size()-1; i>=0; i--) {
14952            ActivityRecord r = activities.get(i);
14953            if (needSep) {
14954                pw.println();
14955            }
14956            needSep = true;
14957            synchronized (this) {
14958                if (lastTask != r.task) {
14959                    lastTask = r.task;
14960                    pw.print("TASK "); pw.print(lastTask.affinity);
14961                            pw.print(" id="); pw.println(lastTask.taskId);
14962                    if (dumpAll) {
14963                        lastTask.dump(pw, "  ");
14964                    }
14965                }
14966            }
14967            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14968        }
14969        return true;
14970    }
14971
14972    /**
14973     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14974     * there is a thread associated with the activity.
14975     */
14976    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14977            final ActivityRecord r, String[] args, boolean dumpAll) {
14978        String innerPrefix = prefix + "  ";
14979        synchronized (this) {
14980            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14981                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14982                    pw.print(" pid=");
14983                    if (r.app != null) pw.println(r.app.pid);
14984                    else pw.println("(not running)");
14985            if (dumpAll) {
14986                r.dump(pw, innerPrefix);
14987            }
14988        }
14989        if (r.app != null && r.app.thread != null) {
14990            // flush anything that is already in the PrintWriter since the thread is going
14991            // to write to the file descriptor directly
14992            pw.flush();
14993            try {
14994                TransferPipe tp = new TransferPipe();
14995                try {
14996                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14997                            r.appToken, innerPrefix, args);
14998                    tp.go(fd);
14999                } finally {
15000                    tp.kill();
15001                }
15002            } catch (IOException e) {
15003                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15004            } catch (RemoteException e) {
15005                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15006            }
15007        }
15008    }
15009
15010    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15011            int opti, boolean dumpAll, String dumpPackage) {
15012        boolean needSep = false;
15013        boolean onlyHistory = false;
15014        boolean printedAnything = false;
15015
15016        if ("history".equals(dumpPackage)) {
15017            if (opti < args.length && "-s".equals(args[opti])) {
15018                dumpAll = false;
15019            }
15020            onlyHistory = true;
15021            dumpPackage = null;
15022        }
15023
15024        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15025        if (!onlyHistory && dumpAll) {
15026            if (mRegisteredReceivers.size() > 0) {
15027                boolean printed = false;
15028                Iterator it = mRegisteredReceivers.values().iterator();
15029                while (it.hasNext()) {
15030                    ReceiverList r = (ReceiverList)it.next();
15031                    if (dumpPackage != null && (r.app == null ||
15032                            !dumpPackage.equals(r.app.info.packageName))) {
15033                        continue;
15034                    }
15035                    if (!printed) {
15036                        pw.println("  Registered Receivers:");
15037                        needSep = true;
15038                        printed = true;
15039                        printedAnything = true;
15040                    }
15041                    pw.print("  * "); pw.println(r);
15042                    r.dump(pw, "    ");
15043                }
15044            }
15045
15046            if (mReceiverResolver.dump(pw, needSep ?
15047                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15048                    "    ", dumpPackage, false, false)) {
15049                needSep = true;
15050                printedAnything = true;
15051            }
15052        }
15053
15054        for (BroadcastQueue q : mBroadcastQueues) {
15055            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15056            printedAnything |= needSep;
15057        }
15058
15059        needSep = true;
15060
15061        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15062            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15063                if (needSep) {
15064                    pw.println();
15065                }
15066                needSep = true;
15067                printedAnything = true;
15068                pw.print("  Sticky broadcasts for user ");
15069                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15070                StringBuilder sb = new StringBuilder(128);
15071                for (Map.Entry<String, ArrayList<Intent>> ent
15072                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15073                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15074                    if (dumpAll) {
15075                        pw.println(":");
15076                        ArrayList<Intent> intents = ent.getValue();
15077                        final int N = intents.size();
15078                        for (int i=0; i<N; i++) {
15079                            sb.setLength(0);
15080                            sb.append("    Intent: ");
15081                            intents.get(i).toShortString(sb, false, true, false, false);
15082                            pw.println(sb.toString());
15083                            Bundle bundle = intents.get(i).getExtras();
15084                            if (bundle != null) {
15085                                pw.print("      ");
15086                                pw.println(bundle.toString());
15087                            }
15088                        }
15089                    } else {
15090                        pw.println("");
15091                    }
15092                }
15093            }
15094        }
15095
15096        if (!onlyHistory && dumpAll) {
15097            pw.println();
15098            for (BroadcastQueue queue : mBroadcastQueues) {
15099                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15100                        + queue.mBroadcastsScheduled);
15101            }
15102            pw.println("  mHandler:");
15103            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15104            needSep = true;
15105            printedAnything = true;
15106        }
15107
15108        if (!printedAnything) {
15109            pw.println("  (nothing)");
15110        }
15111    }
15112
15113    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15114            int opti, boolean dumpAll, String dumpPackage) {
15115        if (mCurBroadcastStats == null) {
15116            return;
15117        }
15118
15119        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15120        final long now = SystemClock.elapsedRealtime();
15121        if (mLastBroadcastStats != null) {
15122            pw.print("  Last stats (from ");
15123            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15124            pw.print(" to ");
15125            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15126            pw.print(", ");
15127            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15128                    - mLastBroadcastStats.mStartUptime, pw);
15129            pw.println(" uptime):");
15130            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15131                pw.println("    (nothing)");
15132            }
15133            pw.println();
15134        }
15135        pw.print("  Current stats (from ");
15136        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15137        pw.print(" to now, ");
15138        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15139                - mCurBroadcastStats.mStartUptime, pw);
15140        pw.println(" uptime):");
15141        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15142            pw.println("    (nothing)");
15143        }
15144    }
15145
15146    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15147            int opti, boolean fullCheckin, String dumpPackage) {
15148        if (mCurBroadcastStats == null) {
15149            return;
15150        }
15151
15152        if (mLastBroadcastStats != null) {
15153            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15154            if (fullCheckin) {
15155                mLastBroadcastStats = null;
15156                return;
15157            }
15158        }
15159        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15160        if (fullCheckin) {
15161            mCurBroadcastStats = null;
15162        }
15163    }
15164
15165    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15166            int opti, boolean dumpAll, String dumpPackage) {
15167        boolean needSep;
15168        boolean printedAnything = false;
15169
15170        ItemMatcher matcher = new ItemMatcher();
15171        matcher.build(args, opti);
15172
15173        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15174
15175        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15176        printedAnything |= needSep;
15177
15178        if (mLaunchingProviders.size() > 0) {
15179            boolean printed = false;
15180            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15181                ContentProviderRecord r = mLaunchingProviders.get(i);
15182                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15183                    continue;
15184                }
15185                if (!printed) {
15186                    if (needSep) pw.println();
15187                    needSep = true;
15188                    pw.println("  Launching content providers:");
15189                    printed = true;
15190                    printedAnything = true;
15191                }
15192                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15193                        pw.println(r);
15194            }
15195        }
15196
15197        if (!printedAnything) {
15198            pw.println("  (nothing)");
15199        }
15200    }
15201
15202    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15203            int opti, boolean dumpAll, String dumpPackage) {
15204        boolean needSep = false;
15205        boolean printedAnything = false;
15206
15207        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15208
15209        if (mGrantedUriPermissions.size() > 0) {
15210            boolean printed = false;
15211            int dumpUid = -2;
15212            if (dumpPackage != null) {
15213                try {
15214                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15215                            MATCH_UNINSTALLED_PACKAGES, 0);
15216                } catch (NameNotFoundException e) {
15217                    dumpUid = -1;
15218                }
15219            }
15220            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15221                int uid = mGrantedUriPermissions.keyAt(i);
15222                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15223                    continue;
15224                }
15225                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15226                if (!printed) {
15227                    if (needSep) pw.println();
15228                    needSep = true;
15229                    pw.println("  Granted Uri Permissions:");
15230                    printed = true;
15231                    printedAnything = true;
15232                }
15233                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15234                for (UriPermission perm : perms.values()) {
15235                    pw.print("    "); pw.println(perm);
15236                    if (dumpAll) {
15237                        perm.dump(pw, "      ");
15238                    }
15239                }
15240            }
15241        }
15242
15243        if (!printedAnything) {
15244            pw.println("  (nothing)");
15245        }
15246    }
15247
15248    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15249            int opti, boolean dumpAll, String dumpPackage) {
15250        boolean printed = false;
15251
15252        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15253
15254        if (mIntentSenderRecords.size() > 0) {
15255            Iterator<WeakReference<PendingIntentRecord>> it
15256                    = mIntentSenderRecords.values().iterator();
15257            while (it.hasNext()) {
15258                WeakReference<PendingIntentRecord> ref = it.next();
15259                PendingIntentRecord rec = ref != null ? ref.get(): null;
15260                if (dumpPackage != null && (rec == null
15261                        || !dumpPackage.equals(rec.key.packageName))) {
15262                    continue;
15263                }
15264                printed = true;
15265                if (rec != null) {
15266                    pw.print("  * "); pw.println(rec);
15267                    if (dumpAll) {
15268                        rec.dump(pw, "    ");
15269                    }
15270                } else {
15271                    pw.print("  * "); pw.println(ref);
15272                }
15273            }
15274        }
15275
15276        if (!printed) {
15277            pw.println("  (nothing)");
15278        }
15279    }
15280
15281    private static final int dumpProcessList(PrintWriter pw,
15282            ActivityManagerService service, List list,
15283            String prefix, String normalLabel, String persistentLabel,
15284            String dumpPackage) {
15285        int numPers = 0;
15286        final int N = list.size()-1;
15287        for (int i=N; i>=0; i--) {
15288            ProcessRecord r = (ProcessRecord)list.get(i);
15289            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15290                continue;
15291            }
15292            pw.println(String.format("%s%s #%2d: %s",
15293                    prefix, (r.persistent ? persistentLabel : normalLabel),
15294                    i, r.toString()));
15295            if (r.persistent) {
15296                numPers++;
15297            }
15298        }
15299        return numPers;
15300    }
15301
15302    private static final boolean dumpProcessOomList(PrintWriter pw,
15303            ActivityManagerService service, List<ProcessRecord> origList,
15304            String prefix, String normalLabel, String persistentLabel,
15305            boolean inclDetails, String dumpPackage) {
15306
15307        ArrayList<Pair<ProcessRecord, Integer>> list
15308                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15309        for (int i=0; i<origList.size(); i++) {
15310            ProcessRecord r = origList.get(i);
15311            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15312                continue;
15313            }
15314            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15315        }
15316
15317        if (list.size() <= 0) {
15318            return false;
15319        }
15320
15321        Comparator<Pair<ProcessRecord, Integer>> comparator
15322                = new Comparator<Pair<ProcessRecord, Integer>>() {
15323            @Override
15324            public int compare(Pair<ProcessRecord, Integer> object1,
15325                    Pair<ProcessRecord, Integer> object2) {
15326                if (object1.first.setAdj != object2.first.setAdj) {
15327                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15328                }
15329                if (object1.first.setProcState != object2.first.setProcState) {
15330                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15331                }
15332                if (object1.second.intValue() != object2.second.intValue()) {
15333                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15334                }
15335                return 0;
15336            }
15337        };
15338
15339        Collections.sort(list, comparator);
15340
15341        final long curRealtime = SystemClock.elapsedRealtime();
15342        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15343        final long curUptime = SystemClock.uptimeMillis();
15344        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15345
15346        for (int i=list.size()-1; i>=0; i--) {
15347            ProcessRecord r = list.get(i).first;
15348            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15349            char schedGroup;
15350            switch (r.setSchedGroup) {
15351                case ProcessList.SCHED_GROUP_BACKGROUND:
15352                    schedGroup = 'B';
15353                    break;
15354                case ProcessList.SCHED_GROUP_DEFAULT:
15355                    schedGroup = 'F';
15356                    break;
15357                case ProcessList.SCHED_GROUP_TOP_APP:
15358                    schedGroup = 'T';
15359                    break;
15360                default:
15361                    schedGroup = '?';
15362                    break;
15363            }
15364            char foreground;
15365            if (r.foregroundActivities) {
15366                foreground = 'A';
15367            } else if (r.foregroundServices) {
15368                foreground = 'S';
15369            } else {
15370                foreground = ' ';
15371            }
15372            String procState = ProcessList.makeProcStateString(r.curProcState);
15373            pw.print(prefix);
15374            pw.print(r.persistent ? persistentLabel : normalLabel);
15375            pw.print(" #");
15376            int num = (origList.size()-1)-list.get(i).second;
15377            if (num < 10) pw.print(' ');
15378            pw.print(num);
15379            pw.print(": ");
15380            pw.print(oomAdj);
15381            pw.print(' ');
15382            pw.print(schedGroup);
15383            pw.print('/');
15384            pw.print(foreground);
15385            pw.print('/');
15386            pw.print(procState);
15387            pw.print(" trm:");
15388            if (r.trimMemoryLevel < 10) pw.print(' ');
15389            pw.print(r.trimMemoryLevel);
15390            pw.print(' ');
15391            pw.print(r.toShortString());
15392            pw.print(" (");
15393            pw.print(r.adjType);
15394            pw.println(')');
15395            if (r.adjSource != null || r.adjTarget != null) {
15396                pw.print(prefix);
15397                pw.print("    ");
15398                if (r.adjTarget instanceof ComponentName) {
15399                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15400                } else if (r.adjTarget != null) {
15401                    pw.print(r.adjTarget.toString());
15402                } else {
15403                    pw.print("{null}");
15404                }
15405                pw.print("<=");
15406                if (r.adjSource instanceof ProcessRecord) {
15407                    pw.print("Proc{");
15408                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15409                    pw.println("}");
15410                } else if (r.adjSource != null) {
15411                    pw.println(r.adjSource.toString());
15412                } else {
15413                    pw.println("{null}");
15414                }
15415            }
15416            if (inclDetails) {
15417                pw.print(prefix);
15418                pw.print("    ");
15419                pw.print("oom: max="); pw.print(r.maxAdj);
15420                pw.print(" curRaw="); pw.print(r.curRawAdj);
15421                pw.print(" setRaw="); pw.print(r.setRawAdj);
15422                pw.print(" cur="); pw.print(r.curAdj);
15423                pw.print(" set="); pw.println(r.setAdj);
15424                pw.print(prefix);
15425                pw.print("    ");
15426                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15427                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15428                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15429                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15430                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15431                pw.println();
15432                pw.print(prefix);
15433                pw.print("    ");
15434                pw.print("cached="); pw.print(r.cached);
15435                pw.print(" empty="); pw.print(r.empty);
15436                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15437
15438                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15439                    if (r.lastWakeTime != 0) {
15440                        long wtime;
15441                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15442                        synchronized (stats) {
15443                            wtime = stats.getProcessWakeTime(r.info.uid,
15444                                    r.pid, curRealtime);
15445                        }
15446                        long timeUsed = wtime - r.lastWakeTime;
15447                        pw.print(prefix);
15448                        pw.print("    ");
15449                        pw.print("keep awake over ");
15450                        TimeUtils.formatDuration(realtimeSince, pw);
15451                        pw.print(" used ");
15452                        TimeUtils.formatDuration(timeUsed, pw);
15453                        pw.print(" (");
15454                        pw.print((timeUsed*100)/realtimeSince);
15455                        pw.println("%)");
15456                    }
15457                    if (r.lastCpuTime != 0) {
15458                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15459                        pw.print(prefix);
15460                        pw.print("    ");
15461                        pw.print("run cpu over ");
15462                        TimeUtils.formatDuration(uptimeSince, pw);
15463                        pw.print(" used ");
15464                        TimeUtils.formatDuration(timeUsed, pw);
15465                        pw.print(" (");
15466                        pw.print((timeUsed*100)/uptimeSince);
15467                        pw.println("%)");
15468                    }
15469                }
15470            }
15471        }
15472        return true;
15473    }
15474
15475    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15476            String[] args) {
15477        ArrayList<ProcessRecord> procs;
15478        synchronized (this) {
15479            if (args != null && args.length > start
15480                    && args[start].charAt(0) != '-') {
15481                procs = new ArrayList<ProcessRecord>();
15482                int pid = -1;
15483                try {
15484                    pid = Integer.parseInt(args[start]);
15485                } catch (NumberFormatException e) {
15486                }
15487                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15488                    ProcessRecord proc = mLruProcesses.get(i);
15489                    if (proc.pid == pid) {
15490                        procs.add(proc);
15491                    } else if (allPkgs && proc.pkgList != null
15492                            && proc.pkgList.containsKey(args[start])) {
15493                        procs.add(proc);
15494                    } else if (proc.processName.equals(args[start])) {
15495                        procs.add(proc);
15496                    }
15497                }
15498                if (procs.size() <= 0) {
15499                    return null;
15500                }
15501            } else {
15502                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15503            }
15504        }
15505        return procs;
15506    }
15507
15508    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15509            PrintWriter pw, String[] args) {
15510        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15511        if (procs == null) {
15512            pw.println("No process found for: " + args[0]);
15513            return;
15514        }
15515
15516        long uptime = SystemClock.uptimeMillis();
15517        long realtime = SystemClock.elapsedRealtime();
15518        pw.println("Applications Graphics Acceleration Info:");
15519        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15520
15521        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15522            ProcessRecord r = procs.get(i);
15523            if (r.thread != null) {
15524                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15525                pw.flush();
15526                try {
15527                    TransferPipe tp = new TransferPipe();
15528                    try {
15529                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15530                        tp.go(fd);
15531                    } finally {
15532                        tp.kill();
15533                    }
15534                } catch (IOException e) {
15535                    pw.println("Failure while dumping the app: " + r);
15536                    pw.flush();
15537                } catch (RemoteException e) {
15538                    pw.println("Got a RemoteException while dumping the app " + r);
15539                    pw.flush();
15540                }
15541            }
15542        }
15543    }
15544
15545    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15546        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15547        if (procs == null) {
15548            pw.println("No process found for: " + args[0]);
15549            return;
15550        }
15551
15552        pw.println("Applications Database Info:");
15553
15554        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15555            ProcessRecord r = procs.get(i);
15556            if (r.thread != null) {
15557                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15558                pw.flush();
15559                try {
15560                    TransferPipe tp = new TransferPipe();
15561                    try {
15562                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15563                        tp.go(fd);
15564                    } finally {
15565                        tp.kill();
15566                    }
15567                } catch (IOException e) {
15568                    pw.println("Failure while dumping the app: " + r);
15569                    pw.flush();
15570                } catch (RemoteException e) {
15571                    pw.println("Got a RemoteException while dumping the app " + r);
15572                    pw.flush();
15573                }
15574            }
15575        }
15576    }
15577
15578    final static class MemItem {
15579        final boolean isProc;
15580        final String label;
15581        final String shortLabel;
15582        final long pss;
15583        final long swapPss;
15584        final int id;
15585        final boolean hasActivities;
15586        ArrayList<MemItem> subitems;
15587
15588        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15589                boolean _hasActivities) {
15590            isProc = true;
15591            label = _label;
15592            shortLabel = _shortLabel;
15593            pss = _pss;
15594            swapPss = _swapPss;
15595            id = _id;
15596            hasActivities = _hasActivities;
15597        }
15598
15599        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15600            isProc = false;
15601            label = _label;
15602            shortLabel = _shortLabel;
15603            pss = _pss;
15604            swapPss = _swapPss;
15605            id = _id;
15606            hasActivities = false;
15607        }
15608    }
15609
15610    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15611            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15612        if (sort && !isCompact) {
15613            Collections.sort(items, new Comparator<MemItem>() {
15614                @Override
15615                public int compare(MemItem lhs, MemItem rhs) {
15616                    if (lhs.pss < rhs.pss) {
15617                        return 1;
15618                    } else if (lhs.pss > rhs.pss) {
15619                        return -1;
15620                    }
15621                    return 0;
15622                }
15623            });
15624        }
15625
15626        for (int i=0; i<items.size(); i++) {
15627            MemItem mi = items.get(i);
15628            if (!isCompact) {
15629                if (dumpSwapPss) {
15630                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15631                            mi.label, stringifyKBSize(mi.swapPss));
15632                } else {
15633                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15634                }
15635            } else if (mi.isProc) {
15636                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15637                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15638                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15639                pw.println(mi.hasActivities ? ",a" : ",e");
15640            } else {
15641                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15642                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15643            }
15644            if (mi.subitems != null) {
15645                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15646                        true, isCompact, dumpSwapPss);
15647            }
15648        }
15649    }
15650
15651    // These are in KB.
15652    static final long[] DUMP_MEM_BUCKETS = new long[] {
15653        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15654        120*1024, 160*1024, 200*1024,
15655        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15656        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15657    };
15658
15659    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15660            boolean stackLike) {
15661        int start = label.lastIndexOf('.');
15662        if (start >= 0) start++;
15663        else start = 0;
15664        int end = label.length();
15665        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15666            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15667                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15668                out.append(bucket);
15669                out.append(stackLike ? "MB." : "MB ");
15670                out.append(label, start, end);
15671                return;
15672            }
15673        }
15674        out.append(memKB/1024);
15675        out.append(stackLike ? "MB." : "MB ");
15676        out.append(label, start, end);
15677    }
15678
15679    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15680            ProcessList.NATIVE_ADJ,
15681            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15682            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15683            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15684            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15685            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15686            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15687    };
15688    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15689            "Native",
15690            "System", "Persistent", "Persistent Service", "Foreground",
15691            "Visible", "Perceptible",
15692            "Heavy Weight", "Backup",
15693            "A Services", "Home",
15694            "Previous", "B Services", "Cached"
15695    };
15696    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15697            "native",
15698            "sys", "pers", "persvc", "fore",
15699            "vis", "percept",
15700            "heavy", "backup",
15701            "servicea", "home",
15702            "prev", "serviceb", "cached"
15703    };
15704
15705    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15706            long realtime, boolean isCheckinRequest, boolean isCompact) {
15707        if (isCompact) {
15708            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15709        }
15710        if (isCheckinRequest || isCompact) {
15711            // short checkin version
15712            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15713        } else {
15714            pw.println("Applications Memory Usage (in Kilobytes):");
15715            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15716        }
15717    }
15718
15719    private static final int KSM_SHARED = 0;
15720    private static final int KSM_SHARING = 1;
15721    private static final int KSM_UNSHARED = 2;
15722    private static final int KSM_VOLATILE = 3;
15723
15724    private final long[] getKsmInfo() {
15725        long[] longOut = new long[4];
15726        final int[] SINGLE_LONG_FORMAT = new int[] {
15727            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15728        };
15729        long[] longTmp = new long[1];
15730        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15731                SINGLE_LONG_FORMAT, null, longTmp, null);
15732        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15733        longTmp[0] = 0;
15734        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15735                SINGLE_LONG_FORMAT, null, longTmp, null);
15736        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15737        longTmp[0] = 0;
15738        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15739                SINGLE_LONG_FORMAT, null, longTmp, null);
15740        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15741        longTmp[0] = 0;
15742        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15743                SINGLE_LONG_FORMAT, null, longTmp, null);
15744        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15745        return longOut;
15746    }
15747
15748    private static String stringifySize(long size, int order) {
15749        Locale locale = Locale.US;
15750        switch (order) {
15751            case 1:
15752                return String.format(locale, "%,13d", size);
15753            case 1024:
15754                return String.format(locale, "%,9dK", size / 1024);
15755            case 1024 * 1024:
15756                return String.format(locale, "%,5dM", size / 1024 / 1024);
15757            case 1024 * 1024 * 1024:
15758                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15759            default:
15760                throw new IllegalArgumentException("Invalid size order");
15761        }
15762    }
15763
15764    private static String stringifyKBSize(long size) {
15765        return stringifySize(size * 1024, 1024);
15766    }
15767
15768    // Update this version number in case you change the 'compact' format
15769    private static final int MEMINFO_COMPACT_VERSION = 1;
15770
15771    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15772            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15773        boolean dumpDetails = false;
15774        boolean dumpFullDetails = false;
15775        boolean dumpDalvik = false;
15776        boolean dumpSummaryOnly = false;
15777        boolean dumpUnreachable = false;
15778        boolean oomOnly = false;
15779        boolean isCompact = false;
15780        boolean localOnly = false;
15781        boolean packages = false;
15782        boolean isCheckinRequest = false;
15783        boolean dumpSwapPss = false;
15784
15785        int opti = 0;
15786        while (opti < args.length) {
15787            String opt = args[opti];
15788            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15789                break;
15790            }
15791            opti++;
15792            if ("-a".equals(opt)) {
15793                dumpDetails = true;
15794                dumpFullDetails = true;
15795                dumpDalvik = true;
15796                dumpSwapPss = true;
15797            } else if ("-d".equals(opt)) {
15798                dumpDalvik = true;
15799            } else if ("-c".equals(opt)) {
15800                isCompact = true;
15801            } else if ("-s".equals(opt)) {
15802                dumpDetails = true;
15803                dumpSummaryOnly = true;
15804            } else if ("-S".equals(opt)) {
15805                dumpSwapPss = true;
15806            } else if ("--unreachable".equals(opt)) {
15807                dumpUnreachable = true;
15808            } else if ("--oom".equals(opt)) {
15809                oomOnly = true;
15810            } else if ("--local".equals(opt)) {
15811                localOnly = true;
15812            } else if ("--package".equals(opt)) {
15813                packages = true;
15814            } else if ("--checkin".equals(opt)) {
15815                isCheckinRequest = true;
15816
15817            } else if ("-h".equals(opt)) {
15818                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15819                pw.println("  -a: include all available information for each process.");
15820                pw.println("  -d: include dalvik details.");
15821                pw.println("  -c: dump in a compact machine-parseable representation.");
15822                pw.println("  -s: dump only summary of application memory usage.");
15823                pw.println("  -S: dump also SwapPss.");
15824                pw.println("  --oom: only show processes organized by oom adj.");
15825                pw.println("  --local: only collect details locally, don't call process.");
15826                pw.println("  --package: interpret process arg as package, dumping all");
15827                pw.println("             processes that have loaded that package.");
15828                pw.println("  --checkin: dump data for a checkin");
15829                pw.println("If [process] is specified it can be the name or ");
15830                pw.println("pid of a specific process to dump.");
15831                return;
15832            } else {
15833                pw.println("Unknown argument: " + opt + "; use -h for help");
15834            }
15835        }
15836
15837        long uptime = SystemClock.uptimeMillis();
15838        long realtime = SystemClock.elapsedRealtime();
15839        final long[] tmpLong = new long[1];
15840
15841        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15842        if (procs == null) {
15843            // No Java processes.  Maybe they want to print a native process.
15844            if (args != null && args.length > opti
15845                    && args[opti].charAt(0) != '-') {
15846                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15847                        = new ArrayList<ProcessCpuTracker.Stats>();
15848                updateCpuStatsNow();
15849                int findPid = -1;
15850                try {
15851                    findPid = Integer.parseInt(args[opti]);
15852                } catch (NumberFormatException e) {
15853                }
15854                synchronized (mProcessCpuTracker) {
15855                    final int N = mProcessCpuTracker.countStats();
15856                    for (int i=0; i<N; i++) {
15857                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15858                        if (st.pid == findPid || (st.baseName != null
15859                                && st.baseName.equals(args[opti]))) {
15860                            nativeProcs.add(st);
15861                        }
15862                    }
15863                }
15864                if (nativeProcs.size() > 0) {
15865                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15866                            isCompact);
15867                    Debug.MemoryInfo mi = null;
15868                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15869                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15870                        final int pid = r.pid;
15871                        if (!isCheckinRequest && dumpDetails) {
15872                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15873                        }
15874                        if (mi == null) {
15875                            mi = new Debug.MemoryInfo();
15876                        }
15877                        if (dumpDetails || (!brief && !oomOnly)) {
15878                            Debug.getMemoryInfo(pid, mi);
15879                        } else {
15880                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15881                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15882                        }
15883                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15884                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15885                        if (isCheckinRequest) {
15886                            pw.println();
15887                        }
15888                    }
15889                    return;
15890                }
15891            }
15892            pw.println("No process found for: " + args[opti]);
15893            return;
15894        }
15895
15896        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15897            dumpDetails = true;
15898        }
15899
15900        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15901
15902        String[] innerArgs = new String[args.length-opti];
15903        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15904
15905        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15906        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15907        long nativePss = 0;
15908        long nativeSwapPss = 0;
15909        long dalvikPss = 0;
15910        long dalvikSwapPss = 0;
15911        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15912                EmptyArray.LONG;
15913        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15914                EmptyArray.LONG;
15915        long otherPss = 0;
15916        long otherSwapPss = 0;
15917        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15918        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15919
15920        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15921        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15922        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15923                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15924
15925        long totalPss = 0;
15926        long totalSwapPss = 0;
15927        long cachedPss = 0;
15928        long cachedSwapPss = 0;
15929        boolean hasSwapPss = false;
15930
15931        Debug.MemoryInfo mi = null;
15932        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15933            final ProcessRecord r = procs.get(i);
15934            final IApplicationThread thread;
15935            final int pid;
15936            final int oomAdj;
15937            final boolean hasActivities;
15938            synchronized (this) {
15939                thread = r.thread;
15940                pid = r.pid;
15941                oomAdj = r.getSetAdjWithServices();
15942                hasActivities = r.activities.size() > 0;
15943            }
15944            if (thread != null) {
15945                if (!isCheckinRequest && dumpDetails) {
15946                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15947                }
15948                if (mi == null) {
15949                    mi = new Debug.MemoryInfo();
15950                }
15951                if (dumpDetails || (!brief && !oomOnly)) {
15952                    Debug.getMemoryInfo(pid, mi);
15953                    hasSwapPss = mi.hasSwappedOutPss;
15954                } else {
15955                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15956                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15957                }
15958                if (dumpDetails) {
15959                    if (localOnly) {
15960                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15961                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15962                        if (isCheckinRequest) {
15963                            pw.println();
15964                        }
15965                    } else {
15966                        try {
15967                            pw.flush();
15968                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15969                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15970                        } catch (RemoteException e) {
15971                            if (!isCheckinRequest) {
15972                                pw.println("Got RemoteException!");
15973                                pw.flush();
15974                            }
15975                        }
15976                    }
15977                }
15978
15979                final long myTotalPss = mi.getTotalPss();
15980                final long myTotalUss = mi.getTotalUss();
15981                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15982
15983                synchronized (this) {
15984                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15985                        // Record this for posterity if the process has been stable.
15986                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15987                    }
15988                }
15989
15990                if (!isCheckinRequest && mi != null) {
15991                    totalPss += myTotalPss;
15992                    totalSwapPss += myTotalSwapPss;
15993                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15994                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15995                            myTotalSwapPss, pid, hasActivities);
15996                    procMems.add(pssItem);
15997                    procMemsMap.put(pid, pssItem);
15998
15999                    nativePss += mi.nativePss;
16000                    nativeSwapPss += mi.nativeSwappedOutPss;
16001                    dalvikPss += mi.dalvikPss;
16002                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16003                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16004                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16005                        dalvikSubitemSwapPss[j] +=
16006                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16007                    }
16008                    otherPss += mi.otherPss;
16009                    otherSwapPss += mi.otherSwappedOutPss;
16010                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16011                        long mem = mi.getOtherPss(j);
16012                        miscPss[j] += mem;
16013                        otherPss -= mem;
16014                        mem = mi.getOtherSwappedOutPss(j);
16015                        miscSwapPss[j] += mem;
16016                        otherSwapPss -= mem;
16017                    }
16018
16019                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16020                        cachedPss += myTotalPss;
16021                        cachedSwapPss += myTotalSwapPss;
16022                    }
16023
16024                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16025                        if (oomIndex == (oomPss.length - 1)
16026                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16027                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16028                            oomPss[oomIndex] += myTotalPss;
16029                            oomSwapPss[oomIndex] += myTotalSwapPss;
16030                            if (oomProcs[oomIndex] == null) {
16031                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16032                            }
16033                            oomProcs[oomIndex].add(pssItem);
16034                            break;
16035                        }
16036                    }
16037                }
16038            }
16039        }
16040
16041        long nativeProcTotalPss = 0;
16042
16043        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16044            // If we are showing aggregations, also look for native processes to
16045            // include so that our aggregations are more accurate.
16046            updateCpuStatsNow();
16047            mi = null;
16048            synchronized (mProcessCpuTracker) {
16049                final int N = mProcessCpuTracker.countStats();
16050                for (int i=0; i<N; i++) {
16051                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16052                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16053                        if (mi == null) {
16054                            mi = new Debug.MemoryInfo();
16055                        }
16056                        if (!brief && !oomOnly) {
16057                            Debug.getMemoryInfo(st.pid, mi);
16058                        } else {
16059                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16060                            mi.nativePrivateDirty = (int)tmpLong[0];
16061                        }
16062
16063                        final long myTotalPss = mi.getTotalPss();
16064                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16065                        totalPss += myTotalPss;
16066                        nativeProcTotalPss += myTotalPss;
16067
16068                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16069                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16070                        procMems.add(pssItem);
16071
16072                        nativePss += mi.nativePss;
16073                        nativeSwapPss += mi.nativeSwappedOutPss;
16074                        dalvikPss += mi.dalvikPss;
16075                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16076                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16077                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16078                            dalvikSubitemSwapPss[j] +=
16079                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16080                        }
16081                        otherPss += mi.otherPss;
16082                        otherSwapPss += mi.otherSwappedOutPss;
16083                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16084                            long mem = mi.getOtherPss(j);
16085                            miscPss[j] += mem;
16086                            otherPss -= mem;
16087                            mem = mi.getOtherSwappedOutPss(j);
16088                            miscSwapPss[j] += mem;
16089                            otherSwapPss -= mem;
16090                        }
16091                        oomPss[0] += myTotalPss;
16092                        oomSwapPss[0] += myTotalSwapPss;
16093                        if (oomProcs[0] == null) {
16094                            oomProcs[0] = new ArrayList<MemItem>();
16095                        }
16096                        oomProcs[0].add(pssItem);
16097                    }
16098                }
16099            }
16100
16101            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16102
16103            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16104            final MemItem dalvikItem =
16105                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16106            if (dalvikSubitemPss.length > 0) {
16107                dalvikItem.subitems = new ArrayList<MemItem>();
16108                for (int j=0; j<dalvikSubitemPss.length; j++) {
16109                    final String name = Debug.MemoryInfo.getOtherLabel(
16110                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16111                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16112                                    dalvikSubitemSwapPss[j], j));
16113                }
16114            }
16115            catMems.add(dalvikItem);
16116            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16117            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16118                String label = Debug.MemoryInfo.getOtherLabel(j);
16119                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16120            }
16121
16122            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16123            for (int j=0; j<oomPss.length; j++) {
16124                if (oomPss[j] != 0) {
16125                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16126                            : DUMP_MEM_OOM_LABEL[j];
16127                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16128                            DUMP_MEM_OOM_ADJ[j]);
16129                    item.subitems = oomProcs[j];
16130                    oomMems.add(item);
16131                }
16132            }
16133
16134            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16135            if (!brief && !oomOnly && !isCompact) {
16136                pw.println();
16137                pw.println("Total PSS by process:");
16138                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16139                pw.println();
16140            }
16141            if (!isCompact) {
16142                pw.println("Total PSS by OOM adjustment:");
16143            }
16144            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16145            if (!brief && !oomOnly) {
16146                PrintWriter out = categoryPw != null ? categoryPw : pw;
16147                if (!isCompact) {
16148                    out.println();
16149                    out.println("Total PSS by category:");
16150                }
16151                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16152            }
16153            if (!isCompact) {
16154                pw.println();
16155            }
16156            MemInfoReader memInfo = new MemInfoReader();
16157            memInfo.readMemInfo();
16158            if (nativeProcTotalPss > 0) {
16159                synchronized (this) {
16160                    final long cachedKb = memInfo.getCachedSizeKb();
16161                    final long freeKb = memInfo.getFreeSizeKb();
16162                    final long zramKb = memInfo.getZramTotalSizeKb();
16163                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16164                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16165                            kernelKb*1024, nativeProcTotalPss*1024);
16166                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16167                            nativeProcTotalPss);
16168                }
16169            }
16170            if (!brief) {
16171                if (!isCompact) {
16172                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16173                    pw.print(" (status ");
16174                    switch (mLastMemoryLevel) {
16175                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16176                            pw.println("normal)");
16177                            break;
16178                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16179                            pw.println("moderate)");
16180                            break;
16181                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16182                            pw.println("low)");
16183                            break;
16184                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16185                            pw.println("critical)");
16186                            break;
16187                        default:
16188                            pw.print(mLastMemoryLevel);
16189                            pw.println(")");
16190                            break;
16191                    }
16192                    pw.print(" Free RAM: ");
16193                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16194                            + memInfo.getFreeSizeKb()));
16195                    pw.print(" (");
16196                    pw.print(stringifyKBSize(cachedPss));
16197                    pw.print(" cached pss + ");
16198                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16199                    pw.print(" cached kernel + ");
16200                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16201                    pw.println(" free)");
16202                } else {
16203                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16204                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16205                            + memInfo.getFreeSizeKb()); pw.print(",");
16206                    pw.println(totalPss - cachedPss);
16207                }
16208            }
16209            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16210                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16211                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16212            if (!isCompact) {
16213                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16214                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16215                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16216                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16217                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16218            } else {
16219                pw.print("lostram,"); pw.println(lostRAM);
16220            }
16221            if (!brief) {
16222                if (memInfo.getZramTotalSizeKb() != 0) {
16223                    if (!isCompact) {
16224                        pw.print("     ZRAM: ");
16225                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16226                                pw.print(" physical used for ");
16227                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16228                                        - memInfo.getSwapFreeSizeKb()));
16229                                pw.print(" in swap (");
16230                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16231                                pw.println(" total swap)");
16232                    } else {
16233                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16234                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16235                                pw.println(memInfo.getSwapFreeSizeKb());
16236                    }
16237                }
16238                final long[] ksm = getKsmInfo();
16239                if (!isCompact) {
16240                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16241                            || ksm[KSM_VOLATILE] != 0) {
16242                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16243                                pw.print(" saved from shared ");
16244                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16245                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16246                                pw.print(" unshared; ");
16247                                pw.print(stringifyKBSize(
16248                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16249                    }
16250                    pw.print("   Tuning: ");
16251                    pw.print(ActivityManager.staticGetMemoryClass());
16252                    pw.print(" (large ");
16253                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16254                    pw.print("), oom ");
16255                    pw.print(stringifySize(
16256                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16257                    pw.print(", restore limit ");
16258                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16259                    if (ActivityManager.isLowRamDeviceStatic()) {
16260                        pw.print(" (low-ram)");
16261                    }
16262                    if (ActivityManager.isHighEndGfx()) {
16263                        pw.print(" (high-end-gfx)");
16264                    }
16265                    pw.println();
16266                } else {
16267                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16268                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16269                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16270                    pw.print("tuning,");
16271                    pw.print(ActivityManager.staticGetMemoryClass());
16272                    pw.print(',');
16273                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16274                    pw.print(',');
16275                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16276                    if (ActivityManager.isLowRamDeviceStatic()) {
16277                        pw.print(",low-ram");
16278                    }
16279                    if (ActivityManager.isHighEndGfx()) {
16280                        pw.print(",high-end-gfx");
16281                    }
16282                    pw.println();
16283                }
16284            }
16285        }
16286    }
16287
16288    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16289            long memtrack, String name) {
16290        sb.append("  ");
16291        sb.append(ProcessList.makeOomAdjString(oomAdj));
16292        sb.append(' ');
16293        sb.append(ProcessList.makeProcStateString(procState));
16294        sb.append(' ');
16295        ProcessList.appendRamKb(sb, pss);
16296        sb.append(": ");
16297        sb.append(name);
16298        if (memtrack > 0) {
16299            sb.append(" (");
16300            sb.append(stringifyKBSize(memtrack));
16301            sb.append(" memtrack)");
16302        }
16303    }
16304
16305    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16306        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16307        sb.append(" (pid ");
16308        sb.append(mi.pid);
16309        sb.append(") ");
16310        sb.append(mi.adjType);
16311        sb.append('\n');
16312        if (mi.adjReason != null) {
16313            sb.append("                      ");
16314            sb.append(mi.adjReason);
16315            sb.append('\n');
16316        }
16317    }
16318
16319    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16320        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16321        for (int i=0, N=memInfos.size(); i<N; i++) {
16322            ProcessMemInfo mi = memInfos.get(i);
16323            infoMap.put(mi.pid, mi);
16324        }
16325        updateCpuStatsNow();
16326        long[] memtrackTmp = new long[1];
16327        synchronized (mProcessCpuTracker) {
16328            final int N = mProcessCpuTracker.countStats();
16329            for (int i=0; i<N; i++) {
16330                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16331                if (st.vsize > 0) {
16332                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16333                    if (pss > 0) {
16334                        if (infoMap.indexOfKey(st.pid) < 0) {
16335                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16336                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16337                            mi.pss = pss;
16338                            mi.memtrack = memtrackTmp[0];
16339                            memInfos.add(mi);
16340                        }
16341                    }
16342                }
16343            }
16344        }
16345
16346        long totalPss = 0;
16347        long totalMemtrack = 0;
16348        for (int i=0, N=memInfos.size(); i<N; i++) {
16349            ProcessMemInfo mi = memInfos.get(i);
16350            if (mi.pss == 0) {
16351                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16352                mi.memtrack = memtrackTmp[0];
16353            }
16354            totalPss += mi.pss;
16355            totalMemtrack += mi.memtrack;
16356        }
16357        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16358            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16359                if (lhs.oomAdj != rhs.oomAdj) {
16360                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16361                }
16362                if (lhs.pss != rhs.pss) {
16363                    return lhs.pss < rhs.pss ? 1 : -1;
16364                }
16365                return 0;
16366            }
16367        });
16368
16369        StringBuilder tag = new StringBuilder(128);
16370        StringBuilder stack = new StringBuilder(128);
16371        tag.append("Low on memory -- ");
16372        appendMemBucket(tag, totalPss, "total", false);
16373        appendMemBucket(stack, totalPss, "total", true);
16374
16375        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16376        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16377        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16378
16379        boolean firstLine = true;
16380        int lastOomAdj = Integer.MIN_VALUE;
16381        long extraNativeRam = 0;
16382        long extraNativeMemtrack = 0;
16383        long cachedPss = 0;
16384        for (int i=0, N=memInfos.size(); i<N; i++) {
16385            ProcessMemInfo mi = memInfos.get(i);
16386
16387            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16388                cachedPss += mi.pss;
16389            }
16390
16391            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16392                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16393                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16394                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16395                if (lastOomAdj != mi.oomAdj) {
16396                    lastOomAdj = mi.oomAdj;
16397                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16398                        tag.append(" / ");
16399                    }
16400                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16401                        if (firstLine) {
16402                            stack.append(":");
16403                            firstLine = false;
16404                        }
16405                        stack.append("\n\t at ");
16406                    } else {
16407                        stack.append("$");
16408                    }
16409                } else {
16410                    tag.append(" ");
16411                    stack.append("$");
16412                }
16413                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16414                    appendMemBucket(tag, mi.pss, mi.name, false);
16415                }
16416                appendMemBucket(stack, mi.pss, mi.name, true);
16417                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16418                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16419                    stack.append("(");
16420                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16421                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16422                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16423                            stack.append(":");
16424                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16425                        }
16426                    }
16427                    stack.append(")");
16428                }
16429            }
16430
16431            appendMemInfo(fullNativeBuilder, mi);
16432            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16433                // The short form only has native processes that are >= 512K.
16434                if (mi.pss >= 512) {
16435                    appendMemInfo(shortNativeBuilder, mi);
16436                } else {
16437                    extraNativeRam += mi.pss;
16438                    extraNativeMemtrack += mi.memtrack;
16439                }
16440            } else {
16441                // Short form has all other details, but if we have collected RAM
16442                // from smaller native processes let's dump a summary of that.
16443                if (extraNativeRam > 0) {
16444                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16445                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16446                    shortNativeBuilder.append('\n');
16447                    extraNativeRam = 0;
16448                }
16449                appendMemInfo(fullJavaBuilder, mi);
16450            }
16451        }
16452
16453        fullJavaBuilder.append("           ");
16454        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16455        fullJavaBuilder.append(": TOTAL");
16456        if (totalMemtrack > 0) {
16457            fullJavaBuilder.append(" (");
16458            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16459            fullJavaBuilder.append(" memtrack)");
16460        } else {
16461        }
16462        fullJavaBuilder.append("\n");
16463
16464        MemInfoReader memInfo = new MemInfoReader();
16465        memInfo.readMemInfo();
16466        final long[] infos = memInfo.getRawInfo();
16467
16468        StringBuilder memInfoBuilder = new StringBuilder(1024);
16469        Debug.getMemInfo(infos);
16470        memInfoBuilder.append("  MemInfo: ");
16471        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16472        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16473        memInfoBuilder.append(stringifyKBSize(
16474                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16475        memInfoBuilder.append(stringifyKBSize(
16476                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16477        memInfoBuilder.append(stringifyKBSize(
16478                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16479        memInfoBuilder.append("           ");
16480        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16481        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16482        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16483        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16484        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16485            memInfoBuilder.append("  ZRAM: ");
16486            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16487            memInfoBuilder.append(" RAM, ");
16488            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16489            memInfoBuilder.append(" swap total, ");
16490            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16491            memInfoBuilder.append(" swap free\n");
16492        }
16493        final long[] ksm = getKsmInfo();
16494        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16495                || ksm[KSM_VOLATILE] != 0) {
16496            memInfoBuilder.append("  KSM: ");
16497            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16498            memInfoBuilder.append(" saved from shared ");
16499            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16500            memInfoBuilder.append("\n       ");
16501            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16502            memInfoBuilder.append(" unshared; ");
16503            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16504            memInfoBuilder.append(" volatile\n");
16505        }
16506        memInfoBuilder.append("  Free RAM: ");
16507        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16508                + memInfo.getFreeSizeKb()));
16509        memInfoBuilder.append("\n");
16510        memInfoBuilder.append("  Used RAM: ");
16511        memInfoBuilder.append(stringifyKBSize(
16512                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16513        memInfoBuilder.append("\n");
16514        memInfoBuilder.append("  Lost RAM: ");
16515        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16516                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16517                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16518        memInfoBuilder.append("\n");
16519        Slog.i(TAG, "Low on memory:");
16520        Slog.i(TAG, shortNativeBuilder.toString());
16521        Slog.i(TAG, fullJavaBuilder.toString());
16522        Slog.i(TAG, memInfoBuilder.toString());
16523
16524        StringBuilder dropBuilder = new StringBuilder(1024);
16525        /*
16526        StringWriter oomSw = new StringWriter();
16527        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16528        StringWriter catSw = new StringWriter();
16529        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16530        String[] emptyArgs = new String[] { };
16531        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16532        oomPw.flush();
16533        String oomString = oomSw.toString();
16534        */
16535        dropBuilder.append("Low on memory:");
16536        dropBuilder.append(stack);
16537        dropBuilder.append('\n');
16538        dropBuilder.append(fullNativeBuilder);
16539        dropBuilder.append(fullJavaBuilder);
16540        dropBuilder.append('\n');
16541        dropBuilder.append(memInfoBuilder);
16542        dropBuilder.append('\n');
16543        /*
16544        dropBuilder.append(oomString);
16545        dropBuilder.append('\n');
16546        */
16547        StringWriter catSw = new StringWriter();
16548        synchronized (ActivityManagerService.this) {
16549            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16550            String[] emptyArgs = new String[] { };
16551            catPw.println();
16552            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16553            catPw.println();
16554            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16555                    false, null).dumpLocked();
16556            catPw.println();
16557            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16558            catPw.flush();
16559        }
16560        dropBuilder.append(catSw.toString());
16561        addErrorToDropBox("lowmem", null, "system_server", null,
16562                null, tag.toString(), dropBuilder.toString(), null, null);
16563        //Slog.i(TAG, "Sent to dropbox:");
16564        //Slog.i(TAG, dropBuilder.toString());
16565        synchronized (ActivityManagerService.this) {
16566            long now = SystemClock.uptimeMillis();
16567            if (mLastMemUsageReportTime < now) {
16568                mLastMemUsageReportTime = now;
16569            }
16570        }
16571    }
16572
16573    /**
16574     * Searches array of arguments for the specified string
16575     * @param args array of argument strings
16576     * @param value value to search for
16577     * @return true if the value is contained in the array
16578     */
16579    private static boolean scanArgs(String[] args, String value) {
16580        if (args != null) {
16581            for (String arg : args) {
16582                if (value.equals(arg)) {
16583                    return true;
16584                }
16585            }
16586        }
16587        return false;
16588    }
16589
16590    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16591            ContentProviderRecord cpr, boolean always) {
16592        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16593
16594        if (!inLaunching || always) {
16595            synchronized (cpr) {
16596                cpr.launchingApp = null;
16597                cpr.notifyAll();
16598            }
16599            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16600            String names[] = cpr.info.authority.split(";");
16601            for (int j = 0; j < names.length; j++) {
16602                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16603            }
16604        }
16605
16606        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16607            ContentProviderConnection conn = cpr.connections.get(i);
16608            if (conn.waiting) {
16609                // If this connection is waiting for the provider, then we don't
16610                // need to mess with its process unless we are always removing
16611                // or for some reason the provider is not currently launching.
16612                if (inLaunching && !always) {
16613                    continue;
16614                }
16615            }
16616            ProcessRecord capp = conn.client;
16617            conn.dead = true;
16618            if (conn.stableCount > 0) {
16619                if (!capp.persistent && capp.thread != null
16620                        && capp.pid != 0
16621                        && capp.pid != MY_PID) {
16622                    capp.kill("depends on provider "
16623                            + cpr.name.flattenToShortString()
16624                            + " in dying proc " + (proc != null ? proc.processName : "??")
16625                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16626                }
16627            } else if (capp.thread != null && conn.provider.provider != null) {
16628                try {
16629                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16630                } catch (RemoteException e) {
16631                }
16632                // In the protocol here, we don't expect the client to correctly
16633                // clean up this connection, we'll just remove it.
16634                cpr.connections.remove(i);
16635                if (conn.client.conProviders.remove(conn)) {
16636                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16637                }
16638            }
16639        }
16640
16641        if (inLaunching && always) {
16642            mLaunchingProviders.remove(cpr);
16643        }
16644        return inLaunching;
16645    }
16646
16647    /**
16648     * Main code for cleaning up a process when it has gone away.  This is
16649     * called both as a result of the process dying, or directly when stopping
16650     * a process when running in single process mode.
16651     *
16652     * @return Returns true if the given process has been restarted, so the
16653     * app that was passed in must remain on the process lists.
16654     */
16655    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16656            boolean restarting, boolean allowRestart, int index) {
16657        if (index >= 0) {
16658            removeLruProcessLocked(app);
16659            ProcessList.remove(app.pid);
16660        }
16661
16662        mProcessesToGc.remove(app);
16663        mPendingPssProcesses.remove(app);
16664
16665        // Dismiss any open dialogs.
16666        if (app.crashDialog != null && !app.forceCrashReport) {
16667            app.crashDialog.dismiss();
16668            app.crashDialog = null;
16669        }
16670        if (app.anrDialog != null) {
16671            app.anrDialog.dismiss();
16672            app.anrDialog = null;
16673        }
16674        if (app.waitDialog != null) {
16675            app.waitDialog.dismiss();
16676            app.waitDialog = null;
16677        }
16678
16679        app.crashing = false;
16680        app.notResponding = false;
16681
16682        app.resetPackageList(mProcessStats);
16683        app.unlinkDeathRecipient();
16684        app.makeInactive(mProcessStats);
16685        app.waitingToKill = null;
16686        app.forcingToForeground = null;
16687        updateProcessForegroundLocked(app, false, false);
16688        app.foregroundActivities = false;
16689        app.hasShownUi = false;
16690        app.treatLikeActivity = false;
16691        app.hasAboveClient = false;
16692        app.hasClientActivities = false;
16693
16694        mServices.killServicesLocked(app, allowRestart);
16695
16696        boolean restart = false;
16697
16698        // Remove published content providers.
16699        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16700            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16701            final boolean always = app.bad || !allowRestart;
16702            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16703            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16704                // We left the provider in the launching list, need to
16705                // restart it.
16706                restart = true;
16707            }
16708
16709            cpr.provider = null;
16710            cpr.proc = null;
16711        }
16712        app.pubProviders.clear();
16713
16714        // Take care of any launching providers waiting for this process.
16715        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16716            restart = true;
16717        }
16718
16719        // Unregister from connected content providers.
16720        if (!app.conProviders.isEmpty()) {
16721            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16722                ContentProviderConnection conn = app.conProviders.get(i);
16723                conn.provider.connections.remove(conn);
16724                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16725                        conn.provider.name);
16726            }
16727            app.conProviders.clear();
16728        }
16729
16730        // At this point there may be remaining entries in mLaunchingProviders
16731        // where we were the only one waiting, so they are no longer of use.
16732        // Look for these and clean up if found.
16733        // XXX Commented out for now.  Trying to figure out a way to reproduce
16734        // the actual situation to identify what is actually going on.
16735        if (false) {
16736            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16737                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16738                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16739                    synchronized (cpr) {
16740                        cpr.launchingApp = null;
16741                        cpr.notifyAll();
16742                    }
16743                }
16744            }
16745        }
16746
16747        skipCurrentReceiverLocked(app);
16748
16749        // Unregister any receivers.
16750        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16751            removeReceiverLocked(app.receivers.valueAt(i));
16752        }
16753        app.receivers.clear();
16754
16755        // If the app is undergoing backup, tell the backup manager about it
16756        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16757            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16758                    + mBackupTarget.appInfo + " died during backup");
16759            try {
16760                IBackupManager bm = IBackupManager.Stub.asInterface(
16761                        ServiceManager.getService(Context.BACKUP_SERVICE));
16762                bm.agentDisconnected(app.info.packageName);
16763            } catch (RemoteException e) {
16764                // can't happen; backup manager is local
16765            }
16766        }
16767
16768        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16769            ProcessChangeItem item = mPendingProcessChanges.get(i);
16770            if (item.pid == app.pid) {
16771                mPendingProcessChanges.remove(i);
16772                mAvailProcessChanges.add(item);
16773            }
16774        }
16775        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16776                null).sendToTarget();
16777
16778        // If the caller is restarting this app, then leave it in its
16779        // current lists and let the caller take care of it.
16780        if (restarting) {
16781            return false;
16782        }
16783
16784        if (!app.persistent || app.isolated) {
16785            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16786                    "Removing non-persistent process during cleanup: " + app);
16787            removeProcessNameLocked(app.processName, app.uid);
16788            if (mHeavyWeightProcess == app) {
16789                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16790                        mHeavyWeightProcess.userId, 0));
16791                mHeavyWeightProcess = null;
16792            }
16793        } else if (!app.removed) {
16794            // This app is persistent, so we need to keep its record around.
16795            // If it is not already on the pending app list, add it there
16796            // and start a new process for it.
16797            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16798                mPersistentStartingProcesses.add(app);
16799                restart = true;
16800            }
16801        }
16802        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16803                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16804        mProcessesOnHold.remove(app);
16805
16806        if (app == mHomeProcess) {
16807            mHomeProcess = null;
16808        }
16809        if (app == mPreviousProcess) {
16810            mPreviousProcess = null;
16811        }
16812
16813        if (restart && !app.isolated) {
16814            // We have components that still need to be running in the
16815            // process, so re-launch it.
16816            if (index < 0) {
16817                ProcessList.remove(app.pid);
16818            }
16819            addProcessNameLocked(app);
16820            startProcessLocked(app, "restart", app.processName);
16821            return true;
16822        } else if (app.pid > 0 && app.pid != MY_PID) {
16823            // Goodbye!
16824            boolean removed;
16825            synchronized (mPidsSelfLocked) {
16826                mPidsSelfLocked.remove(app.pid);
16827                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16828            }
16829            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16830            if (app.isolated) {
16831                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16832            }
16833            app.setPid(0);
16834        }
16835        return false;
16836    }
16837
16838    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16839        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16840            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16841            if (cpr.launchingApp == app) {
16842                return true;
16843            }
16844        }
16845        return false;
16846    }
16847
16848    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16849        // Look through the content providers we are waiting to have launched,
16850        // and if any run in this process then either schedule a restart of
16851        // the process or kill the client waiting for it if this process has
16852        // gone bad.
16853        boolean restart = false;
16854        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16855            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16856            if (cpr.launchingApp == app) {
16857                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16858                    restart = true;
16859                } else {
16860                    removeDyingProviderLocked(app, cpr, true);
16861                }
16862            }
16863        }
16864        return restart;
16865    }
16866
16867    // =========================================================
16868    // SERVICES
16869    // =========================================================
16870
16871    @Override
16872    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16873            int flags) {
16874        enforceNotIsolatedCaller("getServices");
16875        synchronized (this) {
16876            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16877        }
16878    }
16879
16880    @Override
16881    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16882        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16883        synchronized (this) {
16884            return mServices.getRunningServiceControlPanelLocked(name);
16885        }
16886    }
16887
16888    @Override
16889    public ComponentName startService(IApplicationThread caller, Intent service,
16890            String resolvedType, String callingPackage, int userId)
16891            throws TransactionTooLargeException {
16892        enforceNotIsolatedCaller("startService");
16893        // Refuse possible leaked file descriptors
16894        if (service != null && service.hasFileDescriptors() == true) {
16895            throw new IllegalArgumentException("File descriptors passed in Intent");
16896        }
16897
16898        if (callingPackage == null) {
16899            throw new IllegalArgumentException("callingPackage cannot be null");
16900        }
16901
16902        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16903                "startService: " + service + " type=" + resolvedType);
16904        synchronized(this) {
16905            final int callingPid = Binder.getCallingPid();
16906            final int callingUid = Binder.getCallingUid();
16907            final long origId = Binder.clearCallingIdentity();
16908            ComponentName res = mServices.startServiceLocked(caller, service,
16909                    resolvedType, callingPid, callingUid, callingPackage, userId);
16910            Binder.restoreCallingIdentity(origId);
16911            return res;
16912        }
16913    }
16914
16915    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16916            String callingPackage, int userId)
16917            throws TransactionTooLargeException {
16918        synchronized(this) {
16919            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16920                    "startServiceInPackage: " + service + " type=" + resolvedType);
16921            final long origId = Binder.clearCallingIdentity();
16922            ComponentName res = mServices.startServiceLocked(null, service,
16923                    resolvedType, -1, uid, callingPackage, userId);
16924            Binder.restoreCallingIdentity(origId);
16925            return res;
16926        }
16927    }
16928
16929    @Override
16930    public int stopService(IApplicationThread caller, Intent service,
16931            String resolvedType, int userId) {
16932        enforceNotIsolatedCaller("stopService");
16933        // Refuse possible leaked file descriptors
16934        if (service != null && service.hasFileDescriptors() == true) {
16935            throw new IllegalArgumentException("File descriptors passed in Intent");
16936        }
16937
16938        synchronized(this) {
16939            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16940        }
16941    }
16942
16943    @Override
16944    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16945        enforceNotIsolatedCaller("peekService");
16946        // Refuse possible leaked file descriptors
16947        if (service != null && service.hasFileDescriptors() == true) {
16948            throw new IllegalArgumentException("File descriptors passed in Intent");
16949        }
16950
16951        if (callingPackage == null) {
16952            throw new IllegalArgumentException("callingPackage cannot be null");
16953        }
16954
16955        synchronized(this) {
16956            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16957        }
16958    }
16959
16960    @Override
16961    public boolean stopServiceToken(ComponentName className, IBinder token,
16962            int startId) {
16963        synchronized(this) {
16964            return mServices.stopServiceTokenLocked(className, token, startId);
16965        }
16966    }
16967
16968    @Override
16969    public void setServiceForeground(ComponentName className, IBinder token,
16970            int id, Notification notification, int flags) {
16971        synchronized(this) {
16972            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16973        }
16974    }
16975
16976    @Override
16977    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16978            boolean requireFull, String name, String callerPackage) {
16979        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16980                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16981    }
16982
16983    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16984            String className, int flags) {
16985        boolean result = false;
16986        // For apps that don't have pre-defined UIDs, check for permission
16987        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16988            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16989                if (ActivityManager.checkUidPermission(
16990                        INTERACT_ACROSS_USERS,
16991                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16992                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16993                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16994                            + " requests FLAG_SINGLE_USER, but app does not hold "
16995                            + INTERACT_ACROSS_USERS;
16996                    Slog.w(TAG, msg);
16997                    throw new SecurityException(msg);
16998                }
16999                // Permission passed
17000                result = true;
17001            }
17002        } else if ("system".equals(componentProcessName)) {
17003            result = true;
17004        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17005            // Phone app and persistent apps are allowed to export singleuser providers.
17006            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17007                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17008        }
17009        if (DEBUG_MU) Slog.v(TAG_MU,
17010                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17011                + Integer.toHexString(flags) + ") = " + result);
17012        return result;
17013    }
17014
17015    /**
17016     * Checks to see if the caller is in the same app as the singleton
17017     * component, or the component is in a special app. It allows special apps
17018     * to export singleton components but prevents exporting singleton
17019     * components for regular apps.
17020     */
17021    boolean isValidSingletonCall(int callingUid, int componentUid) {
17022        int componentAppId = UserHandle.getAppId(componentUid);
17023        return UserHandle.isSameApp(callingUid, componentUid)
17024                || componentAppId == Process.SYSTEM_UID
17025                || componentAppId == Process.PHONE_UID
17026                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17027                        == PackageManager.PERMISSION_GRANTED;
17028    }
17029
17030    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17031            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17032            int userId) throws TransactionTooLargeException {
17033        enforceNotIsolatedCaller("bindService");
17034
17035        // Refuse possible leaked file descriptors
17036        if (service != null && service.hasFileDescriptors() == true) {
17037            throw new IllegalArgumentException("File descriptors passed in Intent");
17038        }
17039
17040        if (callingPackage == null) {
17041            throw new IllegalArgumentException("callingPackage cannot be null");
17042        }
17043
17044        synchronized(this) {
17045            return mServices.bindServiceLocked(caller, token, service,
17046                    resolvedType, connection, flags, callingPackage, userId);
17047        }
17048    }
17049
17050    public boolean unbindService(IServiceConnection connection) {
17051        synchronized (this) {
17052            return mServices.unbindServiceLocked(connection);
17053        }
17054    }
17055
17056    public void publishService(IBinder token, Intent intent, IBinder service) {
17057        // Refuse possible leaked file descriptors
17058        if (intent != null && intent.hasFileDescriptors() == true) {
17059            throw new IllegalArgumentException("File descriptors passed in Intent");
17060        }
17061
17062        synchronized(this) {
17063            if (!(token instanceof ServiceRecord)) {
17064                throw new IllegalArgumentException("Invalid service token");
17065            }
17066            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17067        }
17068    }
17069
17070    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17071        // Refuse possible leaked file descriptors
17072        if (intent != null && intent.hasFileDescriptors() == true) {
17073            throw new IllegalArgumentException("File descriptors passed in Intent");
17074        }
17075
17076        synchronized(this) {
17077            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17078        }
17079    }
17080
17081    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17082        synchronized(this) {
17083            if (!(token instanceof ServiceRecord)) {
17084                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17085                throw new IllegalArgumentException("Invalid service token");
17086            }
17087            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17088        }
17089    }
17090
17091    // =========================================================
17092    // BACKUP AND RESTORE
17093    // =========================================================
17094
17095    // Cause the target app to be launched if necessary and its backup agent
17096    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17097    // activity manager to announce its creation.
17098    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17099        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17100        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17101
17102        IPackageManager pm = AppGlobals.getPackageManager();
17103        ApplicationInfo app = null;
17104        try {
17105            app = pm.getApplicationInfo(packageName, 0, userId);
17106        } catch (RemoteException e) {
17107            // can't happen; package manager is process-local
17108        }
17109        if (app == null) {
17110            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17111            return false;
17112        }
17113
17114        synchronized(this) {
17115            // !!! TODO: currently no check here that we're already bound
17116            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17117            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17118            synchronized (stats) {
17119                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17120            }
17121
17122            // Backup agent is now in use, its package can't be stopped.
17123            try {
17124                AppGlobals.getPackageManager().setPackageStoppedState(
17125                        app.packageName, false, UserHandle.getUserId(app.uid));
17126            } catch (RemoteException e) {
17127            } catch (IllegalArgumentException e) {
17128                Slog.w(TAG, "Failed trying to unstop package "
17129                        + app.packageName + ": " + e);
17130            }
17131
17132            BackupRecord r = new BackupRecord(ss, app, backupMode);
17133            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17134                    ? new ComponentName(app.packageName, app.backupAgentName)
17135                    : new ComponentName("android", "FullBackupAgent");
17136            // startProcessLocked() returns existing proc's record if it's already running
17137            ProcessRecord proc = startProcessLocked(app.processName, app,
17138                    false, 0, "backup", hostingName, false, false, false);
17139            if (proc == null) {
17140                Slog.e(TAG, "Unable to start backup agent process " + r);
17141                return false;
17142            }
17143
17144            // If the app is a regular app (uid >= 10000) and not the system server or phone
17145            // process, etc, then mark it as being in full backup so that certain calls to the
17146            // process can be blocked. This is not reset to false anywhere because we kill the
17147            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17148            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17149                proc.inFullBackup = true;
17150            }
17151            r.app = proc;
17152            mBackupTarget = r;
17153            mBackupAppName = app.packageName;
17154
17155            // Try not to kill the process during backup
17156            updateOomAdjLocked(proc);
17157
17158            // If the process is already attached, schedule the creation of the backup agent now.
17159            // If it is not yet live, this will be done when it attaches to the framework.
17160            if (proc.thread != null) {
17161                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17162                try {
17163                    proc.thread.scheduleCreateBackupAgent(app,
17164                            compatibilityInfoForPackageLocked(app), backupMode);
17165                } catch (RemoteException e) {
17166                    // Will time out on the backup manager side
17167                }
17168            } else {
17169                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17170            }
17171            // Invariants: at this point, the target app process exists and the application
17172            // is either already running or in the process of coming up.  mBackupTarget and
17173            // mBackupAppName describe the app, so that when it binds back to the AM we
17174            // know that it's scheduled for a backup-agent operation.
17175        }
17176
17177        return true;
17178    }
17179
17180    @Override
17181    public void clearPendingBackup() {
17182        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17183        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17184
17185        synchronized (this) {
17186            mBackupTarget = null;
17187            mBackupAppName = null;
17188        }
17189    }
17190
17191    // A backup agent has just come up
17192    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17193        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17194                + " = " + agent);
17195
17196        synchronized(this) {
17197            if (!agentPackageName.equals(mBackupAppName)) {
17198                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17199                return;
17200            }
17201        }
17202
17203        long oldIdent = Binder.clearCallingIdentity();
17204        try {
17205            IBackupManager bm = IBackupManager.Stub.asInterface(
17206                    ServiceManager.getService(Context.BACKUP_SERVICE));
17207            bm.agentConnected(agentPackageName, agent);
17208        } catch (RemoteException e) {
17209            // can't happen; the backup manager service is local
17210        } catch (Exception e) {
17211            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17212            e.printStackTrace();
17213        } finally {
17214            Binder.restoreCallingIdentity(oldIdent);
17215        }
17216    }
17217
17218    // done with this agent
17219    public void unbindBackupAgent(ApplicationInfo appInfo) {
17220        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17221        if (appInfo == null) {
17222            Slog.w(TAG, "unbind backup agent for null app");
17223            return;
17224        }
17225
17226        synchronized(this) {
17227            try {
17228                if (mBackupAppName == null) {
17229                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17230                    return;
17231                }
17232
17233                if (!mBackupAppName.equals(appInfo.packageName)) {
17234                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17235                    return;
17236                }
17237
17238                // Not backing this app up any more; reset its OOM adjustment
17239                final ProcessRecord proc = mBackupTarget.app;
17240                updateOomAdjLocked(proc);
17241
17242                // If the app crashed during backup, 'thread' will be null here
17243                if (proc.thread != null) {
17244                    try {
17245                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17246                                compatibilityInfoForPackageLocked(appInfo));
17247                    } catch (Exception e) {
17248                        Slog.e(TAG, "Exception when unbinding backup agent:");
17249                        e.printStackTrace();
17250                    }
17251                }
17252            } finally {
17253                mBackupTarget = null;
17254                mBackupAppName = null;
17255            }
17256        }
17257    }
17258    // =========================================================
17259    // BROADCASTS
17260    // =========================================================
17261
17262    boolean isPendingBroadcastProcessLocked(int pid) {
17263        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17264                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17265    }
17266
17267    void skipPendingBroadcastLocked(int pid) {
17268            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17269            for (BroadcastQueue queue : mBroadcastQueues) {
17270                queue.skipPendingBroadcastLocked(pid);
17271            }
17272    }
17273
17274    // The app just attached; send any pending broadcasts that it should receive
17275    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17276        boolean didSomething = false;
17277        for (BroadcastQueue queue : mBroadcastQueues) {
17278            didSomething |= queue.sendPendingBroadcastsLocked(app);
17279        }
17280        return didSomething;
17281    }
17282
17283    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17284            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17285        enforceNotIsolatedCaller("registerReceiver");
17286        ArrayList<Intent> stickyIntents = null;
17287        ProcessRecord callerApp = null;
17288        int callingUid;
17289        int callingPid;
17290        synchronized(this) {
17291            if (caller != null) {
17292                callerApp = getRecordForAppLocked(caller);
17293                if (callerApp == null) {
17294                    throw new SecurityException(
17295                            "Unable to find app for caller " + caller
17296                            + " (pid=" + Binder.getCallingPid()
17297                            + ") when registering receiver " + receiver);
17298                }
17299                if (callerApp.info.uid != Process.SYSTEM_UID &&
17300                        !callerApp.pkgList.containsKey(callerPackage) &&
17301                        !"android".equals(callerPackage)) {
17302                    throw new SecurityException("Given caller package " + callerPackage
17303                            + " is not running in process " + callerApp);
17304                }
17305                callingUid = callerApp.info.uid;
17306                callingPid = callerApp.pid;
17307            } else {
17308                callerPackage = null;
17309                callingUid = Binder.getCallingUid();
17310                callingPid = Binder.getCallingPid();
17311            }
17312
17313            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17314                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17315
17316            Iterator<String> actions = filter.actionsIterator();
17317            if (actions == null) {
17318                ArrayList<String> noAction = new ArrayList<String>(1);
17319                noAction.add(null);
17320                actions = noAction.iterator();
17321            }
17322
17323            // Collect stickies of users
17324            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17325            while (actions.hasNext()) {
17326                String action = actions.next();
17327                for (int id : userIds) {
17328                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17329                    if (stickies != null) {
17330                        ArrayList<Intent> intents = stickies.get(action);
17331                        if (intents != null) {
17332                            if (stickyIntents == null) {
17333                                stickyIntents = new ArrayList<Intent>();
17334                            }
17335                            stickyIntents.addAll(intents);
17336                        }
17337                    }
17338                }
17339            }
17340        }
17341
17342        ArrayList<Intent> allSticky = null;
17343        if (stickyIntents != null) {
17344            final ContentResolver resolver = mContext.getContentResolver();
17345            // Look for any matching sticky broadcasts...
17346            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17347                Intent intent = stickyIntents.get(i);
17348                // If intent has scheme "content", it will need to acccess
17349                // provider that needs to lock mProviderMap in ActivityThread
17350                // and also it may need to wait application response, so we
17351                // cannot lock ActivityManagerService here.
17352                if (filter.match(resolver, intent, true, TAG) >= 0) {
17353                    if (allSticky == null) {
17354                        allSticky = new ArrayList<Intent>();
17355                    }
17356                    allSticky.add(intent);
17357                }
17358            }
17359        }
17360
17361        // The first sticky in the list is returned directly back to the client.
17362        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17363        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17364        if (receiver == null) {
17365            return sticky;
17366        }
17367
17368        synchronized (this) {
17369            if (callerApp != null && (callerApp.thread == null
17370                    || callerApp.thread.asBinder() != caller.asBinder())) {
17371                // Original caller already died
17372                return null;
17373            }
17374            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17375            if (rl == null) {
17376                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17377                        userId, receiver);
17378                if (rl.app != null) {
17379                    rl.app.receivers.add(rl);
17380                } else {
17381                    try {
17382                        receiver.asBinder().linkToDeath(rl, 0);
17383                    } catch (RemoteException e) {
17384                        return sticky;
17385                    }
17386                    rl.linkedToDeath = true;
17387                }
17388                mRegisteredReceivers.put(receiver.asBinder(), rl);
17389            } else if (rl.uid != callingUid) {
17390                throw new IllegalArgumentException(
17391                        "Receiver requested to register for uid " + callingUid
17392                        + " was previously registered for uid " + rl.uid);
17393            } else if (rl.pid != callingPid) {
17394                throw new IllegalArgumentException(
17395                        "Receiver requested to register for pid " + callingPid
17396                        + " was previously registered for pid " + rl.pid);
17397            } else if (rl.userId != userId) {
17398                throw new IllegalArgumentException(
17399                        "Receiver requested to register for user " + userId
17400                        + " was previously registered for user " + rl.userId);
17401            }
17402            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17403                    permission, callingUid, userId);
17404            rl.add(bf);
17405            if (!bf.debugCheck()) {
17406                Slog.w(TAG, "==> For Dynamic broadcast");
17407            }
17408            mReceiverResolver.addFilter(bf);
17409
17410            // Enqueue broadcasts for all existing stickies that match
17411            // this filter.
17412            if (allSticky != null) {
17413                ArrayList receivers = new ArrayList();
17414                receivers.add(bf);
17415
17416                final int stickyCount = allSticky.size();
17417                for (int i = 0; i < stickyCount; i++) {
17418                    Intent intent = allSticky.get(i);
17419                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17420                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17421                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17422                            null, 0, null, null, false, true, true, -1);
17423                    queue.enqueueParallelBroadcastLocked(r);
17424                    queue.scheduleBroadcastsLocked();
17425                }
17426            }
17427
17428            return sticky;
17429        }
17430    }
17431
17432    public void unregisterReceiver(IIntentReceiver receiver) {
17433        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17434
17435        final long origId = Binder.clearCallingIdentity();
17436        try {
17437            boolean doTrim = false;
17438
17439            synchronized(this) {
17440                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17441                if (rl != null) {
17442                    final BroadcastRecord r = rl.curBroadcast;
17443                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17444                        final boolean doNext = r.queue.finishReceiverLocked(
17445                                r, r.resultCode, r.resultData, r.resultExtras,
17446                                r.resultAbort, false);
17447                        if (doNext) {
17448                            doTrim = true;
17449                            r.queue.processNextBroadcast(false);
17450                        }
17451                    }
17452
17453                    if (rl.app != null) {
17454                        rl.app.receivers.remove(rl);
17455                    }
17456                    removeReceiverLocked(rl);
17457                    if (rl.linkedToDeath) {
17458                        rl.linkedToDeath = false;
17459                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17460                    }
17461                }
17462            }
17463
17464            // If we actually concluded any broadcasts, we might now be able
17465            // to trim the recipients' apps from our working set
17466            if (doTrim) {
17467                trimApplications();
17468                return;
17469            }
17470
17471        } finally {
17472            Binder.restoreCallingIdentity(origId);
17473        }
17474    }
17475
17476    void removeReceiverLocked(ReceiverList rl) {
17477        mRegisteredReceivers.remove(rl.receiver.asBinder());
17478        for (int i = rl.size() - 1; i >= 0; i--) {
17479            mReceiverResolver.removeFilter(rl.get(i));
17480        }
17481    }
17482
17483    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17484        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17485            ProcessRecord r = mLruProcesses.get(i);
17486            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17487                try {
17488                    r.thread.dispatchPackageBroadcast(cmd, packages);
17489                } catch (RemoteException ex) {
17490                }
17491            }
17492        }
17493    }
17494
17495    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17496            int callingUid, int[] users) {
17497        // TODO: come back and remove this assumption to triage all broadcasts
17498        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17499
17500        List<ResolveInfo> receivers = null;
17501        try {
17502            HashSet<ComponentName> singleUserReceivers = null;
17503            boolean scannedFirstReceivers = false;
17504            for (int user : users) {
17505                // Skip users that have Shell restrictions, with exception of always permitted
17506                // Shell broadcasts
17507                if (callingUid == Process.SHELL_UID
17508                        && mUserController.hasUserRestriction(
17509                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17510                        && !isPermittedShellBroadcast(intent)) {
17511                    continue;
17512                }
17513                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17514                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17515                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17516                    // If this is not the system user, we need to check for
17517                    // any receivers that should be filtered out.
17518                    for (int i=0; i<newReceivers.size(); i++) {
17519                        ResolveInfo ri = newReceivers.get(i);
17520                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17521                            newReceivers.remove(i);
17522                            i--;
17523                        }
17524                    }
17525                }
17526                if (newReceivers != null && newReceivers.size() == 0) {
17527                    newReceivers = null;
17528                }
17529                if (receivers == null) {
17530                    receivers = newReceivers;
17531                } else if (newReceivers != null) {
17532                    // We need to concatenate the additional receivers
17533                    // found with what we have do far.  This would be easy,
17534                    // but we also need to de-dup any receivers that are
17535                    // singleUser.
17536                    if (!scannedFirstReceivers) {
17537                        // Collect any single user receivers we had already retrieved.
17538                        scannedFirstReceivers = true;
17539                        for (int i=0; i<receivers.size(); i++) {
17540                            ResolveInfo ri = receivers.get(i);
17541                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17542                                ComponentName cn = new ComponentName(
17543                                        ri.activityInfo.packageName, ri.activityInfo.name);
17544                                if (singleUserReceivers == null) {
17545                                    singleUserReceivers = new HashSet<ComponentName>();
17546                                }
17547                                singleUserReceivers.add(cn);
17548                            }
17549                        }
17550                    }
17551                    // Add the new results to the existing results, tracking
17552                    // and de-dupping single user receivers.
17553                    for (int i=0; i<newReceivers.size(); i++) {
17554                        ResolveInfo ri = newReceivers.get(i);
17555                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17556                            ComponentName cn = new ComponentName(
17557                                    ri.activityInfo.packageName, ri.activityInfo.name);
17558                            if (singleUserReceivers == null) {
17559                                singleUserReceivers = new HashSet<ComponentName>();
17560                            }
17561                            if (!singleUserReceivers.contains(cn)) {
17562                                singleUserReceivers.add(cn);
17563                                receivers.add(ri);
17564                            }
17565                        } else {
17566                            receivers.add(ri);
17567                        }
17568                    }
17569                }
17570            }
17571        } catch (RemoteException ex) {
17572            // pm is in same process, this will never happen.
17573        }
17574        return receivers;
17575    }
17576
17577    private boolean isPermittedShellBroadcast(Intent intent) {
17578        // remote bugreport should always be allowed to be taken
17579        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17580    }
17581
17582    final int broadcastIntentLocked(ProcessRecord callerApp,
17583            String callerPackage, Intent intent, String resolvedType,
17584            IIntentReceiver resultTo, int resultCode, String resultData,
17585            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17586            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17587        intent = new Intent(intent);
17588
17589        // By default broadcasts do not go to stopped apps.
17590        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17591
17592        // If we have not finished booting, don't allow this to launch new processes.
17593        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17594            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17595        }
17596
17597        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17598                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17599                + " ordered=" + ordered + " userid=" + userId);
17600        if ((resultTo != null) && !ordered) {
17601            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17602        }
17603
17604        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17605                ALLOW_NON_FULL, "broadcast", callerPackage);
17606
17607        // Make sure that the user who is receiving this broadcast is running.
17608        // If not, we will just skip it. Make an exception for shutdown broadcasts
17609        // and upgrade steps.
17610
17611        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17612            if ((callingUid != Process.SYSTEM_UID
17613                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17614                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17615                Slog.w(TAG, "Skipping broadcast of " + intent
17616                        + ": user " + userId + " is stopped");
17617                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17618            }
17619        }
17620
17621        BroadcastOptions brOptions = null;
17622        if (bOptions != null) {
17623            brOptions = new BroadcastOptions(bOptions);
17624            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17625                // See if the caller is allowed to do this.  Note we are checking against
17626                // the actual real caller (not whoever provided the operation as say a
17627                // PendingIntent), because that who is actually supplied the arguments.
17628                if (checkComponentPermission(
17629                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17630                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17631                        != PackageManager.PERMISSION_GRANTED) {
17632                    String msg = "Permission Denial: " + intent.getAction()
17633                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17634                            + ", uid=" + callingUid + ")"
17635                            + " requires "
17636                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17637                    Slog.w(TAG, msg);
17638                    throw new SecurityException(msg);
17639                }
17640            }
17641        }
17642
17643        // Verify that protected broadcasts are only being sent by system code,
17644        // and that system code is only sending protected broadcasts.
17645        final String action = intent.getAction();
17646        final boolean isProtectedBroadcast;
17647        try {
17648            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17649        } catch (RemoteException e) {
17650            Slog.w(TAG, "Remote exception", e);
17651            return ActivityManager.BROADCAST_SUCCESS;
17652        }
17653
17654        final boolean isCallerSystem;
17655        switch (UserHandle.getAppId(callingUid)) {
17656            case Process.ROOT_UID:
17657            case Process.SYSTEM_UID:
17658            case Process.PHONE_UID:
17659            case Process.BLUETOOTH_UID:
17660            case Process.NFC_UID:
17661                isCallerSystem = true;
17662                break;
17663            default:
17664                isCallerSystem = (callerApp != null) && callerApp.persistent;
17665                break;
17666        }
17667
17668        if (isCallerSystem) {
17669            if (isProtectedBroadcast
17670                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17671                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17672                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17673                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17674                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17675                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17676                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17677                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17678                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17679                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17680                // Broadcast is either protected, or it's a public action that
17681                // we've relaxed, so it's fine for system internals to send.
17682            } else {
17683                // The vast majority of broadcasts sent from system internals
17684                // should be protected to avoid security holes, so yell loudly
17685                // to ensure we examine these cases.
17686                if (callerApp != null) {
17687                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17688                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17689                            new Throwable());
17690                } else {
17691                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17692                            + " from system uid " + UserHandle.formatUid(callingUid)
17693                            + " pkg " + callerPackage,
17694                            new Throwable());
17695                }
17696            }
17697
17698        } else {
17699            if (isProtectedBroadcast) {
17700                String msg = "Permission Denial: not allowed to send broadcast "
17701                        + action + " from pid="
17702                        + callingPid + ", uid=" + callingUid;
17703                Slog.w(TAG, msg);
17704                throw new SecurityException(msg);
17705
17706            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17707                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17708                // Special case for compatibility: we don't want apps to send this,
17709                // but historically it has not been protected and apps may be using it
17710                // to poke their own app widget.  So, instead of making it protected,
17711                // just limit it to the caller.
17712                if (callerPackage == null) {
17713                    String msg = "Permission Denial: not allowed to send broadcast "
17714                            + action + " from unknown caller.";
17715                    Slog.w(TAG, msg);
17716                    throw new SecurityException(msg);
17717                } else if (intent.getComponent() != null) {
17718                    // They are good enough to send to an explicit component...  verify
17719                    // it is being sent to the calling app.
17720                    if (!intent.getComponent().getPackageName().equals(
17721                            callerPackage)) {
17722                        String msg = "Permission Denial: not allowed to send broadcast "
17723                                + action + " to "
17724                                + intent.getComponent().getPackageName() + " from "
17725                                + callerPackage;
17726                        Slog.w(TAG, msg);
17727                        throw new SecurityException(msg);
17728                    }
17729                } else {
17730                    // Limit broadcast to their own package.
17731                    intent.setPackage(callerPackage);
17732                }
17733            }
17734        }
17735
17736        if (action != null) {
17737            switch (action) {
17738                case Intent.ACTION_UID_REMOVED:
17739                case Intent.ACTION_PACKAGE_REMOVED:
17740                case Intent.ACTION_PACKAGE_CHANGED:
17741                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17742                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17743                case Intent.ACTION_PACKAGES_SUSPENDED:
17744                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17745                    // Handle special intents: if this broadcast is from the package
17746                    // manager about a package being removed, we need to remove all of
17747                    // its activities from the history stack.
17748                    if (checkComponentPermission(
17749                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17750                            callingPid, callingUid, -1, true)
17751                            != PackageManager.PERMISSION_GRANTED) {
17752                        String msg = "Permission Denial: " + intent.getAction()
17753                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17754                                + ", uid=" + callingUid + ")"
17755                                + " requires "
17756                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17757                        Slog.w(TAG, msg);
17758                        throw new SecurityException(msg);
17759                    }
17760                    switch (action) {
17761                        case Intent.ACTION_UID_REMOVED:
17762                            final Bundle intentExtras = intent.getExtras();
17763                            final int uid = intentExtras != null
17764                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17765                            if (uid >= 0) {
17766                                mBatteryStatsService.removeUid(uid);
17767                                mAppOpsService.uidRemoved(uid);
17768                            }
17769                            break;
17770                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17771                            // If resources are unavailable just force stop all those packages
17772                            // and flush the attribute cache as well.
17773                            String list[] =
17774                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17775                            if (list != null && list.length > 0) {
17776                                for (int i = 0; i < list.length; i++) {
17777                                    forceStopPackageLocked(list[i], -1, false, true, true,
17778                                            false, false, userId, "storage unmount");
17779                                }
17780                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17781                                sendPackageBroadcastLocked(
17782                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17783                                        userId);
17784                            }
17785                            break;
17786                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17787                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17788                            break;
17789                        case Intent.ACTION_PACKAGE_REMOVED:
17790                        case Intent.ACTION_PACKAGE_CHANGED:
17791                            Uri data = intent.getData();
17792                            String ssp;
17793                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17794                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17795                                final boolean replacing =
17796                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17797                                final boolean killProcess =
17798                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17799                                final boolean fullUninstall = removed && !replacing;
17800                                if (removed) {
17801                                    if (killProcess) {
17802                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17803                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17804                                                false, true, true, false, fullUninstall, userId,
17805                                                removed ? "pkg removed" : "pkg changed");
17806                                    }
17807                                    final int cmd = killProcess
17808                                            ? IApplicationThread.PACKAGE_REMOVED
17809                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17810                                    sendPackageBroadcastLocked(cmd,
17811                                            new String[] {ssp}, userId);
17812                                    if (fullUninstall) {
17813                                        mAppOpsService.packageRemoved(
17814                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17815
17816                                        // Remove all permissions granted from/to this package
17817                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17818
17819                                        removeTasksByPackageNameLocked(ssp, userId);
17820
17821                                        // Hide the "unsupported display" dialog if necessary.
17822                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17823                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17824                                            mUnsupportedDisplaySizeDialog.dismiss();
17825                                            mUnsupportedDisplaySizeDialog = null;
17826                                        }
17827                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17828                                        mBatteryStatsService.notePackageUninstalled(ssp);
17829                                    }
17830                                } else {
17831                                    if (killProcess) {
17832                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17833                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17834                                                userId, ProcessList.INVALID_ADJ,
17835                                                false, true, true, false, "change " + ssp);
17836                                    }
17837                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17838                                            intent.getStringArrayExtra(
17839                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17840                                }
17841                            }
17842                            break;
17843                        case Intent.ACTION_PACKAGES_SUSPENDED:
17844                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17845                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17846                                    intent.getAction());
17847                            final String[] packageNames = intent.getStringArrayExtra(
17848                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17849                            final int userHandle = intent.getIntExtra(
17850                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17851
17852                            synchronized(ActivityManagerService.this) {
17853                                mRecentTasks.onPackagesSuspendedChanged(
17854                                        packageNames, suspended, userHandle);
17855                            }
17856                            break;
17857                    }
17858                    break;
17859                case Intent.ACTION_PACKAGE_REPLACED:
17860                {
17861                    final Uri data = intent.getData();
17862                    final String ssp;
17863                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17864                        final ApplicationInfo aInfo =
17865                                getPackageManagerInternalLocked().getApplicationInfo(
17866                                        ssp,
17867                                        userId);
17868                        if (aInfo == null) {
17869                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17870                                    + " ssp=" + ssp + " data=" + data);
17871                            return ActivityManager.BROADCAST_SUCCESS;
17872                        }
17873                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17874                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17875                                new String[] {ssp}, userId);
17876                    }
17877                    break;
17878                }
17879                case Intent.ACTION_PACKAGE_ADDED:
17880                {
17881                    // Special case for adding a package: by default turn on compatibility mode.
17882                    Uri data = intent.getData();
17883                    String ssp;
17884                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17885                        final boolean replacing =
17886                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17887                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17888
17889                        try {
17890                            ApplicationInfo ai = AppGlobals.getPackageManager().
17891                                    getApplicationInfo(ssp, 0, 0);
17892                            mBatteryStatsService.notePackageInstalled(ssp,
17893                                    ai != null ? ai.versionCode : 0);
17894                        } catch (RemoteException e) {
17895                        }
17896                    }
17897                    break;
17898                }
17899                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17900                {
17901                    Uri data = intent.getData();
17902                    String ssp;
17903                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17904                        // Hide the "unsupported display" dialog if necessary.
17905                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17906                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17907                            mUnsupportedDisplaySizeDialog.dismiss();
17908                            mUnsupportedDisplaySizeDialog = null;
17909                        }
17910                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
17911                    }
17912                    break;
17913                }
17914                case Intent.ACTION_TIMEZONE_CHANGED:
17915                    // If this is the time zone changed action, queue up a message that will reset
17916                    // the timezone of all currently running processes. This message will get
17917                    // queued up before the broadcast happens.
17918                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17919                    break;
17920                case Intent.ACTION_TIME_CHANGED:
17921                    // If the user set the time, let all running processes know.
17922                    final int is24Hour =
17923                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17924                                    : 0;
17925                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17926                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17927                    synchronized (stats) {
17928                        stats.noteCurrentTimeChangedLocked();
17929                    }
17930                    break;
17931                case Intent.ACTION_CLEAR_DNS_CACHE:
17932                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17933                    break;
17934                case Proxy.PROXY_CHANGE_ACTION:
17935                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17936                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17937                    break;
17938                case android.hardware.Camera.ACTION_NEW_PICTURE:
17939                case android.hardware.Camera.ACTION_NEW_VIDEO:
17940                    // These broadcasts are no longer allowed by the system, since they can
17941                    // cause significant thrashing at a crictical point (using the camera).
17942                    // Apps should use JobScehduler to monitor for media provider changes.
17943                    Slog.w(TAG, action + " no longer allowed; dropping from "
17944                            + UserHandle.formatUid(callingUid));
17945                    if (resultTo != null) {
17946                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
17947                        try {
17948                            queue.performReceiveLocked(callerApp, resultTo, intent,
17949                                    Activity.RESULT_CANCELED, null, null,
17950                                    false, false, userId);
17951                        } catch (RemoteException e) {
17952                            Slog.w(TAG, "Failure ["
17953                                    + queue.mQueueName + "] sending broadcast result of "
17954                                    + intent, e);
17955
17956                        }
17957                    }
17958                    // Lie; we don't want to crash the app.
17959                    return ActivityManager.BROADCAST_SUCCESS;
17960            }
17961        }
17962
17963        // Add to the sticky list if requested.
17964        if (sticky) {
17965            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17966                    callingPid, callingUid)
17967                    != PackageManager.PERMISSION_GRANTED) {
17968                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17969                        + callingPid + ", uid=" + callingUid
17970                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17971                Slog.w(TAG, msg);
17972                throw new SecurityException(msg);
17973            }
17974            if (requiredPermissions != null && requiredPermissions.length > 0) {
17975                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17976                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17977                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17978            }
17979            if (intent.getComponent() != null) {
17980                throw new SecurityException(
17981                        "Sticky broadcasts can't target a specific component");
17982            }
17983            // We use userId directly here, since the "all" target is maintained
17984            // as a separate set of sticky broadcasts.
17985            if (userId != UserHandle.USER_ALL) {
17986                // But first, if this is not a broadcast to all users, then
17987                // make sure it doesn't conflict with an existing broadcast to
17988                // all users.
17989                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17990                        UserHandle.USER_ALL);
17991                if (stickies != null) {
17992                    ArrayList<Intent> list = stickies.get(intent.getAction());
17993                    if (list != null) {
17994                        int N = list.size();
17995                        int i;
17996                        for (i=0; i<N; i++) {
17997                            if (intent.filterEquals(list.get(i))) {
17998                                throw new IllegalArgumentException(
17999                                        "Sticky broadcast " + intent + " for user "
18000                                        + userId + " conflicts with existing global broadcast");
18001                            }
18002                        }
18003                    }
18004                }
18005            }
18006            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18007            if (stickies == null) {
18008                stickies = new ArrayMap<>();
18009                mStickyBroadcasts.put(userId, stickies);
18010            }
18011            ArrayList<Intent> list = stickies.get(intent.getAction());
18012            if (list == null) {
18013                list = new ArrayList<>();
18014                stickies.put(intent.getAction(), list);
18015            }
18016            final int stickiesCount = list.size();
18017            int i;
18018            for (i = 0; i < stickiesCount; i++) {
18019                if (intent.filterEquals(list.get(i))) {
18020                    // This sticky already exists, replace it.
18021                    list.set(i, new Intent(intent));
18022                    break;
18023                }
18024            }
18025            if (i >= stickiesCount) {
18026                list.add(new Intent(intent));
18027            }
18028        }
18029
18030        int[] users;
18031        if (userId == UserHandle.USER_ALL) {
18032            // Caller wants broadcast to go to all started users.
18033            users = mUserController.getStartedUserArrayLocked();
18034        } else {
18035            // Caller wants broadcast to go to one specific user.
18036            users = new int[] {userId};
18037        }
18038
18039        // Figure out who all will receive this broadcast.
18040        List receivers = null;
18041        List<BroadcastFilter> registeredReceivers = null;
18042        // Need to resolve the intent to interested receivers...
18043        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18044                 == 0) {
18045            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18046        }
18047        if (intent.getComponent() == null) {
18048            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18049                // Query one target user at a time, excluding shell-restricted users
18050                for (int i = 0; i < users.length; i++) {
18051                    if (mUserController.hasUserRestriction(
18052                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18053                        continue;
18054                    }
18055                    List<BroadcastFilter> registeredReceiversForUser =
18056                            mReceiverResolver.queryIntent(intent,
18057                                    resolvedType, false, users[i]);
18058                    if (registeredReceivers == null) {
18059                        registeredReceivers = registeredReceiversForUser;
18060                    } else if (registeredReceiversForUser != null) {
18061                        registeredReceivers.addAll(registeredReceiversForUser);
18062                    }
18063                }
18064            } else {
18065                registeredReceivers = mReceiverResolver.queryIntent(intent,
18066                        resolvedType, false, userId);
18067            }
18068        }
18069
18070        final boolean replacePending =
18071                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18072
18073        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18074                + " replacePending=" + replacePending);
18075
18076        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18077        if (!ordered && NR > 0) {
18078            // If we are not serializing this broadcast, then send the
18079            // registered receivers separately so they don't wait for the
18080            // components to be launched.
18081            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18082            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18083                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18084                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18085                    resultExtras, ordered, sticky, false, userId);
18086            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18087            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18088            if (!replaced) {
18089                queue.enqueueParallelBroadcastLocked(r);
18090                queue.scheduleBroadcastsLocked();
18091            }
18092            registeredReceivers = null;
18093            NR = 0;
18094        }
18095
18096        // Merge into one list.
18097        int ir = 0;
18098        if (receivers != null) {
18099            // A special case for PACKAGE_ADDED: do not allow the package
18100            // being added to see this broadcast.  This prevents them from
18101            // using this as a back door to get run as soon as they are
18102            // installed.  Maybe in the future we want to have a special install
18103            // broadcast or such for apps, but we'd like to deliberately make
18104            // this decision.
18105            String skipPackages[] = null;
18106            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18107                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18108                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18109                Uri data = intent.getData();
18110                if (data != null) {
18111                    String pkgName = data.getSchemeSpecificPart();
18112                    if (pkgName != null) {
18113                        skipPackages = new String[] { pkgName };
18114                    }
18115                }
18116            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18117                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18118            }
18119            if (skipPackages != null && (skipPackages.length > 0)) {
18120                for (String skipPackage : skipPackages) {
18121                    if (skipPackage != null) {
18122                        int NT = receivers.size();
18123                        for (int it=0; it<NT; it++) {
18124                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18125                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18126                                receivers.remove(it);
18127                                it--;
18128                                NT--;
18129                            }
18130                        }
18131                    }
18132                }
18133            }
18134
18135            int NT = receivers != null ? receivers.size() : 0;
18136            int it = 0;
18137            ResolveInfo curt = null;
18138            BroadcastFilter curr = null;
18139            while (it < NT && ir < NR) {
18140                if (curt == null) {
18141                    curt = (ResolveInfo)receivers.get(it);
18142                }
18143                if (curr == null) {
18144                    curr = registeredReceivers.get(ir);
18145                }
18146                if (curr.getPriority() >= curt.priority) {
18147                    // Insert this broadcast record into the final list.
18148                    receivers.add(it, curr);
18149                    ir++;
18150                    curr = null;
18151                    it++;
18152                    NT++;
18153                } else {
18154                    // Skip to the next ResolveInfo in the final list.
18155                    it++;
18156                    curt = null;
18157                }
18158            }
18159        }
18160        while (ir < NR) {
18161            if (receivers == null) {
18162                receivers = new ArrayList();
18163            }
18164            receivers.add(registeredReceivers.get(ir));
18165            ir++;
18166        }
18167
18168        if ((receivers != null && receivers.size() > 0)
18169                || resultTo != null) {
18170            BroadcastQueue queue = broadcastQueueForIntent(intent);
18171            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18172                    callerPackage, callingPid, callingUid, resolvedType,
18173                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18174                    resultData, resultExtras, ordered, sticky, false, userId);
18175
18176            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18177                    + ": prev had " + queue.mOrderedBroadcasts.size());
18178            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18179                    "Enqueueing broadcast " + r.intent.getAction());
18180
18181            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18182            if (!replaced) {
18183                queue.enqueueOrderedBroadcastLocked(r);
18184                queue.scheduleBroadcastsLocked();
18185            }
18186        } else {
18187            // There was nobody interested in the broadcast, but we still want to record
18188            // that it happened.
18189            if (intent.getComponent() == null && intent.getPackage() == null
18190                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18191                // This was an implicit broadcast... let's record it for posterity.
18192                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18193            }
18194        }
18195
18196        return ActivityManager.BROADCAST_SUCCESS;
18197    }
18198
18199    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18200            int skipCount, long dispatchTime) {
18201        final long now = SystemClock.elapsedRealtime();
18202        if (mCurBroadcastStats == null ||
18203                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18204            mLastBroadcastStats = mCurBroadcastStats;
18205            if (mLastBroadcastStats != null) {
18206                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18207                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18208            }
18209            mCurBroadcastStats = new BroadcastStats();
18210        }
18211        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18212    }
18213
18214    final Intent verifyBroadcastLocked(Intent intent) {
18215        // Refuse possible leaked file descriptors
18216        if (intent != null && intent.hasFileDescriptors() == true) {
18217            throw new IllegalArgumentException("File descriptors passed in Intent");
18218        }
18219
18220        int flags = intent.getFlags();
18221
18222        if (!mProcessesReady) {
18223            // if the caller really truly claims to know what they're doing, go
18224            // ahead and allow the broadcast without launching any receivers
18225            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18226                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18227            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18228                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18229                        + " before boot completion");
18230                throw new IllegalStateException("Cannot broadcast before boot completed");
18231            }
18232        }
18233
18234        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18235            throw new IllegalArgumentException(
18236                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18237        }
18238
18239        return intent;
18240    }
18241
18242    public final int broadcastIntent(IApplicationThread caller,
18243            Intent intent, String resolvedType, IIntentReceiver resultTo,
18244            int resultCode, String resultData, Bundle resultExtras,
18245            String[] requiredPermissions, int appOp, Bundle bOptions,
18246            boolean serialized, boolean sticky, int userId) {
18247        enforceNotIsolatedCaller("broadcastIntent");
18248        synchronized(this) {
18249            intent = verifyBroadcastLocked(intent);
18250
18251            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18252            final int callingPid = Binder.getCallingPid();
18253            final int callingUid = Binder.getCallingUid();
18254            final long origId = Binder.clearCallingIdentity();
18255            int res = broadcastIntentLocked(callerApp,
18256                    callerApp != null ? callerApp.info.packageName : null,
18257                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18258                    requiredPermissions, appOp, bOptions, serialized, sticky,
18259                    callingPid, callingUid, userId);
18260            Binder.restoreCallingIdentity(origId);
18261            return res;
18262        }
18263    }
18264
18265
18266    int broadcastIntentInPackage(String packageName, int uid,
18267            Intent intent, String resolvedType, IIntentReceiver resultTo,
18268            int resultCode, String resultData, Bundle resultExtras,
18269            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18270            int userId) {
18271        synchronized(this) {
18272            intent = verifyBroadcastLocked(intent);
18273
18274            final long origId = Binder.clearCallingIdentity();
18275            String[] requiredPermissions = requiredPermission == null ? null
18276                    : new String[] {requiredPermission};
18277            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18278                    resultTo, resultCode, resultData, resultExtras,
18279                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18280                    sticky, -1, uid, userId);
18281            Binder.restoreCallingIdentity(origId);
18282            return res;
18283        }
18284    }
18285
18286    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18287        // Refuse possible leaked file descriptors
18288        if (intent != null && intent.hasFileDescriptors() == true) {
18289            throw new IllegalArgumentException("File descriptors passed in Intent");
18290        }
18291
18292        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18293                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18294
18295        synchronized(this) {
18296            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18297                    != PackageManager.PERMISSION_GRANTED) {
18298                String msg = "Permission Denial: unbroadcastIntent() from pid="
18299                        + Binder.getCallingPid()
18300                        + ", uid=" + Binder.getCallingUid()
18301                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18302                Slog.w(TAG, msg);
18303                throw new SecurityException(msg);
18304            }
18305            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18306            if (stickies != null) {
18307                ArrayList<Intent> list = stickies.get(intent.getAction());
18308                if (list != null) {
18309                    int N = list.size();
18310                    int i;
18311                    for (i=0; i<N; i++) {
18312                        if (intent.filterEquals(list.get(i))) {
18313                            list.remove(i);
18314                            break;
18315                        }
18316                    }
18317                    if (list.size() <= 0) {
18318                        stickies.remove(intent.getAction());
18319                    }
18320                }
18321                if (stickies.size() <= 0) {
18322                    mStickyBroadcasts.remove(userId);
18323                }
18324            }
18325        }
18326    }
18327
18328    void backgroundServicesFinishedLocked(int userId) {
18329        for (BroadcastQueue queue : mBroadcastQueues) {
18330            queue.backgroundServicesFinishedLocked(userId);
18331        }
18332    }
18333
18334    public void finishReceiver(IBinder who, int resultCode, String resultData,
18335            Bundle resultExtras, boolean resultAbort, int flags) {
18336        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18337
18338        // Refuse possible leaked file descriptors
18339        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18340            throw new IllegalArgumentException("File descriptors passed in Bundle");
18341        }
18342
18343        final long origId = Binder.clearCallingIdentity();
18344        try {
18345            boolean doNext = false;
18346            BroadcastRecord r;
18347
18348            synchronized(this) {
18349                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18350                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18351                r = queue.getMatchingOrderedReceiver(who);
18352                if (r != null) {
18353                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18354                        resultData, resultExtras, resultAbort, true);
18355                }
18356            }
18357
18358            if (doNext) {
18359                r.queue.processNextBroadcast(false);
18360            }
18361            trimApplications();
18362        } finally {
18363            Binder.restoreCallingIdentity(origId);
18364        }
18365    }
18366
18367    // =========================================================
18368    // INSTRUMENTATION
18369    // =========================================================
18370
18371    public boolean startInstrumentation(ComponentName className,
18372            String profileFile, int flags, Bundle arguments,
18373            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18374            int userId, String abiOverride) {
18375        enforceNotIsolatedCaller("startInstrumentation");
18376        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18377                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18378        // Refuse possible leaked file descriptors
18379        if (arguments != null && arguments.hasFileDescriptors()) {
18380            throw new IllegalArgumentException("File descriptors passed in Bundle");
18381        }
18382
18383        synchronized(this) {
18384            InstrumentationInfo ii = null;
18385            ApplicationInfo ai = null;
18386            try {
18387                ii = mContext.getPackageManager().getInstrumentationInfo(
18388                    className, STOCK_PM_FLAGS);
18389                ai = AppGlobals.getPackageManager().getApplicationInfo(
18390                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18391            } catch (PackageManager.NameNotFoundException e) {
18392            } catch (RemoteException e) {
18393            }
18394            if (ii == null) {
18395                reportStartInstrumentationFailureLocked(watcher, className,
18396                        "Unable to find instrumentation info for: " + className);
18397                return false;
18398            }
18399            if (ai == null) {
18400                reportStartInstrumentationFailureLocked(watcher, className,
18401                        "Unable to find instrumentation target package: " + ii.targetPackage);
18402                return false;
18403            }
18404            if (!ai.hasCode()) {
18405                reportStartInstrumentationFailureLocked(watcher, className,
18406                        "Instrumentation target has no code: " + ii.targetPackage);
18407                return false;
18408            }
18409
18410            int match = mContext.getPackageManager().checkSignatures(
18411                    ii.targetPackage, ii.packageName);
18412            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18413                String msg = "Permission Denial: starting instrumentation "
18414                        + className + " from pid="
18415                        + Binder.getCallingPid()
18416                        + ", uid=" + Binder.getCallingPid()
18417                        + " not allowed because package " + ii.packageName
18418                        + " does not have a signature matching the target "
18419                        + ii.targetPackage;
18420                reportStartInstrumentationFailureLocked(watcher, className, msg);
18421                throw new SecurityException(msg);
18422            }
18423
18424            final long origId = Binder.clearCallingIdentity();
18425            // Instrumentation can kill and relaunch even persistent processes
18426            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18427                    "start instr");
18428            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18429            app.instrumentationClass = className;
18430            app.instrumentationInfo = ai;
18431            app.instrumentationProfileFile = profileFile;
18432            app.instrumentationArguments = arguments;
18433            app.instrumentationWatcher = watcher;
18434            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18435            app.instrumentationResultClass = className;
18436            Binder.restoreCallingIdentity(origId);
18437        }
18438
18439        return true;
18440    }
18441
18442    /**
18443     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18444     * error to the logs, but if somebody is watching, send the report there too.  This enables
18445     * the "am" command to report errors with more information.
18446     *
18447     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18448     * @param cn The component name of the instrumentation.
18449     * @param report The error report.
18450     */
18451    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18452            ComponentName cn, String report) {
18453        Slog.w(TAG, report);
18454        if (watcher != null) {
18455            Bundle results = new Bundle();
18456            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18457            results.putString("Error", report);
18458            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18459        }
18460    }
18461
18462    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18463        if (app.instrumentationWatcher != null) {
18464            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18465                    app.instrumentationClass, resultCode, results);
18466        }
18467
18468        // Can't call out of the system process with a lock held, so post a message.
18469        if (app.instrumentationUiAutomationConnection != null) {
18470            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18471                    app.instrumentationUiAutomationConnection).sendToTarget();
18472        }
18473
18474        app.instrumentationWatcher = null;
18475        app.instrumentationUiAutomationConnection = null;
18476        app.instrumentationClass = null;
18477        app.instrumentationInfo = null;
18478        app.instrumentationProfileFile = null;
18479        app.instrumentationArguments = null;
18480
18481        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18482                "finished inst");
18483    }
18484
18485    public void finishInstrumentation(IApplicationThread target,
18486            int resultCode, Bundle results) {
18487        int userId = UserHandle.getCallingUserId();
18488        // Refuse possible leaked file descriptors
18489        if (results != null && results.hasFileDescriptors()) {
18490            throw new IllegalArgumentException("File descriptors passed in Intent");
18491        }
18492
18493        synchronized(this) {
18494            ProcessRecord app = getRecordForAppLocked(target);
18495            if (app == null) {
18496                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18497                return;
18498            }
18499            final long origId = Binder.clearCallingIdentity();
18500            finishInstrumentationLocked(app, resultCode, results);
18501            Binder.restoreCallingIdentity(origId);
18502        }
18503    }
18504
18505    // =========================================================
18506    // CONFIGURATION
18507    // =========================================================
18508
18509    public ConfigurationInfo getDeviceConfigurationInfo() {
18510        ConfigurationInfo config = new ConfigurationInfo();
18511        synchronized (this) {
18512            config.reqTouchScreen = mConfiguration.touchscreen;
18513            config.reqKeyboardType = mConfiguration.keyboard;
18514            config.reqNavigation = mConfiguration.navigation;
18515            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18516                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18517                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18518            }
18519            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18520                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18521                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18522            }
18523            config.reqGlEsVersion = GL_ES_VERSION;
18524        }
18525        return config;
18526    }
18527
18528    ActivityStack getFocusedStack() {
18529        return mStackSupervisor.getFocusedStack();
18530    }
18531
18532    @Override
18533    public int getFocusedStackId() throws RemoteException {
18534        ActivityStack focusedStack = getFocusedStack();
18535        if (focusedStack != null) {
18536            return focusedStack.getStackId();
18537        }
18538        return -1;
18539    }
18540
18541    public Configuration getConfiguration() {
18542        Configuration ci;
18543        synchronized(this) {
18544            ci = new Configuration(mConfiguration);
18545            ci.userSetLocale = false;
18546        }
18547        return ci;
18548    }
18549
18550    @Override
18551    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18552        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18553        synchronized (this) {
18554            mSuppressResizeConfigChanges = suppress;
18555        }
18556    }
18557
18558    @Override
18559    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18560        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18561        if (fromStackId == HOME_STACK_ID) {
18562            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18563        }
18564        synchronized (this) {
18565            final long origId = Binder.clearCallingIdentity();
18566            try {
18567                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18568            } finally {
18569                Binder.restoreCallingIdentity(origId);
18570            }
18571        }
18572    }
18573
18574    @Override
18575    public void updatePersistentConfiguration(Configuration values) {
18576        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18577                "updateConfiguration()");
18578        enforceWriteSettingsPermission("updateConfiguration()");
18579        if (values == null) {
18580            throw new NullPointerException("Configuration must not be null");
18581        }
18582
18583        int userId = UserHandle.getCallingUserId();
18584
18585        synchronized(this) {
18586            final long origId = Binder.clearCallingIdentity();
18587            updateConfigurationLocked(values, null, false, true, userId);
18588            Binder.restoreCallingIdentity(origId);
18589        }
18590    }
18591
18592    private void updateFontScaleIfNeeded() {
18593        final int currentUserId;
18594        synchronized(this) {
18595            currentUserId = mUserController.getCurrentUserIdLocked();
18596        }
18597        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18598                FONT_SCALE, 1.0f, currentUserId);
18599        if (mConfiguration.fontScale != scaleFactor) {
18600            final Configuration configuration = mWindowManager.computeNewConfiguration();
18601            configuration.fontScale = scaleFactor;
18602            updatePersistentConfiguration(configuration);
18603        }
18604    }
18605
18606    private void enforceWriteSettingsPermission(String func) {
18607        int uid = Binder.getCallingUid();
18608        if (uid == Process.ROOT_UID) {
18609            return;
18610        }
18611
18612        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18613                Settings.getPackageNameForUid(mContext, uid), false)) {
18614            return;
18615        }
18616
18617        String msg = "Permission Denial: " + func + " from pid="
18618                + Binder.getCallingPid()
18619                + ", uid=" + uid
18620                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18621        Slog.w(TAG, msg);
18622        throw new SecurityException(msg);
18623    }
18624
18625    public void updateConfiguration(Configuration values) {
18626        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18627                "updateConfiguration()");
18628
18629        synchronized(this) {
18630            if (values == null && mWindowManager != null) {
18631                // sentinel: fetch the current configuration from the window manager
18632                values = mWindowManager.computeNewConfiguration();
18633            }
18634
18635            if (mWindowManager != null) {
18636                mProcessList.applyDisplaySize(mWindowManager);
18637            }
18638
18639            final long origId = Binder.clearCallingIdentity();
18640            if (values != null) {
18641                Settings.System.clearConfiguration(values);
18642            }
18643            updateConfigurationLocked(values, null, false);
18644            Binder.restoreCallingIdentity(origId);
18645        }
18646    }
18647
18648    void updateUserConfigurationLocked() {
18649        Configuration configuration = new Configuration(mConfiguration);
18650        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18651                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18652        updateConfigurationLocked(configuration, null, false);
18653    }
18654
18655    boolean updateConfigurationLocked(Configuration values,
18656            ActivityRecord starting, boolean initLocale) {
18657        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18658        return updateConfigurationLocked(values, starting, initLocale, false,
18659                UserHandle.USER_NULL);
18660    }
18661
18662    // To cache the list of supported system locales
18663    private String[] mSupportedSystemLocales = null;
18664
18665    /**
18666     * Do either or both things: (1) change the current configuration, and (2)
18667     * make sure the given activity is running with the (now) current
18668     * configuration.  Returns true if the activity has been left running, or
18669     * false if <var>starting</var> is being destroyed to match the new
18670     * configuration.
18671     *
18672     * @param userId is only used when persistent parameter is set to true to persist configuration
18673     *               for that particular user
18674     */
18675    private boolean updateConfigurationLocked(Configuration values,
18676            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18677        int changes = 0;
18678
18679        if (mWindowManager != null) {
18680            mWindowManager.deferSurfaceLayout();
18681        }
18682        if (values != null) {
18683            Configuration newConfig = new Configuration(mConfiguration);
18684            changes = newConfig.updateFrom(values);
18685            if (changes != 0) {
18686                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18687                        "Updating configuration to: " + values);
18688
18689                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18690
18691                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18692                    final LocaleList locales = values.getLocales();
18693                    int bestLocaleIndex = 0;
18694                    if (locales.size() > 1) {
18695                        if (mSupportedSystemLocales == null) {
18696                            mSupportedSystemLocales =
18697                                    Resources.getSystem().getAssets().getLocales();
18698                        }
18699                        bestLocaleIndex = Math.max(0,
18700                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18701                    }
18702                    SystemProperties.set("persist.sys.locale",
18703                            locales.get(bestLocaleIndex).toLanguageTag());
18704                    LocaleList.setDefault(locales, bestLocaleIndex);
18705                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18706                            locales.get(bestLocaleIndex)));
18707                }
18708
18709                mConfigurationSeq++;
18710                if (mConfigurationSeq <= 0) {
18711                    mConfigurationSeq = 1;
18712                }
18713                newConfig.seq = mConfigurationSeq;
18714                mConfiguration = newConfig;
18715                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18716                mUsageStatsService.reportConfigurationChange(newConfig,
18717                        mUserController.getCurrentUserIdLocked());
18718                //mUsageStatsService.noteStartConfig(newConfig);
18719
18720                final Configuration configCopy = new Configuration(mConfiguration);
18721
18722                // TODO: If our config changes, should we auto dismiss any currently
18723                // showing dialogs?
18724                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18725
18726                AttributeCache ac = AttributeCache.instance();
18727                if (ac != null) {
18728                    ac.updateConfiguration(configCopy);
18729                }
18730
18731                // Make sure all resources in our process are updated
18732                // right now, so that anyone who is going to retrieve
18733                // resource values after we return will be sure to get
18734                // the new ones.  This is especially important during
18735                // boot, where the first config change needs to guarantee
18736                // all resources have that config before following boot
18737                // code is executed.
18738                mSystemThread.applyConfigurationToResources(configCopy);
18739
18740                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18741                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18742                    msg.obj = new Configuration(configCopy);
18743                    msg.arg1 = userId;
18744                    mHandler.sendMessage(msg);
18745                }
18746
18747                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18748                if (isDensityChange) {
18749                    // Reset the unsupported display size dialog.
18750                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18751
18752                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18753                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18754                }
18755
18756                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18757                    ProcessRecord app = mLruProcesses.get(i);
18758                    try {
18759                        if (app.thread != null) {
18760                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18761                                    + app.processName + " new config " + mConfiguration);
18762                            app.thread.scheduleConfigurationChanged(configCopy);
18763                        }
18764                    } catch (Exception e) {
18765                    }
18766                }
18767                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18768                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18769                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18770                        | Intent.FLAG_RECEIVER_FOREGROUND);
18771                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18772                        null, AppOpsManager.OP_NONE, null, false, false,
18773                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18774                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18775                    // Tell the shortcut manager that the system locale changed.  It needs to know
18776                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18777                    // we "push" from here, rather than having the service listen to the broadcast.
18778                    final ShortcutServiceInternal shortcutService =
18779                            LocalServices.getService(ShortcutServiceInternal.class);
18780                    if (shortcutService != null) {
18781                        shortcutService.onSystemLocaleChangedNoLock();
18782                    }
18783
18784                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18785                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18786                    if (!mProcessesReady) {
18787                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18788                    }
18789                    broadcastIntentLocked(null, null, intent,
18790                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18791                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18792                }
18793            }
18794            // Update the configuration with WM first and check if any of the stacks need to be
18795            // resized due to the configuration change. If so, resize the stacks now and do any
18796            // relaunches if necessary. This way we don't need to relaunch again below in
18797            // ensureActivityConfigurationLocked().
18798            if (mWindowManager != null) {
18799                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18800                if (resizedStacks != null) {
18801                    for (int stackId : resizedStacks) {
18802                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18803                        mStackSupervisor.resizeStackLocked(
18804                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18805                    }
18806                }
18807            }
18808        }
18809
18810        boolean kept = true;
18811        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18812        // mainStack is null during startup.
18813        if (mainStack != null) {
18814            if (changes != 0 && starting == null) {
18815                // If the configuration changed, and the caller is not already
18816                // in the process of starting an activity, then find the top
18817                // activity to check if its configuration needs to change.
18818                starting = mainStack.topRunningActivityLocked();
18819            }
18820
18821            if (starting != null) {
18822                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18823                // And we need to make sure at this point that all other activities
18824                // are made visible with the correct configuration.
18825                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18826                        !PRESERVE_WINDOWS);
18827            }
18828        }
18829        if (mWindowManager != null) {
18830            mWindowManager.continueSurfaceLayout();
18831        }
18832        return kept;
18833    }
18834
18835    /**
18836     * Decide based on the configuration whether we should shouw the ANR,
18837     * crash, etc dialogs.  The idea is that if there is no affordnace to
18838     * press the on-screen buttons, we shouldn't show the dialog.
18839     *
18840     * A thought: SystemUI might also want to get told about this, the Power
18841     * dialog / global actions also might want different behaviors.
18842     */
18843    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18844        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18845                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18846                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18847        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18848                                    == Configuration.UI_MODE_TYPE_CAR);
18849        return inputMethodExists && uiIsNotCarType && !inVrMode;
18850    }
18851
18852    @Override
18853    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18854        synchronized (this) {
18855            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18856            if (srec != null) {
18857                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18858            }
18859        }
18860        return false;
18861    }
18862
18863    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18864            Intent resultData) {
18865
18866        synchronized (this) {
18867            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18868            if (r != null) {
18869                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18870            }
18871            return false;
18872        }
18873    }
18874
18875    public int getLaunchedFromUid(IBinder activityToken) {
18876        ActivityRecord srec;
18877        synchronized (this) {
18878            srec = ActivityRecord.forTokenLocked(activityToken);
18879        }
18880        if (srec == null) {
18881            return -1;
18882        }
18883        return srec.launchedFromUid;
18884    }
18885
18886    public String getLaunchedFromPackage(IBinder activityToken) {
18887        ActivityRecord srec;
18888        synchronized (this) {
18889            srec = ActivityRecord.forTokenLocked(activityToken);
18890        }
18891        if (srec == null) {
18892            return null;
18893        }
18894        return srec.launchedFromPackage;
18895    }
18896
18897    // =========================================================
18898    // LIFETIME MANAGEMENT
18899    // =========================================================
18900
18901    // Returns which broadcast queue the app is the current [or imminent] receiver
18902    // on, or 'null' if the app is not an active broadcast recipient.
18903    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18904        BroadcastRecord r = app.curReceiver;
18905        if (r != null) {
18906            return r.queue;
18907        }
18908
18909        // It's not the current receiver, but it might be starting up to become one
18910        synchronized (this) {
18911            for (BroadcastQueue queue : mBroadcastQueues) {
18912                r = queue.mPendingBroadcast;
18913                if (r != null && r.curApp == app) {
18914                    // found it; report which queue it's in
18915                    return queue;
18916                }
18917            }
18918        }
18919
18920        return null;
18921    }
18922
18923    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18924            int targetUid, ComponentName targetComponent, String targetProcess) {
18925        if (!mTrackingAssociations) {
18926            return null;
18927        }
18928        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18929                = mAssociations.get(targetUid);
18930        if (components == null) {
18931            components = new ArrayMap<>();
18932            mAssociations.put(targetUid, components);
18933        }
18934        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18935        if (sourceUids == null) {
18936            sourceUids = new SparseArray<>();
18937            components.put(targetComponent, sourceUids);
18938        }
18939        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18940        if (sourceProcesses == null) {
18941            sourceProcesses = new ArrayMap<>();
18942            sourceUids.put(sourceUid, sourceProcesses);
18943        }
18944        Association ass = sourceProcesses.get(sourceProcess);
18945        if (ass == null) {
18946            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18947                    targetProcess);
18948            sourceProcesses.put(sourceProcess, ass);
18949        }
18950        ass.mCount++;
18951        ass.mNesting++;
18952        if (ass.mNesting == 1) {
18953            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18954            ass.mLastState = sourceState;
18955        }
18956        return ass;
18957    }
18958
18959    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18960            ComponentName targetComponent) {
18961        if (!mTrackingAssociations) {
18962            return;
18963        }
18964        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18965                = mAssociations.get(targetUid);
18966        if (components == null) {
18967            return;
18968        }
18969        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18970        if (sourceUids == null) {
18971            return;
18972        }
18973        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18974        if (sourceProcesses == null) {
18975            return;
18976        }
18977        Association ass = sourceProcesses.get(sourceProcess);
18978        if (ass == null || ass.mNesting <= 0) {
18979            return;
18980        }
18981        ass.mNesting--;
18982        if (ass.mNesting == 0) {
18983            long uptime = SystemClock.uptimeMillis();
18984            ass.mTime += uptime - ass.mStartTime;
18985            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18986                    += uptime - ass.mLastStateUptime;
18987            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18988        }
18989    }
18990
18991    private void noteUidProcessState(final int uid, final int state) {
18992        mBatteryStatsService.noteUidProcessState(uid, state);
18993        if (mTrackingAssociations) {
18994            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18995                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18996                        = mAssociations.valueAt(i1);
18997                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18998                    SparseArray<ArrayMap<String, Association>> sourceUids
18999                            = targetComponents.valueAt(i2);
19000                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19001                    if (sourceProcesses != null) {
19002                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19003                            Association ass = sourceProcesses.valueAt(i4);
19004                            if (ass.mNesting >= 1) {
19005                                // currently associated
19006                                long uptime = SystemClock.uptimeMillis();
19007                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19008                                        += uptime - ass.mLastStateUptime;
19009                                ass.mLastState = state;
19010                                ass.mLastStateUptime = uptime;
19011                            }
19012                        }
19013                    }
19014                }
19015            }
19016        }
19017    }
19018
19019    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19020            boolean doingAll, long now) {
19021        if (mAdjSeq == app.adjSeq) {
19022            // This adjustment has already been computed.
19023            return app.curRawAdj;
19024        }
19025
19026        if (app.thread == null) {
19027            app.adjSeq = mAdjSeq;
19028            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19029            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19030            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19031        }
19032
19033        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19034        app.adjSource = null;
19035        app.adjTarget = null;
19036        app.empty = false;
19037        app.cached = false;
19038
19039        final int activitiesSize = app.activities.size();
19040
19041        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19042            // The max adjustment doesn't allow this app to be anything
19043            // below foreground, so it is not worth doing work for it.
19044            app.adjType = "fixed";
19045            app.adjSeq = mAdjSeq;
19046            app.curRawAdj = app.maxAdj;
19047            app.foregroundActivities = false;
19048            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19049            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19050            // System processes can do UI, and when they do we want to have
19051            // them trim their memory after the user leaves the UI.  To
19052            // facilitate this, here we need to determine whether or not it
19053            // is currently showing UI.
19054            app.systemNoUi = true;
19055            if (app == TOP_APP) {
19056                app.systemNoUi = false;
19057                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19058                app.adjType = "pers-top-activity";
19059            } else if (activitiesSize > 0) {
19060                for (int j = 0; j < activitiesSize; j++) {
19061                    final ActivityRecord r = app.activities.get(j);
19062                    if (r.visible) {
19063                        app.systemNoUi = false;
19064                    }
19065                }
19066            }
19067            if (!app.systemNoUi) {
19068                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19069            }
19070            return (app.curAdj=app.maxAdj);
19071        }
19072
19073        app.systemNoUi = false;
19074
19075        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19076
19077        // Determine the importance of the process, starting with most
19078        // important to least, and assign an appropriate OOM adjustment.
19079        int adj;
19080        int schedGroup;
19081        int procState;
19082        boolean foregroundActivities = false;
19083        BroadcastQueue queue;
19084        if (app == TOP_APP) {
19085            // The last app on the list is the foreground app.
19086            adj = ProcessList.FOREGROUND_APP_ADJ;
19087            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19088            app.adjType = "top-activity";
19089            foregroundActivities = true;
19090            procState = PROCESS_STATE_CUR_TOP;
19091        } else if (app.instrumentationClass != null) {
19092            // Don't want to kill running instrumentation.
19093            adj = ProcessList.FOREGROUND_APP_ADJ;
19094            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19095            app.adjType = "instrumentation";
19096            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19097        } else if ((queue = isReceivingBroadcast(app)) != null) {
19098            // An app that is currently receiving a broadcast also
19099            // counts as being in the foreground for OOM killer purposes.
19100            // It's placed in a sched group based on the nature of the
19101            // broadcast as reflected by which queue it's active in.
19102            adj = ProcessList.FOREGROUND_APP_ADJ;
19103            schedGroup = (queue == mFgBroadcastQueue)
19104                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19105            app.adjType = "broadcast";
19106            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19107        } else if (app.executingServices.size() > 0) {
19108            // An app that is currently executing a service callback also
19109            // counts as being in the foreground.
19110            adj = ProcessList.FOREGROUND_APP_ADJ;
19111            schedGroup = app.execServicesFg ?
19112                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19113            app.adjType = "exec-service";
19114            procState = ActivityManager.PROCESS_STATE_SERVICE;
19115            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19116        } else {
19117            // As far as we know the process is empty.  We may change our mind later.
19118            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19119            // At this point we don't actually know the adjustment.  Use the cached adj
19120            // value that the caller wants us to.
19121            adj = cachedAdj;
19122            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19123            app.cached = true;
19124            app.empty = true;
19125            app.adjType = "cch-empty";
19126        }
19127
19128        // Examine all activities if not already foreground.
19129        if (!foregroundActivities && activitiesSize > 0) {
19130            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19131            for (int j = 0; j < activitiesSize; j++) {
19132                final ActivityRecord r = app.activities.get(j);
19133                if (r.app != app) {
19134                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19135                            + " instead of expected " + app);
19136                    if (r.app == null || (r.app.uid == app.uid)) {
19137                        // Only fix things up when they look sane
19138                        r.app = app;
19139                    } else {
19140                        continue;
19141                    }
19142                }
19143                if (r.visible) {
19144                    // App has a visible activity; only upgrade adjustment.
19145                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19146                        adj = ProcessList.VISIBLE_APP_ADJ;
19147                        app.adjType = "visible";
19148                    }
19149                    if (procState > PROCESS_STATE_CUR_TOP) {
19150                        procState = PROCESS_STATE_CUR_TOP;
19151                    }
19152                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19153                    app.cached = false;
19154                    app.empty = false;
19155                    foregroundActivities = true;
19156                    if (r.task != null && minLayer > 0) {
19157                        final int layer = r.task.mLayerRank;
19158                        if (layer >= 0 && minLayer > layer) {
19159                            minLayer = layer;
19160                        }
19161                    }
19162                    break;
19163                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19164                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19165                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19166                        app.adjType = "pausing";
19167                    }
19168                    if (procState > PROCESS_STATE_CUR_TOP) {
19169                        procState = PROCESS_STATE_CUR_TOP;
19170                    }
19171                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19172                    app.cached = false;
19173                    app.empty = false;
19174                    foregroundActivities = true;
19175                } else if (r.state == ActivityState.STOPPING) {
19176                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19177                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19178                        app.adjType = "stopping";
19179                    }
19180                    // For the process state, we will at this point consider the
19181                    // process to be cached.  It will be cached either as an activity
19182                    // or empty depending on whether the activity is finishing.  We do
19183                    // this so that we can treat the process as cached for purposes of
19184                    // memory trimming (determing current memory level, trim command to
19185                    // send to process) since there can be an arbitrary number of stopping
19186                    // processes and they should soon all go into the cached state.
19187                    if (!r.finishing) {
19188                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19189                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19190                        }
19191                    }
19192                    app.cached = false;
19193                    app.empty = false;
19194                    foregroundActivities = true;
19195                } else {
19196                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19197                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19198                        app.adjType = "cch-act";
19199                    }
19200                }
19201            }
19202            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19203                adj += minLayer;
19204            }
19205        }
19206
19207        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19208                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19209            if (app.foregroundServices) {
19210                // The user is aware of this app, so make it visible.
19211                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19212                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19213                app.cached = false;
19214                app.adjType = "fg-service";
19215                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19216            } else if (app.forcingToForeground != null) {
19217                // The user is aware of this app, so make it visible.
19218                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19219                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19220                app.cached = false;
19221                app.adjType = "force-fg";
19222                app.adjSource = app.forcingToForeground;
19223                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19224            }
19225        }
19226
19227        if (app == mHeavyWeightProcess) {
19228            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19229                // We don't want to kill the current heavy-weight process.
19230                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19231                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19232                app.cached = false;
19233                app.adjType = "heavy";
19234            }
19235            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19236                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19237            }
19238        }
19239
19240        if (app == mHomeProcess) {
19241            if (adj > ProcessList.HOME_APP_ADJ) {
19242                // This process is hosting what we currently consider to be the
19243                // home app, so we don't want to let it go into the background.
19244                adj = ProcessList.HOME_APP_ADJ;
19245                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19246                app.cached = false;
19247                app.adjType = "home";
19248            }
19249            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19250                procState = ActivityManager.PROCESS_STATE_HOME;
19251            }
19252        }
19253
19254        if (app == mPreviousProcess && app.activities.size() > 0) {
19255            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19256                // This was the previous process that showed UI to the user.
19257                // We want to try to keep it around more aggressively, to give
19258                // a good experience around switching between two apps.
19259                adj = ProcessList.PREVIOUS_APP_ADJ;
19260                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19261                app.cached = false;
19262                app.adjType = "previous";
19263            }
19264            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19265                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19266            }
19267        }
19268
19269        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19270                + " reason=" + app.adjType);
19271
19272        // By default, we use the computed adjustment.  It may be changed if
19273        // there are applications dependent on our services or providers, but
19274        // this gives us a baseline and makes sure we don't get into an
19275        // infinite recursion.
19276        app.adjSeq = mAdjSeq;
19277        app.curRawAdj = adj;
19278        app.hasStartedServices = false;
19279
19280        if (mBackupTarget != null && app == mBackupTarget.app) {
19281            // If possible we want to avoid killing apps while they're being backed up
19282            if (adj > ProcessList.BACKUP_APP_ADJ) {
19283                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19284                adj = ProcessList.BACKUP_APP_ADJ;
19285                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19286                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19287                }
19288                app.adjType = "backup";
19289                app.cached = false;
19290            }
19291            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19292                procState = ActivityManager.PROCESS_STATE_BACKUP;
19293            }
19294        }
19295
19296        boolean mayBeTop = false;
19297
19298        for (int is = app.services.size()-1;
19299                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19300                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19301                        || procState > ActivityManager.PROCESS_STATE_TOP);
19302                is--) {
19303            ServiceRecord s = app.services.valueAt(is);
19304            if (s.startRequested) {
19305                app.hasStartedServices = true;
19306                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19307                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19308                }
19309                if (app.hasShownUi && app != mHomeProcess) {
19310                    // If this process has shown some UI, let it immediately
19311                    // go to the LRU list because it may be pretty heavy with
19312                    // UI stuff.  We'll tag it with a label just to help
19313                    // debug and understand what is going on.
19314                    if (adj > ProcessList.SERVICE_ADJ) {
19315                        app.adjType = "cch-started-ui-services";
19316                    }
19317                } else {
19318                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19319                        // This service has seen some activity within
19320                        // recent memory, so we will keep its process ahead
19321                        // of the background processes.
19322                        if (adj > ProcessList.SERVICE_ADJ) {
19323                            adj = ProcessList.SERVICE_ADJ;
19324                            app.adjType = "started-services";
19325                            app.cached = false;
19326                        }
19327                    }
19328                    // If we have let the service slide into the background
19329                    // state, still have some text describing what it is doing
19330                    // even though the service no longer has an impact.
19331                    if (adj > ProcessList.SERVICE_ADJ) {
19332                        app.adjType = "cch-started-services";
19333                    }
19334                }
19335            }
19336
19337            for (int conni = s.connections.size()-1;
19338                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19339                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19340                            || procState > ActivityManager.PROCESS_STATE_TOP);
19341                    conni--) {
19342                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19343                for (int i = 0;
19344                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19345                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19346                                || procState > ActivityManager.PROCESS_STATE_TOP);
19347                        i++) {
19348                    // XXX should compute this based on the max of
19349                    // all connected clients.
19350                    ConnectionRecord cr = clist.get(i);
19351                    if (cr.binding.client == app) {
19352                        // Binding to ourself is not interesting.
19353                        continue;
19354                    }
19355
19356                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19357                        ProcessRecord client = cr.binding.client;
19358                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19359                                TOP_APP, doingAll, now);
19360                        int clientProcState = client.curProcState;
19361                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19362                            // If the other app is cached for any reason, for purposes here
19363                            // we are going to consider it empty.  The specific cached state
19364                            // doesn't propagate except under certain conditions.
19365                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19366                        }
19367                        String adjType = null;
19368                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19369                            // Not doing bind OOM management, so treat
19370                            // this guy more like a started service.
19371                            if (app.hasShownUi && app != mHomeProcess) {
19372                                // If this process has shown some UI, let it immediately
19373                                // go to the LRU list because it may be pretty heavy with
19374                                // UI stuff.  We'll tag it with a label just to help
19375                                // debug and understand what is going on.
19376                                if (adj > clientAdj) {
19377                                    adjType = "cch-bound-ui-services";
19378                                }
19379                                app.cached = false;
19380                                clientAdj = adj;
19381                                clientProcState = procState;
19382                            } else {
19383                                if (now >= (s.lastActivity
19384                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19385                                    // This service has not seen activity within
19386                                    // recent memory, so allow it to drop to the
19387                                    // LRU list if there is no other reason to keep
19388                                    // it around.  We'll also tag it with a label just
19389                                    // to help debug and undertand what is going on.
19390                                    if (adj > clientAdj) {
19391                                        adjType = "cch-bound-services";
19392                                    }
19393                                    clientAdj = adj;
19394                                }
19395                            }
19396                        }
19397                        if (adj > clientAdj) {
19398                            // If this process has recently shown UI, and
19399                            // the process that is binding to it is less
19400                            // important than being visible, then we don't
19401                            // care about the binding as much as we care
19402                            // about letting this process get into the LRU
19403                            // list to be killed and restarted if needed for
19404                            // memory.
19405                            if (app.hasShownUi && app != mHomeProcess
19406                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19407                                adjType = "cch-bound-ui-services";
19408                            } else {
19409                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19410                                        |Context.BIND_IMPORTANT)) != 0) {
19411                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19412                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19413                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19414                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19415                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19416                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19417                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19418                                    adj = clientAdj;
19419                                } else {
19420                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19421                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19422                                    }
19423                                }
19424                                if (!client.cached) {
19425                                    app.cached = false;
19426                                }
19427                                adjType = "service";
19428                            }
19429                        }
19430                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19431                            // This will treat important bound services identically to
19432                            // the top app, which may behave differently than generic
19433                            // foreground work.
19434                            if (client.curSchedGroup > schedGroup) {
19435                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19436                                    schedGroup = client.curSchedGroup;
19437                                } else {
19438                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19439                                }
19440                            }
19441                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19442                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19443                                    // Special handling of clients who are in the top state.
19444                                    // We *may* want to consider this process to be in the
19445                                    // top state as well, but only if there is not another
19446                                    // reason for it to be running.  Being on the top is a
19447                                    // special state, meaning you are specifically running
19448                                    // for the current top app.  If the process is already
19449                                    // running in the background for some other reason, it
19450                                    // is more important to continue considering it to be
19451                                    // in the background state.
19452                                    mayBeTop = true;
19453                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19454                                } else {
19455                                    // Special handling for above-top states (persistent
19456                                    // processes).  These should not bring the current process
19457                                    // into the top state, since they are not on top.  Instead
19458                                    // give them the best state after that.
19459                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19460                                        clientProcState =
19461                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19462                                    } else if (mWakefulness
19463                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19464                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19465                                                    != 0) {
19466                                        clientProcState =
19467                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19468                                    } else {
19469                                        clientProcState =
19470                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19471                                    }
19472                                }
19473                            }
19474                        } else {
19475                            if (clientProcState <
19476                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19477                                clientProcState =
19478                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19479                            }
19480                        }
19481                        if (procState > clientProcState) {
19482                            procState = clientProcState;
19483                        }
19484                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19485                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19486                            app.pendingUiClean = true;
19487                        }
19488                        if (adjType != null) {
19489                            app.adjType = adjType;
19490                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19491                                    .REASON_SERVICE_IN_USE;
19492                            app.adjSource = cr.binding.client;
19493                            app.adjSourceProcState = clientProcState;
19494                            app.adjTarget = s.name;
19495                        }
19496                    }
19497                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19498                        app.treatLikeActivity = true;
19499                    }
19500                    final ActivityRecord a = cr.activity;
19501                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19502                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19503                            (a.visible || a.state == ActivityState.RESUMED ||
19504                             a.state == ActivityState.PAUSING)) {
19505                            adj = ProcessList.FOREGROUND_APP_ADJ;
19506                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19507                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19508                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19509                                } else {
19510                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19511                                }
19512                            }
19513                            app.cached = false;
19514                            app.adjType = "service";
19515                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19516                                    .REASON_SERVICE_IN_USE;
19517                            app.adjSource = a;
19518                            app.adjSourceProcState = procState;
19519                            app.adjTarget = s.name;
19520                        }
19521                    }
19522                }
19523            }
19524        }
19525
19526        for (int provi = app.pubProviders.size()-1;
19527                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19528                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19529                        || procState > ActivityManager.PROCESS_STATE_TOP);
19530                provi--) {
19531            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19532            for (int i = cpr.connections.size()-1;
19533                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19534                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19535                            || procState > ActivityManager.PROCESS_STATE_TOP);
19536                    i--) {
19537                ContentProviderConnection conn = cpr.connections.get(i);
19538                ProcessRecord client = conn.client;
19539                if (client == app) {
19540                    // Being our own client is not interesting.
19541                    continue;
19542                }
19543                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19544                int clientProcState = client.curProcState;
19545                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19546                    // If the other app is cached for any reason, for purposes here
19547                    // we are going to consider it empty.
19548                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19549                }
19550                if (adj > clientAdj) {
19551                    if (app.hasShownUi && app != mHomeProcess
19552                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19553                        app.adjType = "cch-ui-provider";
19554                    } else {
19555                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19556                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19557                        app.adjType = "provider";
19558                    }
19559                    app.cached &= client.cached;
19560                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19561                            .REASON_PROVIDER_IN_USE;
19562                    app.adjSource = client;
19563                    app.adjSourceProcState = clientProcState;
19564                    app.adjTarget = cpr.name;
19565                }
19566                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19567                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19568                        // Special handling of clients who are in the top state.
19569                        // We *may* want to consider this process to be in the
19570                        // top state as well, but only if there is not another
19571                        // reason for it to be running.  Being on the top is a
19572                        // special state, meaning you are specifically running
19573                        // for the current top app.  If the process is already
19574                        // running in the background for some other reason, it
19575                        // is more important to continue considering it to be
19576                        // in the background state.
19577                        mayBeTop = true;
19578                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19579                    } else {
19580                        // Special handling for above-top states (persistent
19581                        // processes).  These should not bring the current process
19582                        // into the top state, since they are not on top.  Instead
19583                        // give them the best state after that.
19584                        clientProcState =
19585                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19586                    }
19587                }
19588                if (procState > clientProcState) {
19589                    procState = clientProcState;
19590                }
19591                if (client.curSchedGroup > schedGroup) {
19592                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19593                }
19594            }
19595            // If the provider has external (non-framework) process
19596            // dependencies, ensure that its adjustment is at least
19597            // FOREGROUND_APP_ADJ.
19598            if (cpr.hasExternalProcessHandles()) {
19599                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19600                    adj = ProcessList.FOREGROUND_APP_ADJ;
19601                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19602                    app.cached = false;
19603                    app.adjType = "provider";
19604                    app.adjTarget = cpr.name;
19605                }
19606                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19607                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19608                }
19609            }
19610        }
19611
19612        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19613            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19614                adj = ProcessList.PREVIOUS_APP_ADJ;
19615                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19616                app.cached = false;
19617                app.adjType = "provider";
19618            }
19619            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19620                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19621            }
19622        }
19623
19624        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19625            // A client of one of our services or providers is in the top state.  We
19626            // *may* want to be in the top state, but not if we are already running in
19627            // the background for some other reason.  For the decision here, we are going
19628            // to pick out a few specific states that we want to remain in when a client
19629            // is top (states that tend to be longer-term) and otherwise allow it to go
19630            // to the top state.
19631            switch (procState) {
19632                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19633                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19634                case ActivityManager.PROCESS_STATE_SERVICE:
19635                    // These all are longer-term states, so pull them up to the top
19636                    // of the background states, but not all the way to the top state.
19637                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19638                    break;
19639                default:
19640                    // Otherwise, top is a better choice, so take it.
19641                    procState = ActivityManager.PROCESS_STATE_TOP;
19642                    break;
19643            }
19644        }
19645
19646        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19647            if (app.hasClientActivities) {
19648                // This is a cached process, but with client activities.  Mark it so.
19649                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19650                app.adjType = "cch-client-act";
19651            } else if (app.treatLikeActivity) {
19652                // This is a cached process, but somebody wants us to treat it like it has
19653                // an activity, okay!
19654                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19655                app.adjType = "cch-as-act";
19656            }
19657        }
19658
19659        if (adj == ProcessList.SERVICE_ADJ) {
19660            if (doingAll) {
19661                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19662                mNewNumServiceProcs++;
19663                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19664                if (!app.serviceb) {
19665                    // This service isn't far enough down on the LRU list to
19666                    // normally be a B service, but if we are low on RAM and it
19667                    // is large we want to force it down since we would prefer to
19668                    // keep launcher over it.
19669                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19670                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19671                        app.serviceHighRam = true;
19672                        app.serviceb = true;
19673                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19674                    } else {
19675                        mNewNumAServiceProcs++;
19676                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19677                    }
19678                } else {
19679                    app.serviceHighRam = false;
19680                }
19681            }
19682            if (app.serviceb) {
19683                adj = ProcessList.SERVICE_B_ADJ;
19684            }
19685        }
19686
19687        app.curRawAdj = adj;
19688
19689        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19690        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19691        if (adj > app.maxAdj) {
19692            adj = app.maxAdj;
19693            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19694                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19695            }
19696        }
19697
19698        // Do final modification to adj.  Everything we do between here and applying
19699        // the final setAdj must be done in this function, because we will also use
19700        // it when computing the final cached adj later.  Note that we don't need to
19701        // worry about this for max adj above, since max adj will always be used to
19702        // keep it out of the cached vaues.
19703        app.curAdj = app.modifyRawOomAdj(adj);
19704        app.curSchedGroup = schedGroup;
19705        app.curProcState = procState;
19706        app.foregroundActivities = foregroundActivities;
19707
19708        return app.curRawAdj;
19709    }
19710
19711    /**
19712     * Record new PSS sample for a process.
19713     */
19714    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19715            long now) {
19716        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19717                swapPss * 1024);
19718        proc.lastPssTime = now;
19719        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19720        if (DEBUG_PSS) Slog.d(TAG_PSS,
19721                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19722                + " state=" + ProcessList.makeProcStateString(procState));
19723        if (proc.initialIdlePss == 0) {
19724            proc.initialIdlePss = pss;
19725        }
19726        proc.lastPss = pss;
19727        proc.lastSwapPss = swapPss;
19728        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19729            proc.lastCachedPss = pss;
19730            proc.lastCachedSwapPss = swapPss;
19731        }
19732
19733        final SparseArray<Pair<Long, String>> watchUids
19734                = mMemWatchProcesses.getMap().get(proc.processName);
19735        Long check = null;
19736        if (watchUids != null) {
19737            Pair<Long, String> val = watchUids.get(proc.uid);
19738            if (val == null) {
19739                val = watchUids.get(0);
19740            }
19741            if (val != null) {
19742                check = val.first;
19743            }
19744        }
19745        if (check != null) {
19746            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19747                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19748                if (!isDebuggable) {
19749                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19750                        isDebuggable = true;
19751                    }
19752                }
19753                if (isDebuggable) {
19754                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19755                    final ProcessRecord myProc = proc;
19756                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19757                    mMemWatchDumpProcName = proc.processName;
19758                    mMemWatchDumpFile = heapdumpFile.toString();
19759                    mMemWatchDumpPid = proc.pid;
19760                    mMemWatchDumpUid = proc.uid;
19761                    BackgroundThread.getHandler().post(new Runnable() {
19762                        @Override
19763                        public void run() {
19764                            revokeUriPermission(ActivityThread.currentActivityThread()
19765                                            .getApplicationThread(),
19766                                    DumpHeapActivity.JAVA_URI,
19767                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19768                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19769                                    UserHandle.myUserId());
19770                            ParcelFileDescriptor fd = null;
19771                            try {
19772                                heapdumpFile.delete();
19773                                fd = ParcelFileDescriptor.open(heapdumpFile,
19774                                        ParcelFileDescriptor.MODE_CREATE |
19775                                                ParcelFileDescriptor.MODE_TRUNCATE |
19776                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19777                                                ParcelFileDescriptor.MODE_APPEND);
19778                                IApplicationThread thread = myProc.thread;
19779                                if (thread != null) {
19780                                    try {
19781                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19782                                                "Requesting dump heap from "
19783                                                + myProc + " to " + heapdumpFile);
19784                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19785                                    } catch (RemoteException e) {
19786                                    }
19787                                }
19788                            } catch (FileNotFoundException e) {
19789                                e.printStackTrace();
19790                            } finally {
19791                                if (fd != null) {
19792                                    try {
19793                                        fd.close();
19794                                    } catch (IOException e) {
19795                                    }
19796                                }
19797                            }
19798                        }
19799                    });
19800                } else {
19801                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19802                            + ", but debugging not enabled");
19803                }
19804            }
19805        }
19806    }
19807
19808    /**
19809     * Schedule PSS collection of a process.
19810     */
19811    void requestPssLocked(ProcessRecord proc, int procState) {
19812        if (mPendingPssProcesses.contains(proc)) {
19813            return;
19814        }
19815        if (mPendingPssProcesses.size() == 0) {
19816            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19817        }
19818        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19819        proc.pssProcState = procState;
19820        mPendingPssProcesses.add(proc);
19821    }
19822
19823    /**
19824     * Schedule PSS collection of all processes.
19825     */
19826    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19827        if (!always) {
19828            if (now < (mLastFullPssTime +
19829                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19830                return;
19831            }
19832        }
19833        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19834        mLastFullPssTime = now;
19835        mFullPssPending = true;
19836        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19837        mPendingPssProcesses.clear();
19838        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19839            ProcessRecord app = mLruProcesses.get(i);
19840            if (app.thread == null
19841                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19842                continue;
19843            }
19844            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19845                app.pssProcState = app.setProcState;
19846                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19847                        mTestPssMode, isSleepingLocked(), now);
19848                mPendingPssProcesses.add(app);
19849            }
19850        }
19851        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19852    }
19853
19854    public void setTestPssMode(boolean enabled) {
19855        synchronized (this) {
19856            mTestPssMode = enabled;
19857            if (enabled) {
19858                // Whenever we enable the mode, we want to take a snapshot all of current
19859                // process mem use.
19860                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19861            }
19862        }
19863    }
19864
19865    /**
19866     * Ask a given process to GC right now.
19867     */
19868    final void performAppGcLocked(ProcessRecord app) {
19869        try {
19870            app.lastRequestedGc = SystemClock.uptimeMillis();
19871            if (app.thread != null) {
19872                if (app.reportLowMemory) {
19873                    app.reportLowMemory = false;
19874                    app.thread.scheduleLowMemory();
19875                } else {
19876                    app.thread.processInBackground();
19877                }
19878            }
19879        } catch (Exception e) {
19880            // whatever.
19881        }
19882    }
19883
19884    /**
19885     * Returns true if things are idle enough to perform GCs.
19886     */
19887    private final boolean canGcNowLocked() {
19888        boolean processingBroadcasts = false;
19889        for (BroadcastQueue q : mBroadcastQueues) {
19890            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19891                processingBroadcasts = true;
19892            }
19893        }
19894        return !processingBroadcasts
19895                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19896    }
19897
19898    /**
19899     * Perform GCs on all processes that are waiting for it, but only
19900     * if things are idle.
19901     */
19902    final void performAppGcsLocked() {
19903        final int N = mProcessesToGc.size();
19904        if (N <= 0) {
19905            return;
19906        }
19907        if (canGcNowLocked()) {
19908            while (mProcessesToGc.size() > 0) {
19909                ProcessRecord proc = mProcessesToGc.remove(0);
19910                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19911                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19912                            <= SystemClock.uptimeMillis()) {
19913                        // To avoid spamming the system, we will GC processes one
19914                        // at a time, waiting a few seconds between each.
19915                        performAppGcLocked(proc);
19916                        scheduleAppGcsLocked();
19917                        return;
19918                    } else {
19919                        // It hasn't been long enough since we last GCed this
19920                        // process...  put it in the list to wait for its time.
19921                        addProcessToGcListLocked(proc);
19922                        break;
19923                    }
19924                }
19925            }
19926
19927            scheduleAppGcsLocked();
19928        }
19929    }
19930
19931    /**
19932     * If all looks good, perform GCs on all processes waiting for them.
19933     */
19934    final void performAppGcsIfAppropriateLocked() {
19935        if (canGcNowLocked()) {
19936            performAppGcsLocked();
19937            return;
19938        }
19939        // Still not idle, wait some more.
19940        scheduleAppGcsLocked();
19941    }
19942
19943    /**
19944     * Schedule the execution of all pending app GCs.
19945     */
19946    final void scheduleAppGcsLocked() {
19947        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19948
19949        if (mProcessesToGc.size() > 0) {
19950            // Schedule a GC for the time to the next process.
19951            ProcessRecord proc = mProcessesToGc.get(0);
19952            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19953
19954            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19955            long now = SystemClock.uptimeMillis();
19956            if (when < (now+GC_TIMEOUT)) {
19957                when = now + GC_TIMEOUT;
19958            }
19959            mHandler.sendMessageAtTime(msg, when);
19960        }
19961    }
19962
19963    /**
19964     * Add a process to the array of processes waiting to be GCed.  Keeps the
19965     * list in sorted order by the last GC time.  The process can't already be
19966     * on the list.
19967     */
19968    final void addProcessToGcListLocked(ProcessRecord proc) {
19969        boolean added = false;
19970        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19971            if (mProcessesToGc.get(i).lastRequestedGc <
19972                    proc.lastRequestedGc) {
19973                added = true;
19974                mProcessesToGc.add(i+1, proc);
19975                break;
19976            }
19977        }
19978        if (!added) {
19979            mProcessesToGc.add(0, proc);
19980        }
19981    }
19982
19983    /**
19984     * Set up to ask a process to GC itself.  This will either do it
19985     * immediately, or put it on the list of processes to gc the next
19986     * time things are idle.
19987     */
19988    final void scheduleAppGcLocked(ProcessRecord app) {
19989        long now = SystemClock.uptimeMillis();
19990        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19991            return;
19992        }
19993        if (!mProcessesToGc.contains(app)) {
19994            addProcessToGcListLocked(app);
19995            scheduleAppGcsLocked();
19996        }
19997    }
19998
19999    final void checkExcessivePowerUsageLocked(boolean doKills) {
20000        updateCpuStatsNow();
20001
20002        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20003        boolean doWakeKills = doKills;
20004        boolean doCpuKills = doKills;
20005        if (mLastPowerCheckRealtime == 0) {
20006            doWakeKills = false;
20007        }
20008        if (mLastPowerCheckUptime == 0) {
20009            doCpuKills = false;
20010        }
20011        if (stats.isScreenOn()) {
20012            doWakeKills = false;
20013        }
20014        final long curRealtime = SystemClock.elapsedRealtime();
20015        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20016        final long curUptime = SystemClock.uptimeMillis();
20017        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20018        mLastPowerCheckRealtime = curRealtime;
20019        mLastPowerCheckUptime = curUptime;
20020        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20021            doWakeKills = false;
20022        }
20023        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20024            doCpuKills = false;
20025        }
20026        int i = mLruProcesses.size();
20027        while (i > 0) {
20028            i--;
20029            ProcessRecord app = mLruProcesses.get(i);
20030            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20031                long wtime;
20032                synchronized (stats) {
20033                    wtime = stats.getProcessWakeTime(app.info.uid,
20034                            app.pid, curRealtime);
20035                }
20036                long wtimeUsed = wtime - app.lastWakeTime;
20037                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20038                if (DEBUG_POWER) {
20039                    StringBuilder sb = new StringBuilder(128);
20040                    sb.append("Wake for ");
20041                    app.toShortString(sb);
20042                    sb.append(": over ");
20043                    TimeUtils.formatDuration(realtimeSince, sb);
20044                    sb.append(" used ");
20045                    TimeUtils.formatDuration(wtimeUsed, sb);
20046                    sb.append(" (");
20047                    sb.append((wtimeUsed*100)/realtimeSince);
20048                    sb.append("%)");
20049                    Slog.i(TAG_POWER, sb.toString());
20050                    sb.setLength(0);
20051                    sb.append("CPU for ");
20052                    app.toShortString(sb);
20053                    sb.append(": over ");
20054                    TimeUtils.formatDuration(uptimeSince, sb);
20055                    sb.append(" used ");
20056                    TimeUtils.formatDuration(cputimeUsed, sb);
20057                    sb.append(" (");
20058                    sb.append((cputimeUsed*100)/uptimeSince);
20059                    sb.append("%)");
20060                    Slog.i(TAG_POWER, sb.toString());
20061                }
20062                // If a process has held a wake lock for more
20063                // than 50% of the time during this period,
20064                // that sounds bad.  Kill!
20065                if (doWakeKills && realtimeSince > 0
20066                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20067                    synchronized (stats) {
20068                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20069                                realtimeSince, wtimeUsed);
20070                    }
20071                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20072                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20073                } else if (doCpuKills && uptimeSince > 0
20074                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20075                    synchronized (stats) {
20076                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20077                                uptimeSince, cputimeUsed);
20078                    }
20079                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20080                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20081                } else {
20082                    app.lastWakeTime = wtime;
20083                    app.lastCpuTime = app.curCpuTime;
20084                }
20085            }
20086        }
20087    }
20088
20089    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20090            long nowElapsed) {
20091        boolean success = true;
20092
20093        if (app.curRawAdj != app.setRawAdj) {
20094            app.setRawAdj = app.curRawAdj;
20095        }
20096
20097        int changes = 0;
20098
20099        if (app.curAdj != app.setAdj) {
20100            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20101            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20102                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20103                    + app.adjType);
20104            app.setAdj = app.curAdj;
20105            app.verifiedAdj = ProcessList.INVALID_ADJ;
20106        }
20107
20108        if (app.setSchedGroup != app.curSchedGroup) {
20109            app.setSchedGroup = app.curSchedGroup;
20110            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20111                    "Setting sched group of " + app.processName
20112                    + " to " + app.curSchedGroup);
20113            if (app.waitingToKill != null && app.curReceiver == null
20114                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20115                app.kill(app.waitingToKill, true);
20116                success = false;
20117            } else {
20118                int processGroup;
20119                switch (app.curSchedGroup) {
20120                    case ProcessList.SCHED_GROUP_BACKGROUND:
20121                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20122                        break;
20123                    case ProcessList.SCHED_GROUP_TOP_APP:
20124                        processGroup = Process.THREAD_GROUP_TOP_APP;
20125                        break;
20126                    default:
20127                        processGroup = Process.THREAD_GROUP_DEFAULT;
20128                        break;
20129                }
20130                if (true) {
20131                    long oldId = Binder.clearCallingIdentity();
20132                    try {
20133                        Process.setProcessGroup(app.pid, processGroup);
20134                    } catch (Exception e) {
20135                        Slog.w(TAG, "Failed setting process group of " + app.pid
20136                                + " to " + app.curSchedGroup);
20137                        e.printStackTrace();
20138                    } finally {
20139                        Binder.restoreCallingIdentity(oldId);
20140                    }
20141                } else {
20142                    if (app.thread != null) {
20143                        try {
20144                            app.thread.setSchedulingGroup(processGroup);
20145                        } catch (RemoteException e) {
20146                        }
20147                    }
20148                }
20149            }
20150        }
20151        if (app.repForegroundActivities != app.foregroundActivities) {
20152            app.repForegroundActivities = app.foregroundActivities;
20153            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20154        }
20155        if (app.repProcState != app.curProcState) {
20156            app.repProcState = app.curProcState;
20157            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20158            if (app.thread != null) {
20159                try {
20160                    if (false) {
20161                        //RuntimeException h = new RuntimeException("here");
20162                        Slog.i(TAG, "Sending new process state " + app.repProcState
20163                                + " to " + app /*, h*/);
20164                    }
20165                    app.thread.setProcessState(app.repProcState);
20166                } catch (RemoteException e) {
20167                }
20168            }
20169        }
20170        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20171                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20172            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20173                // Experimental code to more aggressively collect pss while
20174                // running test...  the problem is that this tends to collect
20175                // the data right when a process is transitioning between process
20176                // states, which well tend to give noisy data.
20177                long start = SystemClock.uptimeMillis();
20178                long pss = Debug.getPss(app.pid, mTmpLong, null);
20179                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20180                mPendingPssProcesses.remove(app);
20181                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20182                        + " to " + app.curProcState + ": "
20183                        + (SystemClock.uptimeMillis()-start) + "ms");
20184            }
20185            app.lastStateTime = now;
20186            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20187                    mTestPssMode, isSleepingLocked(), now);
20188            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20189                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20190                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20191                    + (app.nextPssTime-now) + ": " + app);
20192        } else {
20193            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20194                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20195                    mTestPssMode)))) {
20196                requestPssLocked(app, app.setProcState);
20197                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20198                        mTestPssMode, isSleepingLocked(), now);
20199            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20200                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20201        }
20202        if (app.setProcState != app.curProcState) {
20203            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20204                    "Proc state change of " + app.processName
20205                            + " to " + app.curProcState);
20206            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20207            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20208            if (setImportant && !curImportant) {
20209                // This app is no longer something we consider important enough to allow to
20210                // use arbitrary amounts of battery power.  Note
20211                // its current wake lock time to later know to kill it if
20212                // it is not behaving well.
20213                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20214                synchronized (stats) {
20215                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20216                            app.pid, nowElapsed);
20217                }
20218                app.lastCpuTime = app.curCpuTime;
20219
20220            }
20221            // Inform UsageStats of important process state change
20222            // Must be called before updating setProcState
20223            maybeUpdateUsageStatsLocked(app, nowElapsed);
20224
20225            app.setProcState = app.curProcState;
20226            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20227                app.notCachedSinceIdle = false;
20228            }
20229            if (!doingAll) {
20230                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20231            } else {
20232                app.procStateChanged = true;
20233            }
20234        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20235                > USAGE_STATS_INTERACTION_INTERVAL) {
20236            // For apps that sit around for a long time in the interactive state, we need
20237            // to report this at least once a day so they don't go idle.
20238            maybeUpdateUsageStatsLocked(app, nowElapsed);
20239        }
20240
20241        if (changes != 0) {
20242            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20243                    "Changes in " + app + ": " + changes);
20244            int i = mPendingProcessChanges.size()-1;
20245            ProcessChangeItem item = null;
20246            while (i >= 0) {
20247                item = mPendingProcessChanges.get(i);
20248                if (item.pid == app.pid) {
20249                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20250                            "Re-using existing item: " + item);
20251                    break;
20252                }
20253                i--;
20254            }
20255            if (i < 0) {
20256                // No existing item in pending changes; need a new one.
20257                final int NA = mAvailProcessChanges.size();
20258                if (NA > 0) {
20259                    item = mAvailProcessChanges.remove(NA-1);
20260                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20261                            "Retrieving available item: " + item);
20262                } else {
20263                    item = new ProcessChangeItem();
20264                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20265                            "Allocating new item: " + item);
20266                }
20267                item.changes = 0;
20268                item.pid = app.pid;
20269                item.uid = app.info.uid;
20270                if (mPendingProcessChanges.size() == 0) {
20271                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20272                            "*** Enqueueing dispatch processes changed!");
20273                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20274                }
20275                mPendingProcessChanges.add(item);
20276            }
20277            item.changes |= changes;
20278            item.processState = app.repProcState;
20279            item.foregroundActivities = app.repForegroundActivities;
20280            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20281                    "Item " + Integer.toHexString(System.identityHashCode(item))
20282                    + " " + app.toShortString() + ": changes=" + item.changes
20283                    + " procState=" + item.processState
20284                    + " foreground=" + item.foregroundActivities
20285                    + " type=" + app.adjType + " source=" + app.adjSource
20286                    + " target=" + app.adjTarget);
20287        }
20288
20289        return success;
20290    }
20291
20292    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20293        final UidRecord.ChangeItem pendingChange;
20294        if (uidRec == null || uidRec.pendingChange == null) {
20295            if (mPendingUidChanges.size() == 0) {
20296                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20297                        "*** Enqueueing dispatch uid changed!");
20298                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20299            }
20300            final int NA = mAvailUidChanges.size();
20301            if (NA > 0) {
20302                pendingChange = mAvailUidChanges.remove(NA-1);
20303                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20304                        "Retrieving available item: " + pendingChange);
20305            } else {
20306                pendingChange = new UidRecord.ChangeItem();
20307                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20308                        "Allocating new item: " + pendingChange);
20309            }
20310            if (uidRec != null) {
20311                uidRec.pendingChange = pendingChange;
20312                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20313                    // If this uid is going away, and we haven't yet reported it is gone,
20314                    // then do so now.
20315                    change = UidRecord.CHANGE_GONE_IDLE;
20316                }
20317            } else if (uid < 0) {
20318                throw new IllegalArgumentException("No UidRecord or uid");
20319            }
20320            pendingChange.uidRecord = uidRec;
20321            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20322            mPendingUidChanges.add(pendingChange);
20323        } else {
20324            pendingChange = uidRec.pendingChange;
20325            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20326                change = UidRecord.CHANGE_GONE_IDLE;
20327            }
20328        }
20329        pendingChange.change = change;
20330        pendingChange.processState = uidRec != null
20331                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20332    }
20333
20334    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20335            String authority) {
20336        if (app == null) return;
20337        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20338            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20339            if (userState == null) return;
20340            final long now = SystemClock.elapsedRealtime();
20341            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20342            if (lastReported == null || lastReported < now - 60 * 1000L) {
20343                mUsageStatsService.reportContentProviderUsage(
20344                        authority, providerPkgName, app.userId);
20345                userState.mProviderLastReportedFg.put(authority, now);
20346            }
20347        }
20348    }
20349
20350    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20351        if (DEBUG_USAGE_STATS) {
20352            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20353                    + "] state changes: old = " + app.setProcState + ", new = "
20354                    + app.curProcState);
20355        }
20356        if (mUsageStatsService == null) {
20357            return;
20358        }
20359        boolean isInteraction;
20360        // To avoid some abuse patterns, we are going to be careful about what we consider
20361        // to be an app interaction.  Being the top activity doesn't count while the display
20362        // is sleeping, nor do short foreground services.
20363        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20364            isInteraction = true;
20365            app.fgInteractionTime = 0;
20366        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20367            if (app.fgInteractionTime == 0) {
20368                app.fgInteractionTime = nowElapsed;
20369                isInteraction = false;
20370            } else {
20371                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20372            }
20373        } else {
20374            isInteraction = app.curProcState
20375                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20376            app.fgInteractionTime = 0;
20377        }
20378        if (isInteraction && (!app.reportedInteraction
20379                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20380            app.interactionEventTime = nowElapsed;
20381            String[] packages = app.getPackageList();
20382            if (packages != null) {
20383                for (int i = 0; i < packages.length; i++) {
20384                    mUsageStatsService.reportEvent(packages[i], app.userId,
20385                            UsageEvents.Event.SYSTEM_INTERACTION);
20386                }
20387            }
20388        }
20389        app.reportedInteraction = isInteraction;
20390        if (!isInteraction) {
20391            app.interactionEventTime = 0;
20392        }
20393    }
20394
20395    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20396        if (proc.thread != null) {
20397            if (proc.baseProcessTracker != null) {
20398                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20399            }
20400        }
20401    }
20402
20403    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20404            ProcessRecord TOP_APP, boolean doingAll, long now) {
20405        if (app.thread == null) {
20406            return false;
20407        }
20408
20409        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20410
20411        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20412    }
20413
20414    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20415            boolean oomAdj) {
20416        if (isForeground != proc.foregroundServices) {
20417            proc.foregroundServices = isForeground;
20418            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20419                    proc.info.uid);
20420            if (isForeground) {
20421                if (curProcs == null) {
20422                    curProcs = new ArrayList<ProcessRecord>();
20423                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20424                }
20425                if (!curProcs.contains(proc)) {
20426                    curProcs.add(proc);
20427                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20428                            proc.info.packageName, proc.info.uid);
20429                }
20430            } else {
20431                if (curProcs != null) {
20432                    if (curProcs.remove(proc)) {
20433                        mBatteryStatsService.noteEvent(
20434                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20435                                proc.info.packageName, proc.info.uid);
20436                        if (curProcs.size() <= 0) {
20437                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20438                        }
20439                    }
20440                }
20441            }
20442            if (oomAdj) {
20443                updateOomAdjLocked();
20444            }
20445        }
20446    }
20447
20448    private final ActivityRecord resumedAppLocked() {
20449        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20450        String pkg;
20451        int uid;
20452        if (act != null) {
20453            pkg = act.packageName;
20454            uid = act.info.applicationInfo.uid;
20455        } else {
20456            pkg = null;
20457            uid = -1;
20458        }
20459        // Has the UID or resumed package name changed?
20460        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20461                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20462            if (mCurResumedPackage != null) {
20463                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20464                        mCurResumedPackage, mCurResumedUid);
20465            }
20466            mCurResumedPackage = pkg;
20467            mCurResumedUid = uid;
20468            if (mCurResumedPackage != null) {
20469                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20470                        mCurResumedPackage, mCurResumedUid);
20471            }
20472        }
20473        return act;
20474    }
20475
20476    final boolean updateOomAdjLocked(ProcessRecord app) {
20477        final ActivityRecord TOP_ACT = resumedAppLocked();
20478        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20479        final boolean wasCached = app.cached;
20480
20481        mAdjSeq++;
20482
20483        // This is the desired cached adjusment we want to tell it to use.
20484        // If our app is currently cached, we know it, and that is it.  Otherwise,
20485        // we don't know it yet, and it needs to now be cached we will then
20486        // need to do a complete oom adj.
20487        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20488                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20489        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20490                SystemClock.uptimeMillis());
20491        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20492            // Changed to/from cached state, so apps after it in the LRU
20493            // list may also be changed.
20494            updateOomAdjLocked();
20495        }
20496        return success;
20497    }
20498
20499    final void updateOomAdjLocked() {
20500        final ActivityRecord TOP_ACT = resumedAppLocked();
20501        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20502        final long now = SystemClock.uptimeMillis();
20503        final long nowElapsed = SystemClock.elapsedRealtime();
20504        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20505        final int N = mLruProcesses.size();
20506
20507        if (false) {
20508            RuntimeException e = new RuntimeException();
20509            e.fillInStackTrace();
20510            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20511        }
20512
20513        // Reset state in all uid records.
20514        for (int i=mActiveUids.size()-1; i>=0; i--) {
20515            final UidRecord uidRec = mActiveUids.valueAt(i);
20516            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20517                    "Starting update of " + uidRec);
20518            uidRec.reset();
20519        }
20520
20521        mStackSupervisor.rankTaskLayersIfNeeded();
20522
20523        mAdjSeq++;
20524        mNewNumServiceProcs = 0;
20525        mNewNumAServiceProcs = 0;
20526
20527        final int emptyProcessLimit;
20528        final int cachedProcessLimit;
20529        if (mProcessLimit <= 0) {
20530            emptyProcessLimit = cachedProcessLimit = 0;
20531        } else if (mProcessLimit == 1) {
20532            emptyProcessLimit = 1;
20533            cachedProcessLimit = 0;
20534        } else {
20535            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20536            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20537        }
20538
20539        // Let's determine how many processes we have running vs.
20540        // how many slots we have for background processes; we may want
20541        // to put multiple processes in a slot of there are enough of
20542        // them.
20543        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20544                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20545        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20546        if (numEmptyProcs > cachedProcessLimit) {
20547            // If there are more empty processes than our limit on cached
20548            // processes, then use the cached process limit for the factor.
20549            // This ensures that the really old empty processes get pushed
20550            // down to the bottom, so if we are running low on memory we will
20551            // have a better chance at keeping around more cached processes
20552            // instead of a gazillion empty processes.
20553            numEmptyProcs = cachedProcessLimit;
20554        }
20555        int emptyFactor = numEmptyProcs/numSlots;
20556        if (emptyFactor < 1) emptyFactor = 1;
20557        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20558        if (cachedFactor < 1) cachedFactor = 1;
20559        int stepCached = 0;
20560        int stepEmpty = 0;
20561        int numCached = 0;
20562        int numEmpty = 0;
20563        int numTrimming = 0;
20564
20565        mNumNonCachedProcs = 0;
20566        mNumCachedHiddenProcs = 0;
20567
20568        // First update the OOM adjustment for each of the
20569        // application processes based on their current state.
20570        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20571        int nextCachedAdj = curCachedAdj+1;
20572        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20573        int nextEmptyAdj = curEmptyAdj+2;
20574        for (int i=N-1; i>=0; i--) {
20575            ProcessRecord app = mLruProcesses.get(i);
20576            if (!app.killedByAm && app.thread != null) {
20577                app.procStateChanged = false;
20578                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20579
20580                // If we haven't yet assigned the final cached adj
20581                // to the process, do that now.
20582                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20583                    switch (app.curProcState) {
20584                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20585                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20586                            // This process is a cached process holding activities...
20587                            // assign it the next cached value for that type, and then
20588                            // step that cached level.
20589                            app.curRawAdj = curCachedAdj;
20590                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20591                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20592                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20593                                    + ")");
20594                            if (curCachedAdj != nextCachedAdj) {
20595                                stepCached++;
20596                                if (stepCached >= cachedFactor) {
20597                                    stepCached = 0;
20598                                    curCachedAdj = nextCachedAdj;
20599                                    nextCachedAdj += 2;
20600                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20601                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20602                                    }
20603                                }
20604                            }
20605                            break;
20606                        default:
20607                            // For everything else, assign next empty cached process
20608                            // level and bump that up.  Note that this means that
20609                            // long-running services that have dropped down to the
20610                            // cached level will be treated as empty (since their process
20611                            // state is still as a service), which is what we want.
20612                            app.curRawAdj = curEmptyAdj;
20613                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20614                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20615                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20616                                    + ")");
20617                            if (curEmptyAdj != nextEmptyAdj) {
20618                                stepEmpty++;
20619                                if (stepEmpty >= emptyFactor) {
20620                                    stepEmpty = 0;
20621                                    curEmptyAdj = nextEmptyAdj;
20622                                    nextEmptyAdj += 2;
20623                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20624                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20625                                    }
20626                                }
20627                            }
20628                            break;
20629                    }
20630                }
20631
20632                applyOomAdjLocked(app, true, now, nowElapsed);
20633
20634                // Count the number of process types.
20635                switch (app.curProcState) {
20636                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20637                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20638                        mNumCachedHiddenProcs++;
20639                        numCached++;
20640                        if (numCached > cachedProcessLimit) {
20641                            app.kill("cached #" + numCached, true);
20642                        }
20643                        break;
20644                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20645                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20646                                && app.lastActivityTime < oldTime) {
20647                            app.kill("empty for "
20648                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20649                                    / 1000) + "s", true);
20650                        } else {
20651                            numEmpty++;
20652                            if (numEmpty > emptyProcessLimit) {
20653                                app.kill("empty #" + numEmpty, true);
20654                            }
20655                        }
20656                        break;
20657                    default:
20658                        mNumNonCachedProcs++;
20659                        break;
20660                }
20661
20662                if (app.isolated && app.services.size() <= 0) {
20663                    // If this is an isolated process, and there are no
20664                    // services running in it, then the process is no longer
20665                    // needed.  We agressively kill these because we can by
20666                    // definition not re-use the same process again, and it is
20667                    // good to avoid having whatever code was running in them
20668                    // left sitting around after no longer needed.
20669                    app.kill("isolated not needed", true);
20670                } else {
20671                    // Keeping this process, update its uid.
20672                    final UidRecord uidRec = app.uidRecord;
20673                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20674                        uidRec.curProcState = app.curProcState;
20675                    }
20676                }
20677
20678                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20679                        && !app.killedByAm) {
20680                    numTrimming++;
20681                }
20682            }
20683        }
20684
20685        mNumServiceProcs = mNewNumServiceProcs;
20686
20687        // Now determine the memory trimming level of background processes.
20688        // Unfortunately we need to start at the back of the list to do this
20689        // properly.  We only do this if the number of background apps we
20690        // are managing to keep around is less than half the maximum we desire;
20691        // if we are keeping a good number around, we'll let them use whatever
20692        // memory they want.
20693        final int numCachedAndEmpty = numCached + numEmpty;
20694        int memFactor;
20695        if (numCached <= ProcessList.TRIM_CACHED_APPS
20696                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20697            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20698                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20699            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20700                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20701            } else {
20702                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20703            }
20704        } else {
20705            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20706        }
20707        // We always allow the memory level to go up (better).  We only allow it to go
20708        // down if we are in a state where that is allowed, *and* the total number of processes
20709        // has gone down since last time.
20710        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20711                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20712                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20713        if (memFactor > mLastMemoryLevel) {
20714            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20715                memFactor = mLastMemoryLevel;
20716                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20717            }
20718        }
20719        if (memFactor != mLastMemoryLevel) {
20720            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20721        }
20722        mLastMemoryLevel = memFactor;
20723        mLastNumProcesses = mLruProcesses.size();
20724        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20725        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20726        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20727            if (mLowRamStartTime == 0) {
20728                mLowRamStartTime = now;
20729            }
20730            int step = 0;
20731            int fgTrimLevel;
20732            switch (memFactor) {
20733                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20734                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20735                    break;
20736                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20737                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20738                    break;
20739                default:
20740                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20741                    break;
20742            }
20743            int factor = numTrimming/3;
20744            int minFactor = 2;
20745            if (mHomeProcess != null) minFactor++;
20746            if (mPreviousProcess != null) minFactor++;
20747            if (factor < minFactor) factor = minFactor;
20748            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20749            for (int i=N-1; i>=0; i--) {
20750                ProcessRecord app = mLruProcesses.get(i);
20751                if (allChanged || app.procStateChanged) {
20752                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20753                    app.procStateChanged = false;
20754                }
20755                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20756                        && !app.killedByAm) {
20757                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20758                        try {
20759                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20760                                    "Trimming memory of " + app.processName + " to " + curLevel);
20761                            app.thread.scheduleTrimMemory(curLevel);
20762                        } catch (RemoteException e) {
20763                        }
20764                        if (false) {
20765                            // For now we won't do this; our memory trimming seems
20766                            // to be good enough at this point that destroying
20767                            // activities causes more harm than good.
20768                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20769                                    && app != mHomeProcess && app != mPreviousProcess) {
20770                                // Need to do this on its own message because the stack may not
20771                                // be in a consistent state at this point.
20772                                // For these apps we will also finish their activities
20773                                // to help them free memory.
20774                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20775                            }
20776                        }
20777                    }
20778                    app.trimMemoryLevel = curLevel;
20779                    step++;
20780                    if (step >= factor) {
20781                        step = 0;
20782                        switch (curLevel) {
20783                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20784                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20785                                break;
20786                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20787                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20788                                break;
20789                        }
20790                    }
20791                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20792                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20793                            && app.thread != null) {
20794                        try {
20795                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20796                                    "Trimming memory of heavy-weight " + app.processName
20797                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20798                            app.thread.scheduleTrimMemory(
20799                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20800                        } catch (RemoteException e) {
20801                        }
20802                    }
20803                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20804                } else {
20805                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20806                            || app.systemNoUi) && app.pendingUiClean) {
20807                        // If this application is now in the background and it
20808                        // had done UI, then give it the special trim level to
20809                        // have it free UI resources.
20810                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20811                        if (app.trimMemoryLevel < level && app.thread != null) {
20812                            try {
20813                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20814                                        "Trimming memory of bg-ui " + app.processName
20815                                        + " to " + level);
20816                                app.thread.scheduleTrimMemory(level);
20817                            } catch (RemoteException e) {
20818                            }
20819                        }
20820                        app.pendingUiClean = false;
20821                    }
20822                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20823                        try {
20824                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20825                                    "Trimming memory of fg " + app.processName
20826                                    + " to " + fgTrimLevel);
20827                            app.thread.scheduleTrimMemory(fgTrimLevel);
20828                        } catch (RemoteException e) {
20829                        }
20830                    }
20831                    app.trimMemoryLevel = fgTrimLevel;
20832                }
20833            }
20834        } else {
20835            if (mLowRamStartTime != 0) {
20836                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20837                mLowRamStartTime = 0;
20838            }
20839            for (int i=N-1; i>=0; i--) {
20840                ProcessRecord app = mLruProcesses.get(i);
20841                if (allChanged || app.procStateChanged) {
20842                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20843                    app.procStateChanged = false;
20844                }
20845                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20846                        || app.systemNoUi) && app.pendingUiClean) {
20847                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20848                            && app.thread != null) {
20849                        try {
20850                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20851                                    "Trimming memory of ui hidden " + app.processName
20852                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20853                            app.thread.scheduleTrimMemory(
20854                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20855                        } catch (RemoteException e) {
20856                        }
20857                    }
20858                    app.pendingUiClean = false;
20859                }
20860                app.trimMemoryLevel = 0;
20861            }
20862        }
20863
20864        if (mAlwaysFinishActivities) {
20865            // Need to do this on its own message because the stack may not
20866            // be in a consistent state at this point.
20867            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20868        }
20869
20870        if (allChanged) {
20871            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20872        }
20873
20874        // Update from any uid changes.
20875        for (int i=mActiveUids.size()-1; i>=0; i--) {
20876            final UidRecord uidRec = mActiveUids.valueAt(i);
20877            int uidChange = UidRecord.CHANGE_PROCSTATE;
20878            if (uidRec.setProcState != uidRec.curProcState) {
20879                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20880                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20881                        + " to " + uidRec.curProcState);
20882                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20883                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20884                        uidRec.lastBackgroundTime = nowElapsed;
20885                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20886                            // Note: the background settle time is in elapsed realtime, while
20887                            // the handler time base is uptime.  All this means is that we may
20888                            // stop background uids later than we had intended, but that only
20889                            // happens because the device was sleeping so we are okay anyway.
20890                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20891                        }
20892                    }
20893                } else {
20894                    if (uidRec.idle) {
20895                        uidChange = UidRecord.CHANGE_ACTIVE;
20896                        uidRec.idle = false;
20897                    }
20898                    uidRec.lastBackgroundTime = 0;
20899                }
20900                uidRec.setProcState = uidRec.curProcState;
20901                enqueueUidChangeLocked(uidRec, -1, uidChange);
20902                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20903            }
20904        }
20905
20906        if (mProcessStats.shouldWriteNowLocked(now)) {
20907            mHandler.post(new Runnable() {
20908                @Override public void run() {
20909                    synchronized (ActivityManagerService.this) {
20910                        mProcessStats.writeStateAsyncLocked();
20911                    }
20912                }
20913            });
20914        }
20915
20916        if (DEBUG_OOM_ADJ) {
20917            final long duration = SystemClock.uptimeMillis() - now;
20918            if (false) {
20919                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20920                        new RuntimeException("here").fillInStackTrace());
20921            } else {
20922                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20923            }
20924        }
20925    }
20926
20927    final void idleUids() {
20928        synchronized (this) {
20929            final long nowElapsed = SystemClock.elapsedRealtime();
20930            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20931            long nextTime = 0;
20932            for (int i=mActiveUids.size()-1; i>=0; i--) {
20933                final UidRecord uidRec = mActiveUids.valueAt(i);
20934                final long bgTime = uidRec.lastBackgroundTime;
20935                if (bgTime > 0 && !uidRec.idle) {
20936                    if (bgTime <= maxBgTime) {
20937                        uidRec.idle = true;
20938                        doStopUidLocked(uidRec.uid, uidRec);
20939                    } else {
20940                        if (nextTime == 0 || nextTime > bgTime) {
20941                            nextTime = bgTime;
20942                        }
20943                    }
20944                }
20945            }
20946            if (nextTime > 0) {
20947                mHandler.removeMessages(IDLE_UIDS_MSG);
20948                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20949                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20950            }
20951        }
20952    }
20953
20954    final void runInBackgroundDisabled(int uid) {
20955        synchronized (this) {
20956            UidRecord uidRec = mActiveUids.get(uid);
20957            if (uidRec != null) {
20958                // This uid is actually running...  should it be considered background now?
20959                if (uidRec.idle) {
20960                    doStopUidLocked(uidRec.uid, uidRec);
20961                }
20962            } else {
20963                // This uid isn't actually running...  still send a report about it being "stopped".
20964                doStopUidLocked(uid, null);
20965            }
20966        }
20967    }
20968
20969    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20970        mServices.stopInBackgroundLocked(uid);
20971        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20972    }
20973
20974    final void trimApplications() {
20975        synchronized (this) {
20976            int i;
20977
20978            // First remove any unused application processes whose package
20979            // has been removed.
20980            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20981                final ProcessRecord app = mRemovedProcesses.get(i);
20982                if (app.activities.size() == 0
20983                        && app.curReceiver == null && app.services.size() == 0) {
20984                    Slog.i(
20985                        TAG, "Exiting empty application process "
20986                        + app.toShortString() + " ("
20987                        + (app.thread != null ? app.thread.asBinder() : null)
20988                        + ")\n");
20989                    if (app.pid > 0 && app.pid != MY_PID) {
20990                        app.kill("empty", false);
20991                    } else {
20992                        try {
20993                            app.thread.scheduleExit();
20994                        } catch (Exception e) {
20995                            // Ignore exceptions.
20996                        }
20997                    }
20998                    cleanUpApplicationRecordLocked(app, false, true, -1);
20999                    mRemovedProcesses.remove(i);
21000
21001                    if (app.persistent) {
21002                        addAppLocked(app.info, false, null /* ABI override */);
21003                    }
21004                }
21005            }
21006
21007            // Now update the oom adj for all processes.
21008            updateOomAdjLocked();
21009        }
21010    }
21011
21012    /** This method sends the specified signal to each of the persistent apps */
21013    public void signalPersistentProcesses(int sig) throws RemoteException {
21014        if (sig != Process.SIGNAL_USR1) {
21015            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21016        }
21017
21018        synchronized (this) {
21019            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21020                    != PackageManager.PERMISSION_GRANTED) {
21021                throw new SecurityException("Requires permission "
21022                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21023            }
21024
21025            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21026                ProcessRecord r = mLruProcesses.get(i);
21027                if (r.thread != null && r.persistent) {
21028                    Process.sendSignal(r.pid, sig);
21029                }
21030            }
21031        }
21032    }
21033
21034    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21035        if (proc == null || proc == mProfileProc) {
21036            proc = mProfileProc;
21037            profileType = mProfileType;
21038            clearProfilerLocked();
21039        }
21040        if (proc == null) {
21041            return;
21042        }
21043        try {
21044            proc.thread.profilerControl(false, null, profileType);
21045        } catch (RemoteException e) {
21046            throw new IllegalStateException("Process disappeared");
21047        }
21048    }
21049
21050    private void clearProfilerLocked() {
21051        if (mProfileFd != null) {
21052            try {
21053                mProfileFd.close();
21054            } catch (IOException e) {
21055            }
21056        }
21057        mProfileApp = null;
21058        mProfileProc = null;
21059        mProfileFile = null;
21060        mProfileType = 0;
21061        mAutoStopProfiler = false;
21062        mSamplingInterval = 0;
21063    }
21064
21065    public boolean profileControl(String process, int userId, boolean start,
21066            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21067
21068        try {
21069            synchronized (this) {
21070                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21071                // its own permission.
21072                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21073                        != PackageManager.PERMISSION_GRANTED) {
21074                    throw new SecurityException("Requires permission "
21075                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21076                }
21077
21078                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21079                    throw new IllegalArgumentException("null profile info or fd");
21080                }
21081
21082                ProcessRecord proc = null;
21083                if (process != null) {
21084                    proc = findProcessLocked(process, userId, "profileControl");
21085                }
21086
21087                if (start && (proc == null || proc.thread == null)) {
21088                    throw new IllegalArgumentException("Unknown process: " + process);
21089                }
21090
21091                if (start) {
21092                    stopProfilerLocked(null, 0);
21093                    setProfileApp(proc.info, proc.processName, profilerInfo);
21094                    mProfileProc = proc;
21095                    mProfileType = profileType;
21096                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21097                    try {
21098                        fd = fd.dup();
21099                    } catch (IOException e) {
21100                        fd = null;
21101                    }
21102                    profilerInfo.profileFd = fd;
21103                    proc.thread.profilerControl(start, profilerInfo, profileType);
21104                    fd = null;
21105                    mProfileFd = null;
21106                } else {
21107                    stopProfilerLocked(proc, profileType);
21108                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21109                        try {
21110                            profilerInfo.profileFd.close();
21111                        } catch (IOException e) {
21112                        }
21113                    }
21114                }
21115
21116                return true;
21117            }
21118        } catch (RemoteException e) {
21119            throw new IllegalStateException("Process disappeared");
21120        } finally {
21121            if (profilerInfo != null && profilerInfo.profileFd != null) {
21122                try {
21123                    profilerInfo.profileFd.close();
21124                } catch (IOException e) {
21125                }
21126            }
21127        }
21128    }
21129
21130    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21131        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21132                userId, true, ALLOW_FULL_ONLY, callName, null);
21133        ProcessRecord proc = null;
21134        try {
21135            int pid = Integer.parseInt(process);
21136            synchronized (mPidsSelfLocked) {
21137                proc = mPidsSelfLocked.get(pid);
21138            }
21139        } catch (NumberFormatException e) {
21140        }
21141
21142        if (proc == null) {
21143            ArrayMap<String, SparseArray<ProcessRecord>> all
21144                    = mProcessNames.getMap();
21145            SparseArray<ProcessRecord> procs = all.get(process);
21146            if (procs != null && procs.size() > 0) {
21147                proc = procs.valueAt(0);
21148                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21149                    for (int i=1; i<procs.size(); i++) {
21150                        ProcessRecord thisProc = procs.valueAt(i);
21151                        if (thisProc.userId == userId) {
21152                            proc = thisProc;
21153                            break;
21154                        }
21155                    }
21156                }
21157            }
21158        }
21159
21160        return proc;
21161    }
21162
21163    public boolean dumpHeap(String process, int userId, boolean managed,
21164            String path, ParcelFileDescriptor fd) throws RemoteException {
21165
21166        try {
21167            synchronized (this) {
21168                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21169                // its own permission (same as profileControl).
21170                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21171                        != PackageManager.PERMISSION_GRANTED) {
21172                    throw new SecurityException("Requires permission "
21173                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21174                }
21175
21176                if (fd == null) {
21177                    throw new IllegalArgumentException("null fd");
21178                }
21179
21180                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21181                if (proc == null || proc.thread == null) {
21182                    throw new IllegalArgumentException("Unknown process: " + process);
21183                }
21184
21185                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21186                if (!isDebuggable) {
21187                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21188                        throw new SecurityException("Process not debuggable: " + proc);
21189                    }
21190                }
21191
21192                proc.thread.dumpHeap(managed, path, fd);
21193                fd = null;
21194                return true;
21195            }
21196        } catch (RemoteException e) {
21197            throw new IllegalStateException("Process disappeared");
21198        } finally {
21199            if (fd != null) {
21200                try {
21201                    fd.close();
21202                } catch (IOException e) {
21203                }
21204            }
21205        }
21206    }
21207
21208    @Override
21209    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21210            String reportPackage) {
21211        if (processName != null) {
21212            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21213                    "setDumpHeapDebugLimit()");
21214        } else {
21215            synchronized (mPidsSelfLocked) {
21216                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21217                if (proc == null) {
21218                    throw new SecurityException("No process found for calling pid "
21219                            + Binder.getCallingPid());
21220                }
21221                if (!Build.IS_DEBUGGABLE
21222                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21223                    throw new SecurityException("Not running a debuggable build");
21224                }
21225                processName = proc.processName;
21226                uid = proc.uid;
21227                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21228                    throw new SecurityException("Package " + reportPackage + " is not running in "
21229                            + proc);
21230                }
21231            }
21232        }
21233        synchronized (this) {
21234            if (maxMemSize > 0) {
21235                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21236            } else {
21237                if (uid != 0) {
21238                    mMemWatchProcesses.remove(processName, uid);
21239                } else {
21240                    mMemWatchProcesses.getMap().remove(processName);
21241                }
21242            }
21243        }
21244    }
21245
21246    @Override
21247    public void dumpHeapFinished(String path) {
21248        synchronized (this) {
21249            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21250                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21251                        + " does not match last pid " + mMemWatchDumpPid);
21252                return;
21253            }
21254            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21255                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21256                        + " does not match last path " + mMemWatchDumpFile);
21257                return;
21258            }
21259            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21260            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21261        }
21262    }
21263
21264    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21265    public void monitor() {
21266        synchronized (this) { }
21267    }
21268
21269    void onCoreSettingsChange(Bundle settings) {
21270        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21271            ProcessRecord processRecord = mLruProcesses.get(i);
21272            try {
21273                if (processRecord.thread != null) {
21274                    processRecord.thread.setCoreSettings(settings);
21275                }
21276            } catch (RemoteException re) {
21277                /* ignore */
21278            }
21279        }
21280    }
21281
21282    // Multi-user methods
21283
21284    /**
21285     * Start user, if its not already running, but don't bring it to foreground.
21286     */
21287    @Override
21288    public boolean startUserInBackground(final int userId) {
21289        return mUserController.startUser(userId, /* foreground */ false);
21290    }
21291
21292    @Override
21293    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21294        return mUserController.unlockUser(userId, token, secret, listener);
21295    }
21296
21297    @Override
21298    public boolean switchUser(final int targetUserId) {
21299        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21300        UserInfo currentUserInfo;
21301        UserInfo targetUserInfo;
21302        synchronized (this) {
21303            int currentUserId = mUserController.getCurrentUserIdLocked();
21304            currentUserInfo = mUserController.getUserInfo(currentUserId);
21305            targetUserInfo = mUserController.getUserInfo(targetUserId);
21306            if (targetUserInfo == null) {
21307                Slog.w(TAG, "No user info for user #" + targetUserId);
21308                return false;
21309            }
21310            if (!targetUserInfo.supportsSwitchTo()) {
21311                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21312                return false;
21313            }
21314            if (targetUserInfo.isManagedProfile()) {
21315                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21316                return false;
21317            }
21318            mUserController.setTargetUserIdLocked(targetUserId);
21319        }
21320        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21321        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21322        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21323        return true;
21324    }
21325
21326    void scheduleStartProfilesLocked() {
21327        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21328            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21329                    DateUtils.SECOND_IN_MILLIS);
21330        }
21331    }
21332
21333    @Override
21334    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21335        return mUserController.stopUser(userId, force, callback);
21336    }
21337
21338    @Override
21339    public UserInfo getCurrentUser() {
21340        return mUserController.getCurrentUser();
21341    }
21342
21343    @Override
21344    public boolean isUserRunning(int userId, int flags) {
21345        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21346                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21347            String msg = "Permission Denial: isUserRunning() from pid="
21348                    + Binder.getCallingPid()
21349                    + ", uid=" + Binder.getCallingUid()
21350                    + " requires " + INTERACT_ACROSS_USERS;
21351            Slog.w(TAG, msg);
21352            throw new SecurityException(msg);
21353        }
21354        synchronized (this) {
21355            return mUserController.isUserRunningLocked(userId, flags);
21356        }
21357    }
21358
21359    @Override
21360    public int[] getRunningUserIds() {
21361        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21362                != PackageManager.PERMISSION_GRANTED) {
21363            String msg = "Permission Denial: isUserRunning() from pid="
21364                    + Binder.getCallingPid()
21365                    + ", uid=" + Binder.getCallingUid()
21366                    + " requires " + INTERACT_ACROSS_USERS;
21367            Slog.w(TAG, msg);
21368            throw new SecurityException(msg);
21369        }
21370        synchronized (this) {
21371            return mUserController.getStartedUserArrayLocked();
21372        }
21373    }
21374
21375    @Override
21376    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21377        mUserController.registerUserSwitchObserver(observer);
21378    }
21379
21380    @Override
21381    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21382        mUserController.unregisterUserSwitchObserver(observer);
21383    }
21384
21385    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21386        if (info == null) return null;
21387        ApplicationInfo newInfo = new ApplicationInfo(info);
21388        newInfo.initForUser(userId);
21389        return newInfo;
21390    }
21391
21392    public boolean isUserStopped(int userId) {
21393        synchronized (this) {
21394            return mUserController.getStartedUserStateLocked(userId) == null;
21395        }
21396    }
21397
21398    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21399        if (aInfo == null
21400                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21401            return aInfo;
21402        }
21403
21404        ActivityInfo info = new ActivityInfo(aInfo);
21405        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21406        return info;
21407    }
21408
21409    private boolean processSanityChecksLocked(ProcessRecord process) {
21410        if (process == null || process.thread == null) {
21411            return false;
21412        }
21413
21414        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21415        if (!isDebuggable) {
21416            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21417                return false;
21418            }
21419        }
21420
21421        return true;
21422    }
21423
21424    public boolean startBinderTracking() throws RemoteException {
21425        synchronized (this) {
21426            mBinderTransactionTrackingEnabled = true;
21427            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21428            // permission (same as profileControl).
21429            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21430                    != PackageManager.PERMISSION_GRANTED) {
21431                throw new SecurityException("Requires permission "
21432                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21433            }
21434
21435            for (int i = 0; i < mLruProcesses.size(); i++) {
21436                ProcessRecord process = mLruProcesses.get(i);
21437                if (!processSanityChecksLocked(process)) {
21438                    continue;
21439                }
21440                try {
21441                    process.thread.startBinderTracking();
21442                } catch (RemoteException e) {
21443                    Log.v(TAG, "Process disappared");
21444                }
21445            }
21446            return true;
21447        }
21448    }
21449
21450    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21451        try {
21452            synchronized (this) {
21453                mBinderTransactionTrackingEnabled = false;
21454                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21455                // permission (same as profileControl).
21456                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21457                        != PackageManager.PERMISSION_GRANTED) {
21458                    throw new SecurityException("Requires permission "
21459                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21460                }
21461
21462                if (fd == null) {
21463                    throw new IllegalArgumentException("null fd");
21464                }
21465
21466                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21467                pw.println("Binder transaction traces for all processes.\n");
21468                for (ProcessRecord process : mLruProcesses) {
21469                    if (!processSanityChecksLocked(process)) {
21470                        continue;
21471                    }
21472
21473                    pw.println("Traces for process: " + process.processName);
21474                    pw.flush();
21475                    try {
21476                        TransferPipe tp = new TransferPipe();
21477                        try {
21478                            process.thread.stopBinderTrackingAndDump(
21479                                    tp.getWriteFd().getFileDescriptor());
21480                            tp.go(fd.getFileDescriptor());
21481                        } finally {
21482                            tp.kill();
21483                        }
21484                    } catch (IOException e) {
21485                        pw.println("Failure while dumping IPC traces from " + process +
21486                                ".  Exception: " + e);
21487                        pw.flush();
21488                    } catch (RemoteException e) {
21489                        pw.println("Got a RemoteException while dumping IPC traces from " +
21490                                process + ".  Exception: " + e);
21491                        pw.flush();
21492                    }
21493                }
21494                fd = null;
21495                return true;
21496            }
21497        } finally {
21498            if (fd != null) {
21499                try {
21500                    fd.close();
21501                } catch (IOException e) {
21502                }
21503            }
21504        }
21505    }
21506
21507    private final class LocalService extends ActivityManagerInternal {
21508        @Override
21509        public void onWakefulnessChanged(int wakefulness) {
21510            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21511        }
21512
21513        @Override
21514        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21515                String processName, String abiOverride, int uid, Runnable crashHandler) {
21516            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21517                    processName, abiOverride, uid, crashHandler);
21518        }
21519
21520        @Override
21521        public SleepToken acquireSleepToken(String tag) {
21522            Preconditions.checkNotNull(tag);
21523
21524            ComponentName requestedVrService = null;
21525            ComponentName callingVrActivity = null;
21526            int userId = -1;
21527            synchronized (ActivityManagerService.this) {
21528                if (mFocusedActivity != null) {
21529                    requestedVrService = mFocusedActivity.requestedVrComponent;
21530                    callingVrActivity = mFocusedActivity.info.getComponentName();
21531                    userId = mFocusedActivity.userId;
21532                }
21533            }
21534
21535            if (requestedVrService != null) {
21536                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21537            }
21538
21539            synchronized (ActivityManagerService.this) {
21540                SleepTokenImpl token = new SleepTokenImpl(tag);
21541                mSleepTokens.add(token);
21542                updateSleepIfNeededLocked();
21543                return token;
21544            }
21545        }
21546
21547        @Override
21548        public ComponentName getHomeActivityForUser(int userId) {
21549            synchronized (ActivityManagerService.this) {
21550                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21551                return homeActivity == null ? null : homeActivity.realActivity;
21552            }
21553        }
21554
21555        @Override
21556        public void onUserRemoved(int userId) {
21557            synchronized (ActivityManagerService.this) {
21558                ActivityManagerService.this.onUserStoppedLocked(userId);
21559            }
21560        }
21561
21562        @Override
21563        public void onLocalVoiceInteractionStarted(IBinder activity,
21564                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21565            synchronized (ActivityManagerService.this) {
21566                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21567                        voiceSession, voiceInteractor);
21568            }
21569        }
21570
21571        @Override
21572        public void notifyStartingWindowDrawn() {
21573            synchronized (ActivityManagerService.this) {
21574                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21575            }
21576        }
21577
21578        @Override
21579        public void notifyAppTransitionStarting(int reason) {
21580            synchronized (ActivityManagerService.this) {
21581                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21582            }
21583        }
21584
21585        @Override
21586        public void notifyAppTransitionFinished() {
21587            synchronized (ActivityManagerService.this) {
21588                mStackSupervisor.notifyAppTransitionDone();
21589            }
21590        }
21591
21592        @Override
21593        public void notifyAppTransitionCancelled() {
21594            synchronized (ActivityManagerService.this) {
21595                mStackSupervisor.notifyAppTransitionDone();
21596            }
21597        }
21598
21599        @Override
21600        public List<IBinder> getTopVisibleActivities() {
21601            synchronized (ActivityManagerService.this) {
21602                return mStackSupervisor.getTopVisibleActivities();
21603            }
21604        }
21605
21606        @Override
21607        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21608            synchronized (ActivityManagerService.this) {
21609                mStackSupervisor.setDockedStackMinimized(minimized);
21610            }
21611        }
21612
21613        @Override
21614        public void killForegroundAppsForUser(int userHandle) {
21615            synchronized (ActivityManagerService.this) {
21616                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21617                final int NP = mProcessNames.getMap().size();
21618                for (int ip = 0; ip < NP; ip++) {
21619                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21620                    final int NA = apps.size();
21621                    for (int ia = 0; ia < NA; ia++) {
21622                        final ProcessRecord app = apps.valueAt(ia);
21623                        if (app.persistent) {
21624                            // We don't kill persistent processes.
21625                            continue;
21626                        }
21627                        if (app.removed) {
21628                            procs.add(app);
21629                        } else if (app.userId == userHandle && app.foregroundActivities) {
21630                            app.removed = true;
21631                            procs.add(app);
21632                        }
21633                    }
21634                }
21635
21636                final int N = procs.size();
21637                for (int i = 0; i < N; i++) {
21638                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21639                }
21640            }
21641        }
21642
21643        @Override
21644        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21645            if (!(target instanceof PendingIntentRecord)) {
21646                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21647                return;
21648            }
21649            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21650        }
21651    }
21652
21653    private final class SleepTokenImpl extends SleepToken {
21654        private final String mTag;
21655        private final long mAcquireTime;
21656
21657        public SleepTokenImpl(String tag) {
21658            mTag = tag;
21659            mAcquireTime = SystemClock.uptimeMillis();
21660        }
21661
21662        @Override
21663        public void release() {
21664            synchronized (ActivityManagerService.this) {
21665                if (mSleepTokens.remove(this)) {
21666                    updateSleepIfNeededLocked();
21667                }
21668            }
21669        }
21670
21671        @Override
21672        public String toString() {
21673            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21674        }
21675    }
21676
21677    /**
21678     * An implementation of IAppTask, that allows an app to manage its own tasks via
21679     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21680     * only the process that calls getAppTasks() can call the AppTask methods.
21681     */
21682    class AppTaskImpl extends IAppTask.Stub {
21683        private int mTaskId;
21684        private int mCallingUid;
21685
21686        public AppTaskImpl(int taskId, int callingUid) {
21687            mTaskId = taskId;
21688            mCallingUid = callingUid;
21689        }
21690
21691        private void checkCaller() {
21692            if (mCallingUid != Binder.getCallingUid()) {
21693                throw new SecurityException("Caller " + mCallingUid
21694                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21695            }
21696        }
21697
21698        @Override
21699        public void finishAndRemoveTask() {
21700            checkCaller();
21701
21702            synchronized (ActivityManagerService.this) {
21703                long origId = Binder.clearCallingIdentity();
21704                try {
21705                    // We remove the task from recents to preserve backwards
21706                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21707                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21708                    }
21709                } finally {
21710                    Binder.restoreCallingIdentity(origId);
21711                }
21712            }
21713        }
21714
21715        @Override
21716        public ActivityManager.RecentTaskInfo getTaskInfo() {
21717            checkCaller();
21718
21719            synchronized (ActivityManagerService.this) {
21720                long origId = Binder.clearCallingIdentity();
21721                try {
21722                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21723                    if (tr == null) {
21724                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21725                    }
21726                    return createRecentTaskInfoFromTaskRecord(tr);
21727                } finally {
21728                    Binder.restoreCallingIdentity(origId);
21729                }
21730            }
21731        }
21732
21733        @Override
21734        public void moveToFront() {
21735            checkCaller();
21736            // Will bring task to front if it already has a root activity.
21737            final long origId = Binder.clearCallingIdentity();
21738            try {
21739                synchronized (this) {
21740                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21741                }
21742            } finally {
21743                Binder.restoreCallingIdentity(origId);
21744            }
21745        }
21746
21747        @Override
21748        public int startActivity(IBinder whoThread, String callingPackage,
21749                Intent intent, String resolvedType, Bundle bOptions) {
21750            checkCaller();
21751
21752            int callingUser = UserHandle.getCallingUserId();
21753            TaskRecord tr;
21754            IApplicationThread appThread;
21755            synchronized (ActivityManagerService.this) {
21756                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21757                if (tr == null) {
21758                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21759                }
21760                appThread = ApplicationThreadNative.asInterface(whoThread);
21761                if (appThread == null) {
21762                    throw new IllegalArgumentException("Bad app thread " + appThread);
21763                }
21764            }
21765            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21766                    resolvedType, null, null, null, null, 0, 0, null, null,
21767                    null, bOptions, false, callingUser, null, tr);
21768        }
21769
21770        @Override
21771        public void setExcludeFromRecents(boolean exclude) {
21772            checkCaller();
21773
21774            synchronized (ActivityManagerService.this) {
21775                long origId = Binder.clearCallingIdentity();
21776                try {
21777                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21778                    if (tr == null) {
21779                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21780                    }
21781                    Intent intent = tr.getBaseIntent();
21782                    if (exclude) {
21783                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21784                    } else {
21785                        intent.setFlags(intent.getFlags()
21786                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21787                    }
21788                } finally {
21789                    Binder.restoreCallingIdentity(origId);
21790                }
21791            }
21792        }
21793    }
21794
21795    /**
21796     * Kill processes for the user with id userId and that depend on the package named packageName
21797     */
21798    @Override
21799    public void killPackageDependents(String packageName, int userId) {
21800        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21801        if (packageName == null) {
21802            throw new NullPointerException(
21803                    "Cannot kill the dependents of a package without its name.");
21804        }
21805
21806        long callingId = Binder.clearCallingIdentity();
21807        IPackageManager pm = AppGlobals.getPackageManager();
21808        int pkgUid = -1;
21809        try {
21810            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21811        } catch (RemoteException e) {
21812        }
21813        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21814            throw new IllegalArgumentException(
21815                    "Cannot kill dependents of non-existing package " + packageName);
21816        }
21817        try {
21818            synchronized(this) {
21819                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21820                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21821                        "dep: " + packageName);
21822            }
21823        } finally {
21824            Binder.restoreCallingIdentity(callingId);
21825        }
21826    }
21827}
21828