ActivityManagerService.java revision 0d1fd8d09163566d2c7eb72037f63b6404ada642
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 android.annotation.Nullable;
20import android.app.ApplicationThreadConstants;
21import android.app.ContentProviderHolder;
22import android.app.IActivityManager;
23import android.app.WaitResult;
24import android.os.IDeviceIdentifiersPolicyService;
25
26import com.android.internal.policy.IKeyguardDismissCallback;
27import com.android.internal.telephony.TelephonyIntents;
28import com.google.android.collect.Lists;
29import com.google.android.collect.Maps;
30import com.android.internal.R;
31import com.android.internal.annotations.GuardedBy;
32import com.android.internal.app.AssistUtils;
33import com.android.internal.app.DumpHeapActivity;
34import com.android.internal.app.IAppOpsCallback;
35import com.android.internal.app.IAppOpsService;
36import com.android.internal.app.IVoiceInteractor;
37import com.android.internal.app.ProcessMap;
38import com.android.internal.app.SystemUserHomeActivity;
39import com.android.internal.app.procstats.ProcessStats;
40import com.android.internal.os.BackgroundThread;
41import com.android.internal.os.BatteryStatsImpl;
42import com.android.internal.os.IResultReceiver;
43import com.android.internal.os.ProcessCpuTracker;
44import com.android.internal.os.TransferPipe;
45import com.android.internal.os.Zygote;
46import com.android.internal.os.InstallerConnection.InstallerException;
47import com.android.internal.util.ArrayUtils;
48import com.android.internal.util.FastPrintWriter;
49import com.android.internal.util.FastXmlSerializer;
50import com.android.internal.util.MemInfoReader;
51import com.android.internal.util.Preconditions;
52import com.android.server.AppOpsService;
53import com.android.server.AttributeCache;
54import com.android.server.DeviceIdleController;
55import com.android.server.IntentResolver;
56import com.android.server.LocalServices;
57import com.android.server.LockGuard;
58import com.android.server.ServiceThread;
59import com.android.server.SystemService;
60import com.android.server.SystemServiceManager;
61import com.android.server.Watchdog;
62import com.android.server.am.ActivityStack.ActivityState;
63import com.android.server.firewall.IntentFirewall;
64import com.android.server.pm.Installer;
65import com.android.server.statusbar.StatusBarManagerInternal;
66import com.android.server.vr.VrManagerInternal;
67import com.android.server.wm.WindowManagerService;
68
69import org.xmlpull.v1.XmlPullParser;
70import org.xmlpull.v1.XmlPullParserException;
71import org.xmlpull.v1.XmlSerializer;
72
73import android.Manifest;
74import android.Manifest.permission;
75import android.annotation.NonNull;
76import android.annotation.UserIdInt;
77import android.app.Activity;
78import android.app.ActivityManager;
79import android.app.ActivityManager.RunningTaskInfo;
80import android.app.ActivityManager.StackId;
81import android.app.ActivityManager.StackInfo;
82import android.app.ActivityManager.TaskThumbnailInfo;
83import android.app.ActivityManagerInternal;
84import android.app.ActivityManagerInternal.SleepToken;
85import android.app.ActivityOptions;
86import android.app.ActivityThread;
87import android.app.AlertDialog;
88import android.app.AppGlobals;
89import android.app.AppOpsManager;
90import android.app.ApplicationErrorReport;
91import android.app.BroadcastOptions;
92import android.app.Dialog;
93import android.app.IActivityContainer;
94import android.app.IActivityContainerCallback;
95import android.app.IActivityController;
96import android.app.IAppTask;
97import android.app.IApplicationThread;
98import android.app.IInstrumentationWatcher;
99import android.app.INotificationManager;
100import android.app.IProcessObserver;
101import android.app.IServiceConnection;
102import android.app.IStopUserCallback;
103import android.app.ITaskStackListener;
104import android.app.IUiAutomationConnection;
105import android.app.IUidObserver;
106import android.app.IUserSwitchObserver;
107import android.app.Instrumentation;
108import android.app.Notification;
109import android.app.NotificationManager;
110import android.app.PendingIntent;
111import android.app.ProfilerInfo;
112import android.app.admin.DevicePolicyManager;
113import android.app.assist.AssistContent;
114import android.app.assist.AssistStructure;
115import android.app.backup.IBackupManager;
116import android.app.usage.UsageEvents;
117import android.app.usage.UsageStatsManagerInternal;
118import android.appwidget.AppWidgetManager;
119import android.content.ActivityNotFoundException;
120import android.content.BroadcastReceiver;
121import android.content.ClipData;
122import android.content.ComponentCallbacks2;
123import android.content.ComponentName;
124import android.content.ContentProvider;
125import android.content.ContentResolver;
126import android.content.Context;
127import android.content.DialogInterface;
128import android.content.IContentProvider;
129import android.content.IIntentReceiver;
130import android.content.IIntentSender;
131import android.content.Intent;
132import android.content.IntentFilter;
133import android.content.IntentSender;
134import android.content.pm.ActivityInfo;
135import android.content.pm.ApplicationInfo;
136import android.content.pm.ConfigurationInfo;
137import android.content.pm.IPackageDataObserver;
138import android.content.pm.IPackageManager;
139import android.content.pm.InstrumentationInfo;
140import android.content.pm.PackageInfo;
141import android.content.pm.PackageManager;
142import android.content.pm.PackageManager.NameNotFoundException;
143import android.content.pm.PackageManagerInternal;
144import android.content.pm.ParceledListSlice;
145import android.content.pm.PathPermission;
146import android.content.pm.PermissionInfo;
147import android.content.pm.ProviderInfo;
148import android.content.pm.ResolveInfo;
149import android.content.pm.ServiceInfo;
150import android.content.pm.UserInfo;
151import android.content.res.CompatibilityInfo;
152import android.content.res.Configuration;
153import android.content.res.Resources;
154import android.database.ContentObserver;
155import android.graphics.Bitmap;
156import android.graphics.Point;
157import android.graphics.Rect;
158import android.location.LocationManager;
159import android.net.Proxy;
160import android.net.ProxyInfo;
161import android.net.Uri;
162import android.os.BatteryStats;
163import android.os.Binder;
164import android.os.Build;
165import android.os.Bundle;
166import android.os.Debug;
167import android.os.DropBoxManager;
168import android.os.Environment;
169import android.os.FactoryTest;
170import android.os.FileObserver;
171import android.os.FileUtils;
172import android.os.Handler;
173import android.os.IBinder;
174import android.os.IPermissionController;
175import android.os.IProcessInfoService;
176import android.os.IProgressListener;
177import android.os.LocaleList;
178import android.os.Looper;
179import android.os.Message;
180import android.os.Parcel;
181import android.os.ParcelFileDescriptor;
182import android.os.PersistableBundle;
183import android.os.PowerManager;
184import android.os.PowerManagerInternal;
185import android.os.Process;
186import android.os.RemoteCallbackList;
187import android.os.RemoteException;
188import android.os.ResultReceiver;
189import android.os.ServiceManager;
190import android.os.ShellCallback;
191import android.os.StrictMode;
192import android.os.SystemClock;
193import android.os.SystemProperties;
194import android.os.Trace;
195import android.os.TransactionTooLargeException;
196import android.os.UpdateLock;
197import android.os.UserHandle;
198import android.os.UserManager;
199import android.os.WorkSource;
200import android.os.storage.IStorageManager;
201import android.os.storage.StorageManagerInternal;
202import android.os.storage.StorageManager;
203import android.provider.Settings;
204import android.service.voice.IVoiceInteractionSession;
205import android.service.voice.VoiceInteractionManagerInternal;
206import android.service.voice.VoiceInteractionSession;
207import android.telecom.TelecomManager;
208import android.text.format.DateUtils;
209import android.text.format.Time;
210import android.text.style.SuggestionSpan;
211import android.util.ArrayMap;
212import android.util.ArraySet;
213import android.util.AtomicFile;
214import android.util.DebugUtils;
215import android.util.DisplayMetrics;
216import android.util.EventLog;
217import android.util.Log;
218import android.util.Pair;
219import android.util.PrintWriterPrinter;
220import android.util.Slog;
221import android.util.SparseArray;
222import android.util.SparseIntArray;
223import android.util.TimeUtils;
224import android.util.Xml;
225import android.view.Gravity;
226import android.view.LayoutInflater;
227import android.view.View;
228import android.view.WindowManager;
229
230import java.io.File;
231import java.io.FileDescriptor;
232import java.io.FileInputStream;
233import java.io.FileNotFoundException;
234import java.io.FileOutputStream;
235import java.io.IOException;
236import java.io.InputStreamReader;
237import java.io.PrintWriter;
238import java.io.StringWriter;
239import java.lang.ref.WeakReference;
240import java.nio.charset.StandardCharsets;
241import java.util.ArrayList;
242import java.util.Arrays;
243import java.util.Collections;
244import java.util.Comparator;
245import java.util.HashMap;
246import java.util.HashSet;
247import java.util.Iterator;
248import java.util.List;
249import java.util.Locale;
250import java.util.Map;
251import java.util.Objects;
252import java.util.Set;
253import java.util.concurrent.atomic.AtomicBoolean;
254import java.util.concurrent.atomic.AtomicLong;
255
256import dalvik.system.VMRuntime;
257
258import libcore.io.IoUtils;
259import libcore.util.EmptyArray;
260
261import static android.Manifest.permission.CHANGE_CONFIGURATION;
262import static android.Manifest.permission.INTERACT_ACROSS_USERS;
263import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
264import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
265import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
266import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
267import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
268import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
269import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
270import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
271import static android.app.ActivityManager.StackId.HOME_STACK_ID;
272import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
273import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
274import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
275import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
276import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
277import static android.content.pm.PackageManager.GET_PROVIDERS;
278import static android.content.pm.PackageManager.MATCH_ANY_USER;
279import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
280import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
281import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
282import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
283import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
284import static android.content.pm.PackageManager.PERMISSION_GRANTED;
285import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
286import static android.os.Build.VERSION_CODES.N;
287import static android.os.Process.PROC_CHAR;
288import static android.os.Process.PROC_OUT_LONG;
289import static android.os.Process.PROC_PARENS;
290import static android.os.Process.PROC_SPACE_TERM;
291import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
292import static android.provider.Settings.Global.DEBUG_APP;
293import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
294import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
295import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
296import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
297import static android.provider.Settings.System.FONT_SCALE;
298import static android.view.Display.DEFAULT_DISPLAY;
299
300import static com.android.internal.util.XmlUtils.readBooleanAttribute;
301import static com.android.internal.util.XmlUtils.readIntAttribute;
302import static com.android.internal.util.XmlUtils.readLongAttribute;
303import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
304import static com.android.internal.util.XmlUtils.writeIntAttribute;
305import static com.android.internal.util.XmlUtils.writeLongAttribute;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
328import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
329import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
330import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
331import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
332import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
333import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
334import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
335import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
336import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
337import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
352import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
353import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
354import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
355import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
356import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
357import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
358import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
359import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
360import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
361import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
362import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
363import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
364import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
365import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
366import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
367import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
368import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
369import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
370import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
371import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
372import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
373import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
374import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
375import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
376import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
377import static com.android.server.wm.AppTransition.TRANSIT_NONE;
378import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
379import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
380import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
381import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
382import static org.xmlpull.v1.XmlPullParser.START_TAG;
383
384public class ActivityManagerService extends IActivityManager.Stub
385        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
386
387    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
388    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
389    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
390    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
391    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
392    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
393    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
394    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
395    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
396    private static final String TAG_LRU = TAG + POSTFIX_LRU;
397    private static final String TAG_MU = TAG + POSTFIX_MU;
398    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
399    private static final String TAG_POWER = TAG + POSTFIX_POWER;
400    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
401    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
402    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
403    private static final String TAG_PSS = TAG + POSTFIX_PSS;
404    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
405    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
406    private static final String TAG_STACK = TAG + POSTFIX_STACK;
407    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
408    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
409    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
410    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
411    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
412
413    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
414    // here so that while the job scheduler can depend on AMS, the other way around
415    // need not be the case.
416    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
417
418    /** Control over CPU and battery monitoring */
419    // write battery stats every 30 minutes.
420    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
421    static final boolean MONITOR_CPU_USAGE = true;
422    // don't sample cpu less than every 5 seconds.
423    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
424    // wait possibly forever for next cpu sample.
425    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
426    static final boolean MONITOR_THREAD_CPU_USAGE = false;
427
428    // The flags that are set for all calls we make to the package manager.
429    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
430
431    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
432
433    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
434
435    // Amount of time after a call to stopAppSwitches() during which we will
436    // prevent further untrusted switches from happening.
437    static final long APP_SWITCH_DELAY_TIME = 5*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.
441    static final int PROC_START_TIMEOUT = 10*1000;
442    // How long we wait for an attached process to publish its content providers
443    // before we decide it must be hung.
444    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
445
446    // How long we will retain processes hosting content providers in the "last activity"
447    // state before allowing them to drop down to the regular cached LRU list.  This is
448    // to avoid thrashing of provider processes under low memory situations.
449    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
450
451    // How long we wait for a launched process to attach to the activity manager
452    // before we decide it's never going to come up for real, when the process was
453    // started with a wrapper for instrumentation (such as Valgrind) because it
454    // could take much longer than usual.
455    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
456
457    // How long to wait after going idle before forcing apps to GC.
458    static final int GC_TIMEOUT = 5*1000;
459
460    // The minimum amount of time between successive GC requests for a process.
461    static final int GC_MIN_INTERVAL = 60*1000;
462
463    // The minimum amount of time between successive PSS requests for a process.
464    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
465
466    // The minimum amount of time between successive PSS requests for a process
467    // when the request is due to the memory state being lowered.
468    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
469
470    // The rate at which we check for apps using excessive power -- 15 mins.
471    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
472
473    // The minimum sample duration we will allow before deciding we have
474    // enough data on wake locks to start killing things.
475    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
476
477    // The minimum sample duration we will allow before deciding we have
478    // enough data on CPU usage to start killing things.
479    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
480
481    // How long we allow a receiver to run before giving up on it.
482    static final int BROADCAST_FG_TIMEOUT = 10*1000;
483    static final int BROADCAST_BG_TIMEOUT = 60*1000;
484
485    // How long we wait until we timeout on key dispatching.
486    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
487
488    // How long we wait until we timeout on key dispatching during instrumentation.
489    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
490
491    // This is the amount of time an app needs to be running a foreground service before
492    // we will consider it to be doing interaction for usage stats.
493    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
494
495    // Maximum amount of time we will allow to elapse before re-reporting usage stats
496    // interaction with foreground processes.
497    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
498
499    // This is the amount of time we allow an app to settle after it goes into the background,
500    // before we start restricting what it can do.
501    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
502
503    // How long to wait in getAssistContextExtras for the activity and foreground services
504    // to respond with the result.
505    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
506
507    // How long top wait when going through the modern assist (which doesn't need to block
508    // on getting this result before starting to launch its UI).
509    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
510
511    // Maximum number of persisted Uri grants a package is allowed
512    static final int MAX_PERSISTED_URI_GRANTS = 128;
513
514    static final int MY_PID = Process.myPid();
515
516    static final String[] EMPTY_STRING_ARRAY = new String[0];
517
518    // How many bytes to write into the dropbox log before truncating
519    static final int DROPBOX_MAX_SIZE = 192 * 1024;
520    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
521    // as one line, but close enough for now.
522    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
523
524    // Access modes for handleIncomingUser.
525    static final int ALLOW_NON_FULL = 0;
526    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
527    static final int ALLOW_FULL_ONLY = 2;
528
529    // Necessary ApplicationInfo flags to mark an app as persistent
530    private static final int PERSISTENT_MASK =
531            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
532
533    // Intent sent when remote bugreport collection has been completed
534    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
535            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
536
537    // Used to indicate that a task is removed it should also be removed from recents.
538    private static final boolean REMOVE_FROM_RECENTS = true;
539    // Used to indicate that an app transition should be animated.
540    static final boolean ANIMATE = true;
541
542    // Determines whether to take full screen screenshots
543    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
544    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
545
546    /** All system services */
547    SystemServiceManager mSystemServiceManager;
548
549    private Installer mInstaller;
550
551    /** Run all ActivityStacks through this */
552    final ActivityStackSupervisor mStackSupervisor;
553    private final KeyguardController mKeyguardController;
554
555    final ActivityStarter mActivityStarter;
556
557    final TaskChangeNotificationController mTaskChangeNotificationController;
558
559    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
560
561    public IntentFirewall mIntentFirewall;
562
563    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
564    // default action automatically.  Important for devices without direct input
565    // devices.
566    private boolean mShowDialogs = true;
567    private boolean mInVrMode = false;
568
569    // Whether we should use SCHED_FIFO for UI and RenderThreads.
570    private boolean mUseFifoUiScheduling = false;
571
572    BroadcastQueue mFgBroadcastQueue;
573    BroadcastQueue mBgBroadcastQueue;
574    // Convenient for easy iteration over the queues. Foreground is first
575    // so that dispatch of foreground broadcasts gets precedence.
576    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
577
578    BroadcastStats mLastBroadcastStats;
579    BroadcastStats mCurBroadcastStats;
580
581    BroadcastQueue broadcastQueueForIntent(Intent intent) {
582        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
583        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
584                "Broadcast intent " + intent + " on "
585                + (isFg ? "foreground" : "background") + " queue");
586        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
587    }
588
589    /**
590     * The last resumed activity. This is identical to the current resumed activity most
591     * of the time but could be different when we're pausing one activity before we resume
592     * another activity.
593     */
594    private ActivityRecord mLastResumedActivity;
595
596    /**
597     * If non-null, we are tracking the time the user spends in the currently focused app.
598     */
599    private AppTimeTracker mCurAppTimeTracker;
600
601    /**
602     * List of intents that were used to start the most recent tasks.
603     */
604    final RecentTasks mRecentTasks;
605
606    /**
607     * For addAppTask: cached of the last activity component that was added.
608     */
609    ComponentName mLastAddedTaskComponent;
610
611    /**
612     * For addAppTask: cached of the last activity uid that was added.
613     */
614    int mLastAddedTaskUid;
615
616    /**
617     * For addAppTask: cached of the last ActivityInfo that was added.
618     */
619    ActivityInfo mLastAddedTaskActivity;
620
621    /**
622     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
623     */
624    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
625
626    /**
627     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
628     */
629    String mDeviceOwnerName;
630
631    final UserController mUserController;
632
633    final AppErrors mAppErrors;
634
635    public boolean canShowErrorDialogs() {
636        return mShowDialogs && !mSleeping && !mShuttingDown
637                && !mKeyguardController.isKeyguardShowing();
638    }
639
640    private static final class PriorityState {
641        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
642        // the current thread is currently in. When it drops down to zero, we will no longer boost
643        // the thread's priority.
644        private int regionCounter = 0;
645
646        // The thread's previous priority before boosting.
647        private int prevPriority = Integer.MIN_VALUE;
648    }
649
650    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
651        @Override protected PriorityState initialValue() {
652            return new PriorityState();
653        }
654    };
655
656    static void boostPriorityForLockedSection() {
657        int tid = Process.myTid();
658        int prevPriority = Process.getThreadPriority(tid);
659        PriorityState state = sThreadPriorityState.get();
660        if (state.regionCounter == 0 && prevPriority > -2) {
661            state.prevPriority = prevPriority;
662            Process.setThreadPriority(tid, -2);
663        }
664        state.regionCounter++;
665    }
666
667    static void resetPriorityAfterLockedSection() {
668        PriorityState state = sThreadPriorityState.get();
669        state.regionCounter--;
670        if (state.regionCounter == 0 && state.prevPriority > -2) {
671            Process.setThreadPriority(Process.myTid(), state.prevPriority);
672        }
673    }
674
675    public class PendingAssistExtras extends Binder implements Runnable {
676        public final ActivityRecord activity;
677        public final Bundle extras;
678        public final Intent intent;
679        public final String hint;
680        public final IResultReceiver receiver;
681        public final int userHandle;
682        public boolean haveResult = false;
683        public Bundle result = null;
684        public AssistStructure structure = null;
685        public AssistContent content = null;
686        public Bundle receiverExtras;
687
688        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
689                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
690            activity = _activity;
691            extras = _extras;
692            intent = _intent;
693            hint = _hint;
694            receiver = _receiver;
695            receiverExtras = _receiverExtras;
696            userHandle = _userHandle;
697        }
698        @Override
699        public void run() {
700            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
701            synchronized (this) {
702                haveResult = true;
703                notifyAll();
704            }
705            pendingAssistExtrasTimedOut(this);
706        }
707    }
708
709    final ArrayList<PendingAssistExtras> mPendingAssistExtras
710            = new ArrayList<PendingAssistExtras>();
711
712    /**
713     * Process management.
714     */
715    final ProcessList mProcessList = new ProcessList();
716
717    /**
718     * All of the applications we currently have running organized by name.
719     * The keys are strings of the application package name (as
720     * returned by the package manager), and the keys are ApplicationRecord
721     * objects.
722     */
723    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
724
725    /**
726     * Tracking long-term execution of processes to look for abuse and other
727     * bad app behavior.
728     */
729    final ProcessStatsService mProcessStats;
730
731    /**
732     * The currently running isolated processes.
733     */
734    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
735
736    /**
737     * Counter for assigning isolated process uids, to avoid frequently reusing the
738     * same ones.
739     */
740    int mNextIsolatedProcessUid = 0;
741
742    /**
743     * The currently running heavy-weight process, if any.
744     */
745    ProcessRecord mHeavyWeightProcess = null;
746
747    /**
748     * All of the processes we currently have running organized by pid.
749     * The keys are the pid running the application.
750     *
751     * <p>NOTE: This object is protected by its own lock, NOT the global
752     * activity manager lock!
753     */
754    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
755
756    /**
757     * All of the processes that have been forced to be foreground.  The key
758     * is the pid of the caller who requested it (we hold a death
759     * link on it).
760     */
761    abstract class ForegroundToken implements IBinder.DeathRecipient {
762        int pid;
763        IBinder token;
764    }
765    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
766
767    /**
768     * List of records for processes that someone had tried to start before the
769     * system was ready.  We don't start them at that point, but ensure they
770     * are started by the time booting is complete.
771     */
772    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
773
774    /**
775     * List of persistent applications that are in the process
776     * of being started.
777     */
778    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
779
780    /**
781     * Processes that are being forcibly torn down.
782     */
783    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
784
785    /**
786     * List of running applications, sorted by recent usage.
787     * The first entry in the list is the least recently used.
788     */
789    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
790
791    /**
792     * Where in mLruProcesses that the processes hosting activities start.
793     */
794    int mLruProcessActivityStart = 0;
795
796    /**
797     * Where in mLruProcesses that the processes hosting services start.
798     * This is after (lower index) than mLruProcessesActivityStart.
799     */
800    int mLruProcessServiceStart = 0;
801
802    /**
803     * List of processes that should gc as soon as things are idle.
804     */
805    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
806
807    /**
808     * Processes we want to collect PSS data from.
809     */
810    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
811
812    private boolean mBinderTransactionTrackingEnabled = false;
813
814    /**
815     * Last time we requested PSS data of all processes.
816     */
817    long mLastFullPssTime = SystemClock.uptimeMillis();
818
819    /**
820     * If set, the next time we collect PSS data we should do a full collection
821     * with data from native processes and the kernel.
822     */
823    boolean mFullPssPending = false;
824
825    /**
826     * This is the process holding what we currently consider to be
827     * the "home" activity.
828     */
829    ProcessRecord mHomeProcess;
830
831    /**
832     * This is the process holding the activity the user last visited that
833     * is in a different process from the one they are currently in.
834     */
835    ProcessRecord mPreviousProcess;
836
837    /**
838     * The time at which the previous process was last visible.
839     */
840    long mPreviousProcessVisibleTime;
841
842    /**
843     * Track all uids that have actively running processes.
844     */
845    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
846
847    /**
848     * This is for verifying the UID report flow.
849     */
850    static final boolean VALIDATE_UID_STATES = true;
851    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
852
853    /**
854     * Packages that the user has asked to have run in screen size
855     * compatibility mode instead of filling the screen.
856     */
857    final CompatModePackages mCompatModePackages;
858
859    /**
860     * Set of IntentSenderRecord objects that are currently active.
861     */
862    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
863            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
864
865    /**
866     * Fingerprints (hashCode()) of stack traces that we've
867     * already logged DropBox entries for.  Guarded by itself.  If
868     * something (rogue user app) forces this over
869     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
870     */
871    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
872    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
873
874    /**
875     * Strict Mode background batched logging state.
876     *
877     * The string buffer is guarded by itself, and its lock is also
878     * used to determine if another batched write is already
879     * in-flight.
880     */
881    private final StringBuilder mStrictModeBuffer = new StringBuilder();
882
883    /**
884     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
885     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
886     */
887    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
888
889    /**
890     * Resolver for broadcast intents to registered receivers.
891     * Holds BroadcastFilter (subclass of IntentFilter).
892     */
893    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
894            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
895        @Override
896        protected boolean allowFilterResult(
897                BroadcastFilter filter, List<BroadcastFilter> dest) {
898            IBinder target = filter.receiverList.receiver.asBinder();
899            for (int i = dest.size() - 1; i >= 0; i--) {
900                if (dest.get(i).receiverList.receiver.asBinder() == target) {
901                    return false;
902                }
903            }
904            return true;
905        }
906
907        @Override
908        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
909            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
910                    || userId == filter.owningUserId) {
911                return super.newResult(filter, match, userId);
912            }
913            return null;
914        }
915
916        @Override
917        protected BroadcastFilter[] newArray(int size) {
918            return new BroadcastFilter[size];
919        }
920
921        @Override
922        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
923            return packageName.equals(filter.packageName);
924        }
925    };
926
927    /**
928     * State of all active sticky broadcasts per user.  Keys are the action of the
929     * sticky Intent, values are an ArrayList of all broadcasted intents with
930     * that action (which should usually be one).  The SparseArray is keyed
931     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
932     * for stickies that are sent to all users.
933     */
934    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
935            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
936
937    final ActiveServices mServices;
938
939    final static class Association {
940        final int mSourceUid;
941        final String mSourceProcess;
942        final int mTargetUid;
943        final ComponentName mTargetComponent;
944        final String mTargetProcess;
945
946        int mCount;
947        long mTime;
948
949        int mNesting;
950        long mStartTime;
951
952        // states of the source process when the bind occurred.
953        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
954        long mLastStateUptime;
955        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
956                - ActivityManager.MIN_PROCESS_STATE+1];
957
958        Association(int sourceUid, String sourceProcess, int targetUid,
959                ComponentName targetComponent, String targetProcess) {
960            mSourceUid = sourceUid;
961            mSourceProcess = sourceProcess;
962            mTargetUid = targetUid;
963            mTargetComponent = targetComponent;
964            mTargetProcess = targetProcess;
965        }
966    }
967
968    /**
969     * When service association tracking is enabled, this is all of the associations we
970     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
971     * -> association data.
972     */
973    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
974            mAssociations = new SparseArray<>();
975    boolean mTrackingAssociations;
976
977    /**
978     * Backup/restore process management
979     */
980    String mBackupAppName = null;
981    BackupRecord mBackupTarget = null;
982
983    final ProviderMap mProviderMap;
984
985    /**
986     * List of content providers who have clients waiting for them.  The
987     * application is currently being launched and the provider will be
988     * removed from this list once it is published.
989     */
990    final ArrayList<ContentProviderRecord> mLaunchingProviders
991            = new ArrayList<ContentProviderRecord>();
992
993    /**
994     * File storing persisted {@link #mGrantedUriPermissions}.
995     */
996    private final AtomicFile mGrantFile;
997
998    /** XML constants used in {@link #mGrantFile} */
999    private static final String TAG_URI_GRANTS = "uri-grants";
1000    private static final String TAG_URI_GRANT = "uri-grant";
1001    private static final String ATTR_USER_HANDLE = "userHandle";
1002    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1003    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1004    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1005    private static final String ATTR_TARGET_PKG = "targetPkg";
1006    private static final String ATTR_URI = "uri";
1007    private static final String ATTR_MODE_FLAGS = "modeFlags";
1008    private static final String ATTR_CREATED_TIME = "createdTime";
1009    private static final String ATTR_PREFIX = "prefix";
1010
1011    /**
1012     * Global set of specific {@link Uri} permissions that have been granted.
1013     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1014     * to {@link UriPermission#uri} to {@link UriPermission}.
1015     */
1016    @GuardedBy("this")
1017    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1018            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1019
1020    public static class GrantUri {
1021        public final int sourceUserId;
1022        public final Uri uri;
1023        public boolean prefix;
1024
1025        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1026            this.sourceUserId = sourceUserId;
1027            this.uri = uri;
1028            this.prefix = prefix;
1029        }
1030
1031        @Override
1032        public int hashCode() {
1033            int hashCode = 1;
1034            hashCode = 31 * hashCode + sourceUserId;
1035            hashCode = 31 * hashCode + uri.hashCode();
1036            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1037            return hashCode;
1038        }
1039
1040        @Override
1041        public boolean equals(Object o) {
1042            if (o instanceof GrantUri) {
1043                GrantUri other = (GrantUri) o;
1044                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1045                        && prefix == other.prefix;
1046            }
1047            return false;
1048        }
1049
1050        @Override
1051        public String toString() {
1052            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1053            if (prefix) result += " [prefix]";
1054            return result;
1055        }
1056
1057        public String toSafeString() {
1058            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1059            if (prefix) result += " [prefix]";
1060            return result;
1061        }
1062
1063        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1064            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1065                    ContentProvider.getUriWithoutUserId(uri), false);
1066        }
1067    }
1068
1069    CoreSettingsObserver mCoreSettingsObserver;
1070
1071    FontScaleSettingObserver mFontScaleSettingObserver;
1072
1073    private final class FontScaleSettingObserver extends ContentObserver {
1074        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1075
1076        public FontScaleSettingObserver() {
1077            super(mHandler);
1078            ContentResolver resolver = mContext.getContentResolver();
1079            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1080        }
1081
1082        @Override
1083        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1084            if (mFontScaleUri.equals(uri)) {
1085                updateFontScaleIfNeeded(userId);
1086            }
1087        }
1088    }
1089
1090    /**
1091     * Thread-local storage used to carry caller permissions over through
1092     * indirect content-provider access.
1093     */
1094    private class Identity {
1095        public final IBinder token;
1096        public final int pid;
1097        public final int uid;
1098
1099        Identity(IBinder _token, int _pid, int _uid) {
1100            token = _token;
1101            pid = _pid;
1102            uid = _uid;
1103        }
1104    }
1105
1106    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1107
1108    /**
1109     * All information we have collected about the runtime performance of
1110     * any user id that can impact battery performance.
1111     */
1112    final BatteryStatsService mBatteryStatsService;
1113
1114    /**
1115     * Information about component usage
1116     */
1117    UsageStatsManagerInternal mUsageStatsService;
1118
1119    /**
1120     * Access to DeviceIdleController service.
1121     */
1122    DeviceIdleController.LocalService mLocalDeviceIdleController;
1123
1124    /**
1125     * Information about and control over application operations
1126     */
1127    final AppOpsService mAppOpsService;
1128
1129    /** Current sequencing integer of the configuration, for skipping old configurations. */
1130    private int mConfigurationSeq;
1131
1132    /**
1133     * Temp object used when global and/or display override configuration is updated. It is also
1134     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1135     * anyone...
1136     */
1137    private Configuration mTempConfig = new Configuration();
1138
1139    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1140            new UpdateConfigurationResult();
1141    private static final class UpdateConfigurationResult {
1142        // Configuration changes that were updated.
1143        int changes;
1144        // If the activity was relaunched to match the new configuration.
1145        boolean activityRelaunched;
1146
1147        void reset() {
1148            changes = 0;
1149            activityRelaunched = false;
1150        }
1151    }
1152
1153    boolean mSuppressResizeConfigChanges;
1154
1155    /**
1156     * Hardware-reported OpenGLES version.
1157     */
1158    final int GL_ES_VERSION;
1159
1160    /**
1161     * List of initialization arguments to pass to all processes when binding applications to them.
1162     * For example, references to the commonly used services.
1163     */
1164    HashMap<String, IBinder> mAppBindArgs;
1165    HashMap<String, IBinder> mIsolatedAppBindArgs;
1166
1167    /**
1168     * Temporary to avoid allocations.  Protected by main lock.
1169     */
1170    final StringBuilder mStringBuilder = new StringBuilder(256);
1171
1172    /**
1173     * Used to control how we initialize the service.
1174     */
1175    ComponentName mTopComponent;
1176    String mTopAction = Intent.ACTION_MAIN;
1177    String mTopData;
1178
1179    volatile boolean mProcessesReady = false;
1180    volatile boolean mSystemReady = false;
1181    volatile boolean mOnBattery = false;
1182    volatile int mFactoryTest;
1183
1184    @GuardedBy("this") boolean mBooting = false;
1185    @GuardedBy("this") boolean mCallFinishBooting = false;
1186    @GuardedBy("this") boolean mBootAnimationComplete = false;
1187    @GuardedBy("this") boolean mLaunchWarningShown = false;
1188    @GuardedBy("this") boolean mCheckedForSetup = false;
1189
1190    Context mContext;
1191
1192    /**
1193     * The time at which we will allow normal application switches again,
1194     * after a call to {@link #stopAppSwitches()}.
1195     */
1196    long mAppSwitchesAllowedTime;
1197
1198    /**
1199     * This is set to true after the first switch after mAppSwitchesAllowedTime
1200     * is set; any switches after that will clear the time.
1201     */
1202    boolean mDidAppSwitch;
1203
1204    /**
1205     * Last time (in realtime) at which we checked for power usage.
1206     */
1207    long mLastPowerCheckRealtime;
1208
1209    /**
1210     * Last time (in uptime) at which we checked for power usage.
1211     */
1212    long mLastPowerCheckUptime;
1213
1214    /**
1215     * Set while we are wanting to sleep, to prevent any
1216     * activities from being started/resumed.
1217     */
1218    private boolean mSleeping = false;
1219
1220    /**
1221     * The process state used for processes that are running the top activities.
1222     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1223     */
1224    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1225
1226    /**
1227     * Set while we are running a voice interaction.  This overrides
1228     * sleeping while it is active.
1229     */
1230    private IVoiceInteractionSession mRunningVoice;
1231
1232    /**
1233     * For some direct access we need to power manager.
1234     */
1235    PowerManagerInternal mLocalPowerManager;
1236
1237    /**
1238     * We want to hold a wake lock while running a voice interaction session, since
1239     * this may happen with the screen off and we need to keep the CPU running to
1240     * be able to continue to interact with the user.
1241     */
1242    PowerManager.WakeLock mVoiceWakeLock;
1243
1244    /**
1245     * State of external calls telling us if the device is awake or asleep.
1246     */
1247    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1248
1249    /**
1250     * A list of tokens that cause the top activity to be put to sleep.
1251     * They are used by components that may hide and block interaction with underlying
1252     * activities.
1253     */
1254    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1255
1256    /**
1257     * Set if we are shutting down the system, similar to sleeping.
1258     */
1259    boolean mShuttingDown = false;
1260
1261    /**
1262     * Current sequence id for oom_adj computation traversal.
1263     */
1264    int mAdjSeq = 0;
1265
1266    /**
1267     * Current sequence id for process LRU updating.
1268     */
1269    int mLruSeq = 0;
1270
1271    /**
1272     * Keep track of the non-cached/empty process we last found, to help
1273     * determine how to distribute cached/empty processes next time.
1274     */
1275    int mNumNonCachedProcs = 0;
1276
1277    /**
1278     * Keep track of the number of cached hidden procs, to balance oom adj
1279     * distribution between those and empty procs.
1280     */
1281    int mNumCachedHiddenProcs = 0;
1282
1283    /**
1284     * Keep track of the number of service processes we last found, to
1285     * determine on the next iteration which should be B services.
1286     */
1287    int mNumServiceProcs = 0;
1288    int mNewNumAServiceProcs = 0;
1289    int mNewNumServiceProcs = 0;
1290
1291    /**
1292     * Allow the current computed overall memory level of the system to go down?
1293     * This is set to false when we are killing processes for reasons other than
1294     * memory management, so that the now smaller process list will not be taken as
1295     * an indication that memory is tighter.
1296     */
1297    boolean mAllowLowerMemLevel = false;
1298
1299    /**
1300     * The last computed memory level, for holding when we are in a state that
1301     * processes are going away for other reasons.
1302     */
1303    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1304
1305    /**
1306     * The last total number of process we have, to determine if changes actually look
1307     * like a shrinking number of process due to lower RAM.
1308     */
1309    int mLastNumProcesses;
1310
1311    /**
1312     * The uptime of the last time we performed idle maintenance.
1313     */
1314    long mLastIdleTime = SystemClock.uptimeMillis();
1315
1316    /**
1317     * Total time spent with RAM that has been added in the past since the last idle time.
1318     */
1319    long mLowRamTimeSinceLastIdle = 0;
1320
1321    /**
1322     * If RAM is currently low, when that horrible situation started.
1323     */
1324    long mLowRamStartTime = 0;
1325
1326    /**
1327     * For reporting to battery stats the current top application.
1328     */
1329    private String mCurResumedPackage = null;
1330    private int mCurResumedUid = -1;
1331
1332    /**
1333     * For reporting to battery stats the apps currently running foreground
1334     * service.  The ProcessMap is package/uid tuples; each of these contain
1335     * an array of the currently foreground processes.
1336     */
1337    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1338            = new ProcessMap<ArrayList<ProcessRecord>>();
1339
1340    /**
1341     * This is set if we had to do a delayed dexopt of an app before launching
1342     * it, to increase the ANR timeouts in that case.
1343     */
1344    boolean mDidDexOpt;
1345
1346    /**
1347     * Set if the systemServer made a call to enterSafeMode.
1348     */
1349    boolean mSafeMode;
1350
1351    /**
1352     * If true, we are running under a test environment so will sample PSS from processes
1353     * much more rapidly to try to collect better data when the tests are rapidly
1354     * running through apps.
1355     */
1356    boolean mTestPssMode = false;
1357
1358    String mDebugApp = null;
1359    boolean mWaitForDebugger = false;
1360    boolean mDebugTransient = false;
1361    String mOrigDebugApp = null;
1362    boolean mOrigWaitForDebugger = false;
1363    boolean mAlwaysFinishActivities = false;
1364    boolean mForceResizableActivities;
1365    boolean mSupportsMultiWindow;
1366    boolean mSupportsFreeformWindowManagement;
1367    boolean mSupportsPictureInPicture;
1368    boolean mSupportsLeanbackOnly;
1369    IActivityController mController = null;
1370    boolean mControllerIsAMonkey = false;
1371    String mProfileApp = null;
1372    ProcessRecord mProfileProc = null;
1373    String mProfileFile;
1374    ParcelFileDescriptor mProfileFd;
1375    int mSamplingInterval = 0;
1376    boolean mAutoStopProfiler = false;
1377    int mProfileType = 0;
1378    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1379    String mMemWatchDumpProcName;
1380    String mMemWatchDumpFile;
1381    int mMemWatchDumpPid;
1382    int mMemWatchDumpUid;
1383    String mTrackAllocationApp = null;
1384    String mNativeDebuggingApp = null;
1385
1386    final long[] mTmpLong = new long[2];
1387
1388    static final class ProcessChangeItem {
1389        static final int CHANGE_ACTIVITIES = 1<<0;
1390        static final int CHANGE_PROCESS_STATE = 1<<1;
1391        int changes;
1392        int uid;
1393        int pid;
1394        int processState;
1395        boolean foregroundActivities;
1396    }
1397
1398    static final class UidObserverRegistration {
1399        final int uid;
1400        final String pkg;
1401        final int which;
1402        final int cutpoint;
1403
1404        final SparseIntArray lastProcStates;
1405
1406        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1407            uid = _uid;
1408            pkg = _pkg;
1409            which = _which;
1410            cutpoint = _cutpoint;
1411            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1412                lastProcStates = new SparseIntArray();
1413            } else {
1414                lastProcStates = null;
1415            }
1416        }
1417    }
1418
1419    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1420    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1421
1422    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1423    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1424
1425    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1426    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1427
1428    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1429    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1430
1431    /**
1432     * Runtime CPU use collection thread.  This object's lock is used to
1433     * perform synchronization with the thread (notifying it to run).
1434     */
1435    final Thread mProcessCpuThread;
1436
1437    /**
1438     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1439     * Must acquire this object's lock when accessing it.
1440     * NOTE: this lock will be held while doing long operations (trawling
1441     * through all processes in /proc), so it should never be acquired by
1442     * any critical paths such as when holding the main activity manager lock.
1443     */
1444    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1445            MONITOR_THREAD_CPU_USAGE);
1446    final AtomicLong mLastCpuTime = new AtomicLong(0);
1447    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1448
1449    long mLastWriteTime = 0;
1450
1451    /**
1452     * Used to retain an update lock when the foreground activity is in
1453     * immersive mode.
1454     */
1455    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1456
1457    /**
1458     * Set to true after the system has finished booting.
1459     */
1460    boolean mBooted = false;
1461
1462    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1463    int mProcessLimitOverride = -1;
1464
1465    WindowManagerService mWindowManager;
1466    final ActivityThread mSystemThread;
1467
1468    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1469        final ProcessRecord mApp;
1470        final int mPid;
1471        final IApplicationThread mAppThread;
1472
1473        AppDeathRecipient(ProcessRecord app, int pid,
1474                IApplicationThread thread) {
1475            if (DEBUG_ALL) Slog.v(
1476                TAG, "New death recipient " + this
1477                + " for thread " + thread.asBinder());
1478            mApp = app;
1479            mPid = pid;
1480            mAppThread = thread;
1481        }
1482
1483        @Override
1484        public void binderDied() {
1485            if (DEBUG_ALL) Slog.v(
1486                TAG, "Death received in " + this
1487                + " for thread " + mAppThread.asBinder());
1488            synchronized(ActivityManagerService.this) {
1489                appDiedLocked(mApp, mPid, mAppThread, true);
1490            }
1491        }
1492    }
1493
1494    static final int SHOW_ERROR_UI_MSG = 1;
1495    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1496    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1497    static final int UPDATE_CONFIGURATION_MSG = 4;
1498    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1499    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1500    static final int SERVICE_TIMEOUT_MSG = 12;
1501    static final int UPDATE_TIME_ZONE = 13;
1502    static final int SHOW_UID_ERROR_UI_MSG = 14;
1503    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1504    static final int PROC_START_TIMEOUT_MSG = 20;
1505    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1506    static final int KILL_APPLICATION_MSG = 22;
1507    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1508    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1509    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1510    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1511    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1512    static final int CLEAR_DNS_CACHE_MSG = 28;
1513    static final int UPDATE_HTTP_PROXY_MSG = 29;
1514    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1515    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1516    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1517    static final int REPORT_MEM_USAGE_MSG = 33;
1518    static final int REPORT_USER_SWITCH_MSG = 34;
1519    static final int CONTINUE_USER_SWITCH_MSG = 35;
1520    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1521    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1522    static final int PERSIST_URI_GRANTS_MSG = 38;
1523    static final int REQUEST_ALL_PSS_MSG = 39;
1524    static final int START_PROFILES_MSG = 40;
1525    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1526    static final int SYSTEM_USER_START_MSG = 42;
1527    static final int SYSTEM_USER_CURRENT_MSG = 43;
1528    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1529    static final int FINISH_BOOTING_MSG = 45;
1530    static final int START_USER_SWITCH_UI_MSG = 46;
1531    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1532    static final int DISMISS_DIALOG_UI_MSG = 48;
1533    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1534    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1535    static final int DELETE_DUMPHEAP_MSG = 51;
1536    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1537    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1538    static final int REPORT_TIME_TRACKER_MSG = 54;
1539    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1540    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1541    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1542    static final int IDLE_UIDS_MSG = 58;
1543    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1544    static final int LOG_STACK_STATE = 60;
1545    static final int VR_MODE_CHANGE_MSG = 61;
1546    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 62;
1547    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 63;
1548    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 64;
1549    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 65;
1550    static final int START_USER_SWITCH_FG_MSG = 712;
1551
1552    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1553    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1554    static final int FIRST_COMPAT_MODE_MSG = 300;
1555    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1556
1557    static ServiceThread sKillThread = null;
1558    static KillHandler sKillHandler = null;
1559
1560    CompatModeDialog mCompatModeDialog;
1561    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1562    long mLastMemUsageReportTime = 0;
1563
1564    /**
1565     * Flag whether the current user is a "monkey", i.e. whether
1566     * the UI is driven by a UI automation tool.
1567     */
1568    private boolean mUserIsMonkey;
1569
1570    /** Flag whether the device has a Recents UI */
1571    boolean mHasRecents;
1572
1573    /** The dimensions of the thumbnails in the Recents UI. */
1574    int mThumbnailWidth;
1575    int mThumbnailHeight;
1576    float mFullscreenThumbnailScale;
1577
1578    /** The aspect ratio bounds of the PIP. */
1579    float mMinPipAspectRatio;
1580    float mMaxPipAspectRatio;
1581
1582    final ServiceThread mHandlerThread;
1583    final MainHandler mHandler;
1584    final UiHandler mUiHandler;
1585
1586    PackageManagerInternal mPackageManagerInt;
1587
1588    // VoiceInteraction session ID that changes for each new request except when
1589    // being called for multiwindow assist in a single session.
1590    private int mViSessionId = 1000;
1591
1592    final boolean mPermissionReviewRequired;
1593
1594    /**
1595     * Current global configuration information. Contains general settings for the entire system,
1596     * also corresponds to the merged configuration of the default display.
1597     */
1598    Configuration getGlobalConfiguration() {
1599        return mStackSupervisor.getConfiguration();
1600    }
1601
1602    final class KillHandler extends Handler {
1603        static final int KILL_PROCESS_GROUP_MSG = 4000;
1604
1605        public KillHandler(Looper looper) {
1606            super(looper, null, true);
1607        }
1608
1609        @Override
1610        public void handleMessage(Message msg) {
1611            switch (msg.what) {
1612                case KILL_PROCESS_GROUP_MSG:
1613                {
1614                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1615                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1616                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1617                }
1618                break;
1619
1620                default:
1621                    super.handleMessage(msg);
1622            }
1623        }
1624    }
1625
1626    final class UiHandler extends Handler {
1627        public UiHandler() {
1628            super(com.android.server.UiThread.get().getLooper(), null, true);
1629        }
1630
1631        @Override
1632        public void handleMessage(Message msg) {
1633            switch (msg.what) {
1634            case SHOW_ERROR_UI_MSG: {
1635                mAppErrors.handleShowAppErrorUi(msg);
1636                ensureBootCompleted();
1637            } break;
1638            case SHOW_NOT_RESPONDING_UI_MSG: {
1639                mAppErrors.handleShowAnrUi(msg);
1640                ensureBootCompleted();
1641            } break;
1642            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1643                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1644                synchronized (ActivityManagerService.this) {
1645                    ProcessRecord proc = (ProcessRecord) data.get("app");
1646                    if (proc == null) {
1647                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1648                        break;
1649                    }
1650                    if (proc.crashDialog != null) {
1651                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1652                        return;
1653                    }
1654                    AppErrorResult res = (AppErrorResult) data.get("result");
1655                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1656                        Dialog d = new StrictModeViolationDialog(mContext,
1657                                ActivityManagerService.this, res, proc);
1658                        d.show();
1659                        proc.crashDialog = d;
1660                    } else {
1661                        // The device is asleep, so just pretend that the user
1662                        // saw a crash dialog and hit "force quit".
1663                        res.set(0);
1664                    }
1665                }
1666                ensureBootCompleted();
1667            } break;
1668            case SHOW_FACTORY_ERROR_UI_MSG: {
1669                Dialog d = new FactoryErrorDialog(
1670                    mContext, msg.getData().getCharSequence("msg"));
1671                d.show();
1672                ensureBootCompleted();
1673            } break;
1674            case WAIT_FOR_DEBUGGER_UI_MSG: {
1675                synchronized (ActivityManagerService.this) {
1676                    ProcessRecord app = (ProcessRecord)msg.obj;
1677                    if (msg.arg1 != 0) {
1678                        if (!app.waitedForDebugger) {
1679                            Dialog d = new AppWaitingForDebuggerDialog(
1680                                    ActivityManagerService.this,
1681                                    mContext, app);
1682                            app.waitDialog = d;
1683                            app.waitedForDebugger = true;
1684                            d.show();
1685                        }
1686                    } else {
1687                        if (app.waitDialog != null) {
1688                            app.waitDialog.dismiss();
1689                            app.waitDialog = null;
1690                        }
1691                    }
1692                }
1693            } break;
1694            case SHOW_UID_ERROR_UI_MSG: {
1695                if (mShowDialogs) {
1696                    AlertDialog d = new BaseErrorDialog(mContext);
1697                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1698                    d.setCancelable(false);
1699                    d.setTitle(mContext.getText(R.string.android_system_label));
1700                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1701                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1702                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1703                    d.show();
1704                }
1705            } break;
1706            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1707                if (mShowDialogs) {
1708                    AlertDialog d = new BaseErrorDialog(mContext);
1709                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1710                    d.setCancelable(false);
1711                    d.setTitle(mContext.getText(R.string.android_system_label));
1712                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1713                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1714                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1715                    d.show();
1716                }
1717            } break;
1718            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1719                synchronized (ActivityManagerService.this) {
1720                    ActivityRecord ar = (ActivityRecord) msg.obj;
1721                    if (mCompatModeDialog != null) {
1722                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1723                                ar.info.applicationInfo.packageName)) {
1724                            return;
1725                        }
1726                        mCompatModeDialog.dismiss();
1727                        mCompatModeDialog = null;
1728                    }
1729                    if (ar != null && false) {
1730                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1731                                ar.packageName)) {
1732                            int mode = mCompatModePackages.computeCompatModeLocked(
1733                                    ar.info.applicationInfo);
1734                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1735                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1736                                mCompatModeDialog = new CompatModeDialog(
1737                                        ActivityManagerService.this, mContext,
1738                                        ar.info.applicationInfo);
1739                                mCompatModeDialog.show();
1740                            }
1741                        }
1742                    }
1743                }
1744                break;
1745            }
1746            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1747                synchronized (ActivityManagerService.this) {
1748                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1749                    if (mUnsupportedDisplaySizeDialog != null) {
1750                        mUnsupportedDisplaySizeDialog.dismiss();
1751                        mUnsupportedDisplaySizeDialog = null;
1752                    }
1753                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1754                            ar.packageName)) {
1755                        // TODO(multi-display): Show dialog on appropriate display.
1756                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1757                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1758                        mUnsupportedDisplaySizeDialog.show();
1759                    }
1760                }
1761                break;
1762            }
1763            case START_USER_SWITCH_UI_MSG: {
1764                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1765                break;
1766            }
1767            case DISMISS_DIALOG_UI_MSG: {
1768                final Dialog d = (Dialog) msg.obj;
1769                d.dismiss();
1770                break;
1771            }
1772            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1773                dispatchProcessesChanged();
1774                break;
1775            }
1776            case DISPATCH_PROCESS_DIED_UI_MSG: {
1777                final int pid = msg.arg1;
1778                final int uid = msg.arg2;
1779                dispatchProcessDied(pid, uid);
1780                break;
1781            }
1782            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1783                dispatchUidsChanged();
1784            } break;
1785            }
1786        }
1787    }
1788
1789    final class MainHandler extends Handler {
1790        public MainHandler(Looper looper) {
1791            super(looper, null, true);
1792        }
1793
1794        @Override
1795        public void handleMessage(Message msg) {
1796            switch (msg.what) {
1797            case UPDATE_CONFIGURATION_MSG: {
1798                final ContentResolver resolver = mContext.getContentResolver();
1799                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1800                        msg.arg1);
1801            } break;
1802            case GC_BACKGROUND_PROCESSES_MSG: {
1803                synchronized (ActivityManagerService.this) {
1804                    performAppGcsIfAppropriateLocked();
1805                }
1806            } break;
1807            case SERVICE_TIMEOUT_MSG: {
1808                if (mDidDexOpt) {
1809                    mDidDexOpt = false;
1810                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1811                    nmsg.obj = msg.obj;
1812                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1813                    return;
1814                }
1815                mServices.serviceTimeout((ProcessRecord)msg.obj);
1816            } break;
1817            case UPDATE_TIME_ZONE: {
1818                synchronized (ActivityManagerService.this) {
1819                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1820                        ProcessRecord r = mLruProcesses.get(i);
1821                        if (r.thread != null) {
1822                            try {
1823                                r.thread.updateTimeZone();
1824                            } catch (RemoteException ex) {
1825                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1826                            }
1827                        }
1828                    }
1829                }
1830            } break;
1831            case CLEAR_DNS_CACHE_MSG: {
1832                synchronized (ActivityManagerService.this) {
1833                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1834                        ProcessRecord r = mLruProcesses.get(i);
1835                        if (r.thread != null) {
1836                            try {
1837                                r.thread.clearDnsCache();
1838                            } catch (RemoteException ex) {
1839                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1840                            }
1841                        }
1842                    }
1843                }
1844            } break;
1845            case UPDATE_HTTP_PROXY_MSG: {
1846                ProxyInfo proxy = (ProxyInfo)msg.obj;
1847                String host = "";
1848                String port = "";
1849                String exclList = "";
1850                Uri pacFileUrl = Uri.EMPTY;
1851                if (proxy != null) {
1852                    host = proxy.getHost();
1853                    port = Integer.toString(proxy.getPort());
1854                    exclList = proxy.getExclusionListAsString();
1855                    pacFileUrl = proxy.getPacFileUrl();
1856                }
1857                synchronized (ActivityManagerService.this) {
1858                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1859                        ProcessRecord r = mLruProcesses.get(i);
1860                        if (r.thread != null) {
1861                            try {
1862                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1863                            } catch (RemoteException ex) {
1864                                Slog.w(TAG, "Failed to update http proxy for: " +
1865                                        r.info.processName);
1866                            }
1867                        }
1868                    }
1869                }
1870            } break;
1871            case PROC_START_TIMEOUT_MSG: {
1872                if (mDidDexOpt) {
1873                    mDidDexOpt = false;
1874                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1875                    nmsg.obj = msg.obj;
1876                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1877                    return;
1878                }
1879                ProcessRecord app = (ProcessRecord)msg.obj;
1880                synchronized (ActivityManagerService.this) {
1881                    processStartTimedOutLocked(app);
1882                }
1883            } break;
1884            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1885                ProcessRecord app = (ProcessRecord)msg.obj;
1886                synchronized (ActivityManagerService.this) {
1887                    processContentProviderPublishTimedOutLocked(app);
1888                }
1889            } break;
1890            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1891                synchronized (ActivityManagerService.this) {
1892                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1893                }
1894            } break;
1895            case KILL_APPLICATION_MSG: {
1896                synchronized (ActivityManagerService.this) {
1897                    final int appId = msg.arg1;
1898                    final int userId = msg.arg2;
1899                    Bundle bundle = (Bundle)msg.obj;
1900                    String pkg = bundle.getString("pkg");
1901                    String reason = bundle.getString("reason");
1902                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1903                            false, userId, reason);
1904                }
1905            } break;
1906            case FINALIZE_PENDING_INTENT_MSG: {
1907                ((PendingIntentRecord)msg.obj).completeFinalize();
1908            } break;
1909            case POST_HEAVY_NOTIFICATION_MSG: {
1910                INotificationManager inm = NotificationManager.getService();
1911                if (inm == null) {
1912                    return;
1913                }
1914
1915                ActivityRecord root = (ActivityRecord)msg.obj;
1916                ProcessRecord process = root.app;
1917                if (process == null) {
1918                    return;
1919                }
1920
1921                try {
1922                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1923                    String text = mContext.getString(R.string.heavy_weight_notification,
1924                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1925                    Notification notification = new Notification.Builder(context)
1926                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1927                            .setWhen(0)
1928                            .setOngoing(true)
1929                            .setTicker(text)
1930                            .setColor(mContext.getColor(
1931                                    com.android.internal.R.color.system_notification_accent_color))
1932                            .setContentTitle(text)
1933                            .setContentText(
1934                                    mContext.getText(R.string.heavy_weight_notification_detail))
1935                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1936                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1937                                    new UserHandle(root.userId)))
1938                            .build();
1939                    try {
1940                        int[] outId = new int[1];
1941                        inm.enqueueNotificationWithTag("android", "android", null,
1942                                R.string.heavy_weight_notification,
1943                                notification, outId, root.userId);
1944                    } catch (RuntimeException e) {
1945                        Slog.w(ActivityManagerService.TAG,
1946                                "Error showing notification for heavy-weight app", e);
1947                    } catch (RemoteException e) {
1948                    }
1949                } catch (NameNotFoundException e) {
1950                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1951                }
1952            } break;
1953            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1954                INotificationManager inm = NotificationManager.getService();
1955                if (inm == null) {
1956                    return;
1957                }
1958                try {
1959                    inm.cancelNotificationWithTag("android", null,
1960                            R.string.heavy_weight_notification,  msg.arg1);
1961                } catch (RuntimeException e) {
1962                    Slog.w(ActivityManagerService.TAG,
1963                            "Error canceling notification for service", e);
1964                } catch (RemoteException e) {
1965                }
1966            } break;
1967            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1968                synchronized (ActivityManagerService.this) {
1969                    checkExcessivePowerUsageLocked(true);
1970                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1971                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1972                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1973                }
1974            } break;
1975            case REPORT_MEM_USAGE_MSG: {
1976                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1977                Thread thread = new Thread() {
1978                    @Override public void run() {
1979                        reportMemUsage(memInfos);
1980                    }
1981                };
1982                thread.start();
1983                break;
1984            }
1985            case START_USER_SWITCH_FG_MSG: {
1986                mUserController.startUserInForeground(msg.arg1);
1987                break;
1988            }
1989            case REPORT_USER_SWITCH_MSG: {
1990                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1991                break;
1992            }
1993            case CONTINUE_USER_SWITCH_MSG: {
1994                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1995                break;
1996            }
1997            case USER_SWITCH_TIMEOUT_MSG: {
1998                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1999                break;
2000            }
2001            case IMMERSIVE_MODE_LOCK_MSG: {
2002                final boolean nextState = (msg.arg1 != 0);
2003                if (mUpdateLock.isHeld() != nextState) {
2004                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2005                            "Applying new update lock state '" + nextState
2006                            + "' for " + (ActivityRecord)msg.obj);
2007                    if (nextState) {
2008                        mUpdateLock.acquire();
2009                    } else {
2010                        mUpdateLock.release();
2011                    }
2012                }
2013                break;
2014            }
2015            case PERSIST_URI_GRANTS_MSG: {
2016                writeGrantedUriPermissions();
2017                break;
2018            }
2019            case REQUEST_ALL_PSS_MSG: {
2020                synchronized (ActivityManagerService.this) {
2021                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2022                }
2023                break;
2024            }
2025            case START_PROFILES_MSG: {
2026                synchronized (ActivityManagerService.this) {
2027                    mUserController.startProfilesLocked();
2028                }
2029                break;
2030            }
2031            case UPDATE_TIME_PREFERENCE_MSG: {
2032                // The user's time format preference might have changed.
2033                // For convenience we re-use the Intent extra values.
2034                synchronized (ActivityManagerService.this) {
2035                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2036                        ProcessRecord r = mLruProcesses.get(i);
2037                        if (r.thread != null) {
2038                            try {
2039                                r.thread.updateTimePrefs(msg.arg1);
2040                            } catch (RemoteException ex) {
2041                                Slog.w(TAG, "Failed to update preferences for: "
2042                                        + r.info.processName);
2043                            }
2044                        }
2045                    }
2046                }
2047                break;
2048            }
2049            case SYSTEM_USER_START_MSG: {
2050                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2051                        Integer.toString(msg.arg1), msg.arg1);
2052                mSystemServiceManager.startUser(msg.arg1);
2053                break;
2054            }
2055            case SYSTEM_USER_UNLOCK_MSG: {
2056                final int userId = msg.arg1;
2057                mSystemServiceManager.unlockUser(userId);
2058                synchronized (ActivityManagerService.this) {
2059                    mRecentTasks.loadUserRecentsLocked(userId);
2060                }
2061                if (userId == UserHandle.USER_SYSTEM) {
2062                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2063                }
2064                installEncryptionUnawareProviders(userId);
2065                mUserController.finishUserUnlocked((UserState) msg.obj);
2066                break;
2067            }
2068            case SYSTEM_USER_CURRENT_MSG: {
2069                mBatteryStatsService.noteEvent(
2070                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2071                        Integer.toString(msg.arg2), msg.arg2);
2072                mBatteryStatsService.noteEvent(
2073                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2074                        Integer.toString(msg.arg1), msg.arg1);
2075                mSystemServiceManager.switchUser(msg.arg1);
2076                break;
2077            }
2078            case ENTER_ANIMATION_COMPLETE_MSG: {
2079                synchronized (ActivityManagerService.this) {
2080                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2081                    if (r != null && r.app != null && r.app.thread != null) {
2082                        try {
2083                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2084                        } catch (RemoteException e) {
2085                        }
2086                    }
2087                }
2088                break;
2089            }
2090            case FINISH_BOOTING_MSG: {
2091                if (msg.arg1 != 0) {
2092                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2093                    finishBooting();
2094                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2095                }
2096                if (msg.arg2 != 0) {
2097                    enableScreenAfterBoot();
2098                }
2099                break;
2100            }
2101            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2102                try {
2103                    Locale l = (Locale) msg.obj;
2104                    IBinder service = ServiceManager.getService("mount");
2105                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2106                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2107                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2108                } catch (RemoteException e) {
2109                    Log.e(TAG, "Error storing locale for decryption UI", e);
2110                }
2111                break;
2112            }
2113            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2114                final int uid = msg.arg1;
2115                final byte[] firstPacket = (byte[]) msg.obj;
2116
2117                synchronized (mPidsSelfLocked) {
2118                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2119                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2120                        if (p.uid == uid) {
2121                            try {
2122                                p.thread.notifyCleartextNetwork(firstPacket);
2123                            } catch (RemoteException ignored) {
2124                            }
2125                        }
2126                    }
2127                }
2128                break;
2129            }
2130            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2131                final String procName;
2132                final int uid;
2133                final long memLimit;
2134                final String reportPackage;
2135                synchronized (ActivityManagerService.this) {
2136                    procName = mMemWatchDumpProcName;
2137                    uid = mMemWatchDumpUid;
2138                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2139                    if (val == null) {
2140                        val = mMemWatchProcesses.get(procName, 0);
2141                    }
2142                    if (val != null) {
2143                        memLimit = val.first;
2144                        reportPackage = val.second;
2145                    } else {
2146                        memLimit = 0;
2147                        reportPackage = null;
2148                    }
2149                }
2150                if (procName == null) {
2151                    return;
2152                }
2153
2154                if (DEBUG_PSS) Slog.d(TAG_PSS,
2155                        "Showing dump heap notification from " + procName + "/" + uid);
2156
2157                INotificationManager inm = NotificationManager.getService();
2158                if (inm == null) {
2159                    return;
2160                }
2161
2162                String text = mContext.getString(R.string.dump_heap_notification, procName);
2163
2164
2165                Intent deleteIntent = new Intent();
2166                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2167                Intent intent = new Intent();
2168                intent.setClassName("android", DumpHeapActivity.class.getName());
2169                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2170                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2171                if (reportPackage != null) {
2172                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2173                }
2174                int userId = UserHandle.getUserId(uid);
2175                Notification notification = new Notification.Builder(mContext)
2176                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2177                        .setWhen(0)
2178                        .setOngoing(true)
2179                        .setAutoCancel(true)
2180                        .setTicker(text)
2181                        .setColor(mContext.getColor(
2182                                com.android.internal.R.color.system_notification_accent_color))
2183                        .setContentTitle(text)
2184                        .setContentText(
2185                                mContext.getText(R.string.dump_heap_notification_detail))
2186                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2187                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2188                                new UserHandle(userId)))
2189                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2190                                deleteIntent, 0, UserHandle.SYSTEM))
2191                        .build();
2192
2193                try {
2194                    int[] outId = new int[1];
2195                    inm.enqueueNotificationWithTag("android", "android", null,
2196                            R.string.dump_heap_notification,
2197                            notification, outId, userId);
2198                } catch (RuntimeException e) {
2199                    Slog.w(ActivityManagerService.TAG,
2200                            "Error showing notification for dump heap", e);
2201                } catch (RemoteException e) {
2202                }
2203            } break;
2204            case DELETE_DUMPHEAP_MSG: {
2205                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2206                        DumpHeapActivity.JAVA_URI,
2207                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2208                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2209                        UserHandle.myUserId());
2210                synchronized (ActivityManagerService.this) {
2211                    mMemWatchDumpFile = null;
2212                    mMemWatchDumpProcName = null;
2213                    mMemWatchDumpPid = -1;
2214                    mMemWatchDumpUid = -1;
2215                }
2216            } break;
2217            case FOREGROUND_PROFILE_CHANGED_MSG: {
2218                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2219            } break;
2220            case REPORT_TIME_TRACKER_MSG: {
2221                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2222                tracker.deliverResult(mContext);
2223            } break;
2224            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2225                mUserController.dispatchUserSwitchComplete(msg.arg1);
2226            } break;
2227            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2228                mUserController.dispatchLockedBootComplete(msg.arg1);
2229            } break;
2230            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2231                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2232                try {
2233                    connection.shutdown();
2234                } catch (RemoteException e) {
2235                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2236                }
2237                // Only a UiAutomation can set this flag and now that
2238                // it is finished we make sure it is reset to its default.
2239                mUserIsMonkey = false;
2240            } break;
2241            case IDLE_UIDS_MSG: {
2242                idleUids();
2243            } break;
2244            case VR_MODE_CHANGE_MSG: {
2245                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2246                if (vrService == null) {
2247                    break;
2248                }
2249                final ActivityRecord r = (ActivityRecord) msg.obj;
2250                boolean vrMode;
2251                ComponentName requestedPackage;
2252                ComponentName callingPackage;
2253                int userId;
2254                synchronized (ActivityManagerService.this) {
2255                    vrMode = r.requestedVrComponent != null;
2256                    requestedPackage = r.requestedVrComponent;
2257                    userId = r.userId;
2258                    callingPackage = r.info.getComponentName();
2259                    if (mInVrMode != vrMode) {
2260                        mInVrMode = vrMode;
2261                        mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), mInVrMode);
2262                        if (r.app != null) {
2263                            ProcessRecord proc = r.app;
2264                            if (proc.vrThreadTid > 0) {
2265                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2266                                    try {
2267                                        if (mInVrMode == true) {
2268                                            Process.setThreadScheduler(proc.vrThreadTid,
2269                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2270                                        } else {
2271                                            Process.setThreadScheduler(proc.vrThreadTid,
2272                                                Process.SCHED_OTHER, 0);
2273                                        }
2274                                    } catch (IllegalArgumentException e) {
2275                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2276                                                + " not exist:\n" + e);
2277                                    }
2278                                }
2279                            }
2280                        }
2281                    }
2282                }
2283                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2284            } break;
2285            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2286                final ActivityRecord r = (ActivityRecord) msg.obj;
2287                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2288                if (needsVrMode) {
2289                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2290                            r.info.getComponentName(), false);
2291                }
2292            } break;
2293            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2294                synchronized (ActivityManagerService.this) {
2295                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2296                        ProcessRecord r = mLruProcesses.get(i);
2297                        if (r.thread != null) {
2298                            try {
2299                                r.thread.handleTrustStorageUpdate();
2300                            } catch (RemoteException ex) {
2301                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2302                                        r.info.processName);
2303                            }
2304                        }
2305                    }
2306                }
2307            } break;
2308            }
2309        }
2310    };
2311
2312    static final int COLLECT_PSS_BG_MSG = 1;
2313
2314    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2315        @Override
2316        public void handleMessage(Message msg) {
2317            switch (msg.what) {
2318            case COLLECT_PSS_BG_MSG: {
2319                long start = SystemClock.uptimeMillis();
2320                MemInfoReader memInfo = null;
2321                synchronized (ActivityManagerService.this) {
2322                    if (mFullPssPending) {
2323                        mFullPssPending = false;
2324                        memInfo = new MemInfoReader();
2325                    }
2326                }
2327                if (memInfo != null) {
2328                    updateCpuStatsNow();
2329                    long nativeTotalPss = 0;
2330                    final List<ProcessCpuTracker.Stats> stats;
2331                    synchronized (mProcessCpuTracker) {
2332                        stats = mProcessCpuTracker.getStats( (st)-> {
2333                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2334                        });
2335                    }
2336                    final int N = stats.size();
2337                    for (int j = 0; j < N; j++) {
2338                        synchronized (mPidsSelfLocked) {
2339                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2340                                // This is one of our own processes; skip it.
2341                                continue;
2342                            }
2343                        }
2344                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2345                    }
2346                    memInfo.readMemInfo();
2347                    synchronized (ActivityManagerService.this) {
2348                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2349                                + (SystemClock.uptimeMillis()-start) + "ms");
2350                        final long cachedKb = memInfo.getCachedSizeKb();
2351                        final long freeKb = memInfo.getFreeSizeKb();
2352                        final long zramKb = memInfo.getZramTotalSizeKb();
2353                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2354                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2355                                kernelKb*1024, nativeTotalPss*1024);
2356                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2357                                nativeTotalPss);
2358                    }
2359                }
2360
2361                int num = 0;
2362                long[] tmp = new long[2];
2363                do {
2364                    ProcessRecord proc;
2365                    int procState;
2366                    int pid;
2367                    long lastPssTime;
2368                    synchronized (ActivityManagerService.this) {
2369                        if (mPendingPssProcesses.size() <= 0) {
2370                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2371                                    "Collected PSS of " + num + " processes in "
2372                                    + (SystemClock.uptimeMillis() - start) + "ms");
2373                            mPendingPssProcesses.clear();
2374                            return;
2375                        }
2376                        proc = mPendingPssProcesses.remove(0);
2377                        procState = proc.pssProcState;
2378                        lastPssTime = proc.lastPssTime;
2379                        if (proc.thread != null && procState == proc.setProcState
2380                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2381                                        < SystemClock.uptimeMillis()) {
2382                            pid = proc.pid;
2383                        } else {
2384                            proc = null;
2385                            pid = 0;
2386                        }
2387                    }
2388                    if (proc != null) {
2389                        long pss = Debug.getPss(pid, tmp, null);
2390                        synchronized (ActivityManagerService.this) {
2391                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2392                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2393                                num++;
2394                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2395                                        SystemClock.uptimeMillis());
2396                            }
2397                        }
2398                    }
2399                } while (true);
2400            }
2401            }
2402        }
2403    };
2404
2405    public void setSystemProcess() {
2406        try {
2407            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2408            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2409            ServiceManager.addService("meminfo", new MemBinder(this));
2410            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2411            ServiceManager.addService("dbinfo", new DbBinder(this));
2412            if (MONITOR_CPU_USAGE) {
2413                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2414            }
2415            ServiceManager.addService("permission", new PermissionController(this));
2416            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2417
2418            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2419                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2420            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2421
2422            synchronized (this) {
2423                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2424                app.persistent = true;
2425                app.pid = MY_PID;
2426                app.maxAdj = ProcessList.SYSTEM_ADJ;
2427                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2428                synchronized (mPidsSelfLocked) {
2429                    mPidsSelfLocked.put(app.pid, app);
2430                }
2431                updateLruProcessLocked(app, false, null);
2432                updateOomAdjLocked();
2433            }
2434        } catch (PackageManager.NameNotFoundException e) {
2435            throw new RuntimeException(
2436                    "Unable to find android system package", e);
2437        }
2438    }
2439
2440    public void setWindowManager(WindowManagerService wm) {
2441        mWindowManager = wm;
2442        mStackSupervisor.setWindowManager(wm);
2443        mActivityStarter.setWindowManager(wm);
2444    }
2445
2446    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2447        mUsageStatsService = usageStatsManager;
2448    }
2449
2450    public void startObservingNativeCrashes() {
2451        final NativeCrashListener ncl = new NativeCrashListener(this);
2452        ncl.start();
2453    }
2454
2455    public IAppOpsService getAppOpsService() {
2456        return mAppOpsService;
2457    }
2458
2459    static class MemBinder extends Binder {
2460        ActivityManagerService mActivityManagerService;
2461        MemBinder(ActivityManagerService activityManagerService) {
2462            mActivityManagerService = activityManagerService;
2463        }
2464
2465        @Override
2466        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2467            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2468                    != PackageManager.PERMISSION_GRANTED) {
2469                pw.println("Permission Denial: can't dump meminfo from from pid="
2470                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2471                        + " without permission " + android.Manifest.permission.DUMP);
2472                return;
2473            }
2474
2475            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2476        }
2477    }
2478
2479    static class GraphicsBinder extends Binder {
2480        ActivityManagerService mActivityManagerService;
2481        GraphicsBinder(ActivityManagerService activityManagerService) {
2482            mActivityManagerService = activityManagerService;
2483        }
2484
2485        @Override
2486        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2487            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2488                    != PackageManager.PERMISSION_GRANTED) {
2489                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2490                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2491                        + " without permission " + android.Manifest.permission.DUMP);
2492                return;
2493            }
2494
2495            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2496        }
2497    }
2498
2499    static class DbBinder extends Binder {
2500        ActivityManagerService mActivityManagerService;
2501        DbBinder(ActivityManagerService activityManagerService) {
2502            mActivityManagerService = activityManagerService;
2503        }
2504
2505        @Override
2506        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2507            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2508                    != PackageManager.PERMISSION_GRANTED) {
2509                pw.println("Permission Denial: can't dump dbinfo from from pid="
2510                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2511                        + " without permission " + android.Manifest.permission.DUMP);
2512                return;
2513            }
2514
2515            mActivityManagerService.dumpDbInfo(fd, pw, args);
2516        }
2517    }
2518
2519    static class CpuBinder extends Binder {
2520        ActivityManagerService mActivityManagerService;
2521        CpuBinder(ActivityManagerService activityManagerService) {
2522            mActivityManagerService = activityManagerService;
2523        }
2524
2525        @Override
2526        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2527            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2528                    != PackageManager.PERMISSION_GRANTED) {
2529                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2530                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2531                        + " without permission " + android.Manifest.permission.DUMP);
2532                return;
2533            }
2534
2535            synchronized (mActivityManagerService.mProcessCpuTracker) {
2536                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2537                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2538                        SystemClock.uptimeMillis()));
2539            }
2540        }
2541    }
2542
2543    public static final class Lifecycle extends SystemService {
2544        private final ActivityManagerService mService;
2545
2546        public Lifecycle(Context context) {
2547            super(context);
2548            mService = new ActivityManagerService(context);
2549        }
2550
2551        @Override
2552        public void onStart() {
2553            mService.start();
2554        }
2555
2556        public ActivityManagerService getService() {
2557            return mService;
2558        }
2559    }
2560
2561    // Note: This method is invoked on the main thread but may need to attach various
2562    // handlers to other threads.  So take care to be explicit about the looper.
2563    public ActivityManagerService(Context systemContext) {
2564        mContext = systemContext;
2565        mFactoryTest = FactoryTest.getMode();
2566        mSystemThread = ActivityThread.currentActivityThread();
2567
2568        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2569
2570        mPermissionReviewRequired = mContext.getResources().getBoolean(
2571                com.android.internal.R.bool.config_permissionReviewRequired);
2572
2573        mHandlerThread = new ServiceThread(TAG,
2574                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2575        mHandlerThread.start();
2576        mHandler = new MainHandler(mHandlerThread.getLooper());
2577        mUiHandler = new UiHandler();
2578
2579        /* static; one-time init here */
2580        if (sKillHandler == null) {
2581            sKillThread = new ServiceThread(TAG + ":kill",
2582                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2583            sKillThread.start();
2584            sKillHandler = new KillHandler(sKillThread.getLooper());
2585        }
2586
2587        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2588                "foreground", BROADCAST_FG_TIMEOUT, false);
2589        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2590                "background", BROADCAST_BG_TIMEOUT, true);
2591        mBroadcastQueues[0] = mFgBroadcastQueue;
2592        mBroadcastQueues[1] = mBgBroadcastQueue;
2593
2594        mServices = new ActiveServices(this);
2595        mProviderMap = new ProviderMap(this);
2596        mAppErrors = new AppErrors(mContext, this);
2597
2598        // TODO: Move creation of battery stats service outside of activity manager service.
2599        File dataDir = Environment.getDataDirectory();
2600        File systemDir = new File(dataDir, "system");
2601        systemDir.mkdirs();
2602        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2603        mBatteryStatsService.getActiveStatistics().readLocked();
2604        mBatteryStatsService.scheduleWriteToDisk();
2605        mOnBattery = DEBUG_POWER ? true
2606                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2607        mBatteryStatsService.getActiveStatistics().setCallback(this);
2608
2609        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2610
2611        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2612        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2613                new IAppOpsCallback.Stub() {
2614                    @Override public void opChanged(int op, int uid, String packageName) {
2615                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2616                            if (mAppOpsService.checkOperation(op, uid, packageName)
2617                                    != AppOpsManager.MODE_ALLOWED) {
2618                                runInBackgroundDisabled(uid);
2619                            }
2620                        }
2621                    }
2622                });
2623
2624        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2625
2626        mUserController = new UserController(this);
2627
2628        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2629            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2630
2631        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2632            mUseFifoUiScheduling = true;
2633        }
2634
2635        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2636
2637        mTempConfig.setToDefaults();
2638        mTempConfig.setLocales(LocaleList.getDefault());
2639        mConfigurationSeq = mTempConfig.seq = 1;
2640
2641        mProcessCpuTracker.init();
2642
2643        mStackSupervisor = new ActivityStackSupervisor(this);
2644        mStackSupervisor.onConfigurationChanged(mTempConfig);
2645        mKeyguardController = mStackSupervisor.mKeyguardController;
2646        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2647        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2648        mTaskChangeNotificationController =
2649                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2650        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2651        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2652
2653        mProcessCpuThread = new Thread("CpuTracker") {
2654            @Override
2655            public void run() {
2656                while (true) {
2657                    try {
2658                        try {
2659                            synchronized(this) {
2660                                final long now = SystemClock.uptimeMillis();
2661                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2662                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2663                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2664                                //        + ", write delay=" + nextWriteDelay);
2665                                if (nextWriteDelay < nextCpuDelay) {
2666                                    nextCpuDelay = nextWriteDelay;
2667                                }
2668                                if (nextCpuDelay > 0) {
2669                                    mProcessCpuMutexFree.set(true);
2670                                    this.wait(nextCpuDelay);
2671                                }
2672                            }
2673                        } catch (InterruptedException e) {
2674                        }
2675                        updateCpuStatsNow();
2676                    } catch (Exception e) {
2677                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2678                    }
2679                }
2680            }
2681        };
2682
2683        Watchdog.getInstance().addMonitor(this);
2684        Watchdog.getInstance().addThread(mHandler);
2685    }
2686
2687    public void setSystemServiceManager(SystemServiceManager mgr) {
2688        mSystemServiceManager = mgr;
2689    }
2690
2691    public void setInstaller(Installer installer) {
2692        mInstaller = installer;
2693    }
2694
2695    private void start() {
2696        Process.removeAllProcessGroups();
2697        mProcessCpuThread.start();
2698
2699        mBatteryStatsService.publish(mContext);
2700        mAppOpsService.publish(mContext);
2701        Slog.d("AppOps", "AppOpsService published");
2702        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2703    }
2704
2705    void onUserStoppedLocked(int userId) {
2706        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2707    }
2708
2709    public void initPowerManagement() {
2710        mStackSupervisor.initPowerManagement();
2711        mBatteryStatsService.initPowerManagement();
2712        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2713        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2714        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2715        mVoiceWakeLock.setReferenceCounted(false);
2716    }
2717
2718    @Override
2719    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2720            throws RemoteException {
2721        if (code == SYSPROPS_TRANSACTION) {
2722            // We need to tell all apps about the system property change.
2723            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2724            synchronized(this) {
2725                final int NP = mProcessNames.getMap().size();
2726                for (int ip=0; ip<NP; ip++) {
2727                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2728                    final int NA = apps.size();
2729                    for (int ia=0; ia<NA; ia++) {
2730                        ProcessRecord app = apps.valueAt(ia);
2731                        if (app.thread != null) {
2732                            procs.add(app.thread.asBinder());
2733                        }
2734                    }
2735                }
2736            }
2737
2738            int N = procs.size();
2739            for (int i=0; i<N; i++) {
2740                Parcel data2 = Parcel.obtain();
2741                try {
2742                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2743                            Binder.FLAG_ONEWAY);
2744                } catch (RemoteException e) {
2745                }
2746                data2.recycle();
2747            }
2748        }
2749        try {
2750            return super.onTransact(code, data, reply, flags);
2751        } catch (RuntimeException e) {
2752            // The activity manager only throws security exceptions, so let's
2753            // log all others.
2754            if (!(e instanceof SecurityException)) {
2755                Slog.wtf(TAG, "Activity Manager Crash", e);
2756            }
2757            throw e;
2758        }
2759    }
2760
2761    void updateCpuStats() {
2762        final long now = SystemClock.uptimeMillis();
2763        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2764            return;
2765        }
2766        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2767            synchronized (mProcessCpuThread) {
2768                mProcessCpuThread.notify();
2769            }
2770        }
2771    }
2772
2773    void updateCpuStatsNow() {
2774        synchronized (mProcessCpuTracker) {
2775            mProcessCpuMutexFree.set(false);
2776            final long now = SystemClock.uptimeMillis();
2777            boolean haveNewCpuStats = false;
2778
2779            if (MONITOR_CPU_USAGE &&
2780                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2781                mLastCpuTime.set(now);
2782                mProcessCpuTracker.update();
2783                if (mProcessCpuTracker.hasGoodLastStats()) {
2784                    haveNewCpuStats = true;
2785                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2786                    //Slog.i(TAG, "Total CPU usage: "
2787                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2788
2789                    // Slog the cpu usage if the property is set.
2790                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2791                        int user = mProcessCpuTracker.getLastUserTime();
2792                        int system = mProcessCpuTracker.getLastSystemTime();
2793                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2794                        int irq = mProcessCpuTracker.getLastIrqTime();
2795                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2796                        int idle = mProcessCpuTracker.getLastIdleTime();
2797
2798                        int total = user + system + iowait + irq + softIrq + idle;
2799                        if (total == 0) total = 1;
2800
2801                        EventLog.writeEvent(EventLogTags.CPU,
2802                                ((user+system+iowait+irq+softIrq) * 100) / total,
2803                                (user * 100) / total,
2804                                (system * 100) / total,
2805                                (iowait * 100) / total,
2806                                (irq * 100) / total,
2807                                (softIrq * 100) / total);
2808                    }
2809                }
2810            }
2811
2812            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2813            synchronized(bstats) {
2814                synchronized(mPidsSelfLocked) {
2815                    if (haveNewCpuStats) {
2816                        if (bstats.startAddingCpuLocked()) {
2817                            int totalUTime = 0;
2818                            int totalSTime = 0;
2819                            final int N = mProcessCpuTracker.countStats();
2820                            for (int i=0; i<N; i++) {
2821                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2822                                if (!st.working) {
2823                                    continue;
2824                                }
2825                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2826                                totalUTime += st.rel_utime;
2827                                totalSTime += st.rel_stime;
2828                                if (pr != null) {
2829                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2830                                    if (ps == null || !ps.isActive()) {
2831                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2832                                                pr.info.uid, pr.processName);
2833                                    }
2834                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2835                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2836                                } else {
2837                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2838                                    if (ps == null || !ps.isActive()) {
2839                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2840                                                bstats.mapUid(st.uid), st.name);
2841                                    }
2842                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2843                                }
2844                            }
2845                            final int userTime = mProcessCpuTracker.getLastUserTime();
2846                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2847                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2848                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2849                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2850                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2851                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2852                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2853                        }
2854                    }
2855                }
2856
2857                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2858                    mLastWriteTime = now;
2859                    mBatteryStatsService.scheduleWriteToDisk();
2860                }
2861            }
2862        }
2863    }
2864
2865    @Override
2866    public void batteryNeedsCpuUpdate() {
2867        updateCpuStatsNow();
2868    }
2869
2870    @Override
2871    public void batteryPowerChanged(boolean onBattery) {
2872        // When plugging in, update the CPU stats first before changing
2873        // the plug state.
2874        updateCpuStatsNow();
2875        synchronized (this) {
2876            synchronized(mPidsSelfLocked) {
2877                mOnBattery = DEBUG_POWER ? true : onBattery;
2878            }
2879        }
2880    }
2881
2882    @Override
2883    public void batterySendBroadcast(Intent intent) {
2884        synchronized (this) {
2885            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2886                    AppOpsManager.OP_NONE, null, false, false,
2887                    -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2888        }
2889    }
2890
2891    /**
2892     * Initialize the application bind args. These are passed to each
2893     * process when the bindApplication() IPC is sent to the process. They're
2894     * lazily setup to make sure the services are running when they're asked for.
2895     */
2896    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2897        // Isolated processes won't get this optimization, so that we don't
2898        // violate the rules about which services they have access to.
2899        if (isolated) {
2900            if (mIsolatedAppBindArgs == null) {
2901                mIsolatedAppBindArgs = new HashMap<>();
2902                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2903            }
2904            return mIsolatedAppBindArgs;
2905        }
2906
2907        if (mAppBindArgs == null) {
2908            mAppBindArgs = new HashMap<>();
2909
2910            // Setup the application init args
2911            mAppBindArgs.put("package", ServiceManager.getService("package"));
2912            mAppBindArgs.put("window", ServiceManager.getService("window"));
2913            mAppBindArgs.put(Context.ALARM_SERVICE,
2914                    ServiceManager.getService(Context.ALARM_SERVICE));
2915        }
2916        return mAppBindArgs;
2917    }
2918
2919    /**
2920     * Update AMS states when an activity is resumed. This should only be called by
2921     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
2922     */
2923    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
2924        if (r.task.isApplicationTask()) {
2925            if (mCurAppTimeTracker != r.appTimeTracker) {
2926                // We are switching app tracking.  Complete the current one.
2927                if (mCurAppTimeTracker != null) {
2928                    mCurAppTimeTracker.stop();
2929                    mHandler.obtainMessage(
2930                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2931                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2932                    mCurAppTimeTracker = null;
2933                }
2934                if (r.appTimeTracker != null) {
2935                    mCurAppTimeTracker = r.appTimeTracker;
2936                    startTimeTrackingFocusedActivityLocked();
2937                }
2938            } else {
2939                startTimeTrackingFocusedActivityLocked();
2940            }
2941        } else {
2942            r.appTimeTracker = null;
2943        }
2944        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2945        // TODO: Probably not, because we don't want to resume voice on switching
2946        // back to this activity
2947        if (r.task.voiceInteractor != null) {
2948            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2949        } else {
2950            finishRunningVoiceLocked();
2951            IVoiceInteractionSession session;
2952            if (mLastResumedActivity != null
2953                    && ((session = mLastResumedActivity.task.voiceSession) != null
2954                    || (session = mLastResumedActivity.voiceSession) != null)) {
2955                // We had been in a voice interaction session, but now focused has
2956                // move to something different.  Just finish the session, we can't
2957                // return to it and retain the proper state and synchronization with
2958                // the voice interaction service.
2959                finishVoiceTask(session);
2960            }
2961        }
2962
2963        mWindowManager.setFocusedApp(r.appToken, true);
2964
2965        applyUpdateLockStateLocked(r);
2966        applyUpdateVrModeLocked(r);
2967        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
2968            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2969            mHandler.obtainMessage(
2970                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
2971        }
2972
2973        mLastResumedActivity = r;
2974
2975        EventLogTags.writeAmSetResumedActivity(
2976                r == null ? -1 : r.userId,
2977                r == null ? "NULL" : r.shortComponentName,
2978                reason);
2979    }
2980
2981    @Override
2982    public void setFocusedStack(int stackId) {
2983        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2984        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2985        final long callingId = Binder.clearCallingIdentity();
2986        try {
2987            synchronized (this) {
2988                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2989                if (stack == null) {
2990                    return;
2991                }
2992                final ActivityRecord r = stack.topRunningActivityLocked();
2993                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
2994                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2995                }
2996            }
2997        } finally {
2998            Binder.restoreCallingIdentity(callingId);
2999        }
3000    }
3001
3002    @Override
3003    public void setFocusedTask(int taskId) {
3004        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3005        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3006        final long callingId = Binder.clearCallingIdentity();
3007        try {
3008            synchronized (this) {
3009                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3010                if (task == null) {
3011                    return;
3012                }
3013                final ActivityRecord r = task.topRunningActivityLocked();
3014                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3015                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3016                }
3017            }
3018        } finally {
3019            Binder.restoreCallingIdentity(callingId);
3020        }
3021    }
3022
3023    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3024    @Override
3025    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3026        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3027        mTaskChangeNotificationController.registerTaskStackListener(listener);
3028    }
3029
3030    /**
3031     * Unregister a task stack listener so that it stops receiving callbacks.
3032     */
3033    @Override
3034    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3035         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3036         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3037     }
3038
3039    @Override
3040    public void notifyActivityDrawn(IBinder token) {
3041        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3042        synchronized (this) {
3043            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3044            if (r != null) {
3045                r.getStack().notifyActivityDrawnLocked(r);
3046            }
3047        }
3048    }
3049
3050    final void applyUpdateLockStateLocked(ActivityRecord r) {
3051        // Modifications to the UpdateLock state are done on our handler, outside
3052        // the activity manager's locks.  The new state is determined based on the
3053        // state *now* of the relevant activity record.  The object is passed to
3054        // the handler solely for logging detail, not to be consulted/modified.
3055        final boolean nextState = r != null && r.immersive;
3056        mHandler.sendMessage(
3057                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3058    }
3059
3060    final void applyUpdateVrModeLocked(ActivityRecord r) {
3061        mHandler.sendMessage(
3062                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3063    }
3064
3065    void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3066        mHandler.sendMessage(
3067                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3068    }
3069
3070    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3071            ComponentName callingPackage, boolean immediate) {
3072        VrManagerInternal vrService =
3073                LocalServices.getService(VrManagerInternal.class);
3074        if (immediate) {
3075            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3076        } else {
3077            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3078        }
3079    }
3080
3081    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3082        Message msg = Message.obtain();
3083        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3084        msg.obj = r.task.askedCompatMode ? null : r;
3085        mUiHandler.sendMessage(msg);
3086    }
3087
3088    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3089        final Configuration globalConfig = getGlobalConfiguration();
3090        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3091                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3092            final Message msg = Message.obtain();
3093            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3094            msg.obj = r;
3095            mUiHandler.sendMessage(msg);
3096        }
3097    }
3098
3099    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3100            String what, Object obj, ProcessRecord srcApp) {
3101        app.lastActivityTime = now;
3102
3103        if (app.activities.size() > 0) {
3104            // Don't want to touch dependent processes that are hosting activities.
3105            return index;
3106        }
3107
3108        int lrui = mLruProcesses.lastIndexOf(app);
3109        if (lrui < 0) {
3110            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3111                    + what + " " + obj + " from " + srcApp);
3112            return index;
3113        }
3114
3115        if (lrui >= index) {
3116            // Don't want to cause this to move dependent processes *back* in the
3117            // list as if they were less frequently used.
3118            return index;
3119        }
3120
3121        if (lrui >= mLruProcessActivityStart) {
3122            // Don't want to touch dependent processes that are hosting activities.
3123            return index;
3124        }
3125
3126        mLruProcesses.remove(lrui);
3127        if (index > 0) {
3128            index--;
3129        }
3130        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3131                + " in LRU list: " + app);
3132        mLruProcesses.add(index, app);
3133        return index;
3134    }
3135
3136    static void killProcessGroup(int uid, int pid) {
3137        if (sKillHandler != null) {
3138            sKillHandler.sendMessage(
3139                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3140        } else {
3141            Slog.w(TAG, "Asked to kill process group before system bringup!");
3142            Process.killProcessGroup(uid, pid);
3143        }
3144    }
3145
3146    final void removeLruProcessLocked(ProcessRecord app) {
3147        int lrui = mLruProcesses.lastIndexOf(app);
3148        if (lrui >= 0) {
3149            if (!app.killed) {
3150                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3151                Process.killProcessQuiet(app.pid);
3152                killProcessGroup(app.uid, app.pid);
3153            }
3154            if (lrui <= mLruProcessActivityStart) {
3155                mLruProcessActivityStart--;
3156            }
3157            if (lrui <= mLruProcessServiceStart) {
3158                mLruProcessServiceStart--;
3159            }
3160            mLruProcesses.remove(lrui);
3161        }
3162    }
3163
3164    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3165            ProcessRecord client) {
3166        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3167                || app.treatLikeActivity;
3168        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3169        if (!activityChange && hasActivity) {
3170            // The process has activities, so we are only allowing activity-based adjustments
3171            // to move it.  It should be kept in the front of the list with other
3172            // processes that have activities, and we don't want those to change their
3173            // order except due to activity operations.
3174            return;
3175        }
3176
3177        mLruSeq++;
3178        final long now = SystemClock.uptimeMillis();
3179        app.lastActivityTime = now;
3180
3181        // First a quick reject: if the app is already at the position we will
3182        // put it, then there is nothing to do.
3183        if (hasActivity) {
3184            final int N = mLruProcesses.size();
3185            if (N > 0 && mLruProcesses.get(N-1) == app) {
3186                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3187                return;
3188            }
3189        } else {
3190            if (mLruProcessServiceStart > 0
3191                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3192                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3193                return;
3194            }
3195        }
3196
3197        int lrui = mLruProcesses.lastIndexOf(app);
3198
3199        if (app.persistent && lrui >= 0) {
3200            // We don't care about the position of persistent processes, as long as
3201            // they are in the list.
3202            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3203            return;
3204        }
3205
3206        /* In progress: compute new position first, so we can avoid doing work
3207           if the process is not actually going to move.  Not yet working.
3208        int addIndex;
3209        int nextIndex;
3210        boolean inActivity = false, inService = false;
3211        if (hasActivity) {
3212            // Process has activities, put it at the very tipsy-top.
3213            addIndex = mLruProcesses.size();
3214            nextIndex = mLruProcessServiceStart;
3215            inActivity = true;
3216        } else if (hasService) {
3217            // Process has services, put it at the top of the service list.
3218            addIndex = mLruProcessActivityStart;
3219            nextIndex = mLruProcessServiceStart;
3220            inActivity = true;
3221            inService = true;
3222        } else  {
3223            // Process not otherwise of interest, it goes to the top of the non-service area.
3224            addIndex = mLruProcessServiceStart;
3225            if (client != null) {
3226                int clientIndex = mLruProcesses.lastIndexOf(client);
3227                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3228                        + app);
3229                if (clientIndex >= 0 && addIndex > clientIndex) {
3230                    addIndex = clientIndex;
3231                }
3232            }
3233            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3234        }
3235
3236        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3237                + mLruProcessActivityStart + "): " + app);
3238        */
3239
3240        if (lrui >= 0) {
3241            if (lrui < mLruProcessActivityStart) {
3242                mLruProcessActivityStart--;
3243            }
3244            if (lrui < mLruProcessServiceStart) {
3245                mLruProcessServiceStart--;
3246            }
3247            /*
3248            if (addIndex > lrui) {
3249                addIndex--;
3250            }
3251            if (nextIndex > lrui) {
3252                nextIndex--;
3253            }
3254            */
3255            mLruProcesses.remove(lrui);
3256        }
3257
3258        /*
3259        mLruProcesses.add(addIndex, app);
3260        if (inActivity) {
3261            mLruProcessActivityStart++;
3262        }
3263        if (inService) {
3264            mLruProcessActivityStart++;
3265        }
3266        */
3267
3268        int nextIndex;
3269        if (hasActivity) {
3270            final int N = mLruProcesses.size();
3271            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3272                // Process doesn't have activities, but has clients with
3273                // activities...  move it up, but one below the top (the top
3274                // should always have a real activity).
3275                if (DEBUG_LRU) Slog.d(TAG_LRU,
3276                        "Adding to second-top of LRU activity list: " + app);
3277                mLruProcesses.add(N - 1, app);
3278                // To keep it from spamming the LRU list (by making a bunch of clients),
3279                // we will push down any other entries owned by the app.
3280                final int uid = app.info.uid;
3281                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3282                    ProcessRecord subProc = mLruProcesses.get(i);
3283                    if (subProc.info.uid == uid) {
3284                        // We want to push this one down the list.  If the process after
3285                        // it is for the same uid, however, don't do so, because we don't
3286                        // want them internally to be re-ordered.
3287                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3288                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3289                                    "Pushing uid " + uid + " swapping at " + i + ": "
3290                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3291                            ProcessRecord tmp = mLruProcesses.get(i);
3292                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3293                            mLruProcesses.set(i - 1, tmp);
3294                            i--;
3295                        }
3296                    } else {
3297                        // A gap, we can stop here.
3298                        break;
3299                    }
3300                }
3301            } else {
3302                // Process has activities, put it at the very tipsy-top.
3303                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3304                mLruProcesses.add(app);
3305            }
3306            nextIndex = mLruProcessServiceStart;
3307        } else if (hasService) {
3308            // Process has services, put it at the top of the service list.
3309            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3310            mLruProcesses.add(mLruProcessActivityStart, app);
3311            nextIndex = mLruProcessServiceStart;
3312            mLruProcessActivityStart++;
3313        } else  {
3314            // Process not otherwise of interest, it goes to the top of the non-service area.
3315            int index = mLruProcessServiceStart;
3316            if (client != null) {
3317                // If there is a client, don't allow the process to be moved up higher
3318                // in the list than that client.
3319                int clientIndex = mLruProcesses.lastIndexOf(client);
3320                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3321                        + " when updating " + app);
3322                if (clientIndex <= lrui) {
3323                    // Don't allow the client index restriction to push it down farther in the
3324                    // list than it already is.
3325                    clientIndex = lrui;
3326                }
3327                if (clientIndex >= 0 && index > clientIndex) {
3328                    index = clientIndex;
3329                }
3330            }
3331            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3332            mLruProcesses.add(index, app);
3333            nextIndex = index-1;
3334            mLruProcessActivityStart++;
3335            mLruProcessServiceStart++;
3336        }
3337
3338        // If the app is currently using a content provider or service,
3339        // bump those processes as well.
3340        for (int j=app.connections.size()-1; j>=0; j--) {
3341            ConnectionRecord cr = app.connections.valueAt(j);
3342            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3343                    && cr.binding.service.app != null
3344                    && cr.binding.service.app.lruSeq != mLruSeq
3345                    && !cr.binding.service.app.persistent) {
3346                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3347                        "service connection", cr, app);
3348            }
3349        }
3350        for (int j=app.conProviders.size()-1; j>=0; j--) {
3351            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3352            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3353                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3354                        "provider reference", cpr, app);
3355            }
3356        }
3357    }
3358
3359    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3360        if (uid == Process.SYSTEM_UID) {
3361            // The system gets to run in any process.  If there are multiple
3362            // processes with the same uid, just pick the first (this
3363            // should never happen).
3364            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3365            if (procs == null) return null;
3366            final int procCount = procs.size();
3367            for (int i = 0; i < procCount; i++) {
3368                final int procUid = procs.keyAt(i);
3369                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3370                    // Don't use an app process or different user process for system component.
3371                    continue;
3372                }
3373                return procs.valueAt(i);
3374            }
3375        }
3376        ProcessRecord proc = mProcessNames.get(processName, uid);
3377        if (false && proc != null && !keepIfLarge
3378                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3379                && proc.lastCachedPss >= 4000) {
3380            // Turn this condition on to cause killing to happen regularly, for testing.
3381            if (proc.baseProcessTracker != null) {
3382                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3383            }
3384            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3385        } else if (proc != null && !keepIfLarge
3386                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3387                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3388            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3389            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3390                if (proc.baseProcessTracker != null) {
3391                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3392                }
3393                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3394            }
3395        }
3396        return proc;
3397    }
3398
3399    void notifyPackageUse(String packageName, int reason) {
3400        IPackageManager pm = AppGlobals.getPackageManager();
3401        try {
3402            pm.notifyPackageUse(packageName, reason);
3403        } catch (RemoteException e) {
3404        }
3405    }
3406
3407    boolean isNextTransitionForward() {
3408        int transit = mWindowManager.getPendingAppTransition();
3409        return transit == TRANSIT_ACTIVITY_OPEN
3410                || transit == TRANSIT_TASK_OPEN
3411                || transit == TRANSIT_TASK_TO_FRONT;
3412    }
3413
3414    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3415            String processName, String abiOverride, int uid, Runnable crashHandler) {
3416        synchronized(this) {
3417            ApplicationInfo info = new ApplicationInfo();
3418            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3419            // For isolated processes, the former contains the parent's uid and the latter the
3420            // actual uid of the isolated process.
3421            // In the special case introduced by this method (which is, starting an isolated
3422            // process directly from the SystemServer without an actual parent app process) the
3423            // closest thing to a parent's uid is SYSTEM_UID.
3424            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3425            // the |isolated| logic in the ProcessRecord constructor.
3426            info.uid = Process.SYSTEM_UID;
3427            info.processName = processName;
3428            info.className = entryPoint;
3429            info.packageName = "android";
3430            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3431                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3432                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3433                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3434                    crashHandler);
3435            return proc != null ? proc.pid : 0;
3436        }
3437    }
3438
3439    final ProcessRecord startProcessLocked(String processName,
3440            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3441            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3442            boolean isolated, boolean keepIfLarge) {
3443        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3444                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3445                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3446                null /* crashHandler */);
3447    }
3448
3449    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3450            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3451            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3452            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3453        long startTime = SystemClock.elapsedRealtime();
3454        ProcessRecord app;
3455        if (!isolated) {
3456            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3457            checkTime(startTime, "startProcess: after getProcessRecord");
3458
3459            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3460                // If we are in the background, then check to see if this process
3461                // is bad.  If so, we will just silently fail.
3462                if (mAppErrors.isBadProcessLocked(info)) {
3463                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3464                            + "/" + info.processName);
3465                    return null;
3466                }
3467            } else {
3468                // When the user is explicitly starting a process, then clear its
3469                // crash count so that we won't make it bad until they see at
3470                // least one crash dialog again, and make the process good again
3471                // if it had been bad.
3472                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3473                        + "/" + info.processName);
3474                mAppErrors.resetProcessCrashTimeLocked(info);
3475                if (mAppErrors.isBadProcessLocked(info)) {
3476                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3477                            UserHandle.getUserId(info.uid), info.uid,
3478                            info.processName);
3479                    mAppErrors.clearBadProcessLocked(info);
3480                    if (app != null) {
3481                        app.bad = false;
3482                    }
3483                }
3484            }
3485        } else {
3486            // If this is an isolated process, it can't re-use an existing process.
3487            app = null;
3488        }
3489
3490        // We don't have to do anything more if:
3491        // (1) There is an existing application record; and
3492        // (2) The caller doesn't think it is dead, OR there is no thread
3493        //     object attached to it so we know it couldn't have crashed; and
3494        // (3) There is a pid assigned to it, so it is either starting or
3495        //     already running.
3496        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3497                + " app=" + app + " knownToBeDead=" + knownToBeDead
3498                + " thread=" + (app != null ? app.thread : null)
3499                + " pid=" + (app != null ? app.pid : -1));
3500        if (app != null && app.pid > 0) {
3501            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3502                // We already have the app running, or are waiting for it to
3503                // come up (we have a pid but not yet its thread), so keep it.
3504                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3505                // If this is a new package in the process, add the package to the list
3506                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3507                checkTime(startTime, "startProcess: done, added package to proc");
3508                return app;
3509            }
3510
3511            // An application record is attached to a previous process,
3512            // clean it up now.
3513            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3514            checkTime(startTime, "startProcess: bad proc running, killing");
3515            killProcessGroup(app.uid, app.pid);
3516            handleAppDiedLocked(app, true, true);
3517            checkTime(startTime, "startProcess: done killing old proc");
3518        }
3519
3520        String hostingNameStr = hostingName != null
3521                ? hostingName.flattenToShortString() : null;
3522
3523        if (app == null) {
3524            checkTime(startTime, "startProcess: creating new process record");
3525            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3526            if (app == null) {
3527                Slog.w(TAG, "Failed making new process record for "
3528                        + processName + "/" + info.uid + " isolated=" + isolated);
3529                return null;
3530            }
3531            app.crashHandler = crashHandler;
3532            checkTime(startTime, "startProcess: done creating new process record");
3533        } else {
3534            // If this is a new package in the process, add the package to the list
3535            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3536            checkTime(startTime, "startProcess: added package to existing proc");
3537        }
3538
3539        // If the system is not ready yet, then hold off on starting this
3540        // process until it is.
3541        if (!mProcessesReady
3542                && !isAllowedWhileBooting(info)
3543                && !allowWhileBooting) {
3544            if (!mProcessesOnHold.contains(app)) {
3545                mProcessesOnHold.add(app);
3546            }
3547            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3548                    "System not ready, putting on hold: " + app);
3549            checkTime(startTime, "startProcess: returning with proc on hold");
3550            return app;
3551        }
3552
3553        checkTime(startTime, "startProcess: stepping in to startProcess");
3554        startProcessLocked(
3555                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3556        checkTime(startTime, "startProcess: done starting proc!");
3557        return (app.pid != 0) ? app : null;
3558    }
3559
3560    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3561        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3562    }
3563
3564    private final void startProcessLocked(ProcessRecord app,
3565            String hostingType, String hostingNameStr) {
3566        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3567                null /* entryPoint */, null /* entryPointArgs */);
3568    }
3569
3570    private final void startProcessLocked(ProcessRecord app, String hostingType,
3571            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3572        long startTime = SystemClock.elapsedRealtime();
3573        if (app.pid > 0 && app.pid != MY_PID) {
3574            checkTime(startTime, "startProcess: removing from pids map");
3575            synchronized (mPidsSelfLocked) {
3576                mPidsSelfLocked.remove(app.pid);
3577                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3578            }
3579            checkTime(startTime, "startProcess: done removing from pids map");
3580            app.setPid(0);
3581        }
3582
3583        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3584                "startProcessLocked removing on hold: " + app);
3585        mProcessesOnHold.remove(app);
3586
3587        checkTime(startTime, "startProcess: starting to update cpu stats");
3588        updateCpuStats();
3589        checkTime(startTime, "startProcess: done updating cpu stats");
3590
3591        try {
3592            try {
3593                final int userId = UserHandle.getUserId(app.uid);
3594                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3595            } catch (RemoteException e) {
3596                throw e.rethrowAsRuntimeException();
3597            }
3598
3599            int uid = app.uid;
3600            int[] gids = null;
3601            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3602            if (!app.isolated) {
3603                int[] permGids = null;
3604                try {
3605                    checkTime(startTime, "startProcess: getting gids from package manager");
3606                    final IPackageManager pm = AppGlobals.getPackageManager();
3607                    permGids = pm.getPackageGids(app.info.packageName,
3608                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3609                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3610                            StorageManagerInternal.class);
3611                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3612                            app.info.packageName);
3613                } catch (RemoteException e) {
3614                    throw e.rethrowAsRuntimeException();
3615                }
3616
3617                /*
3618                 * Add shared application and profile GIDs so applications can share some
3619                 * resources like shared libraries and access user-wide resources
3620                 */
3621                if (ArrayUtils.isEmpty(permGids)) {
3622                    gids = new int[2];
3623                } else {
3624                    gids = new int[permGids.length + 2];
3625                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3626                }
3627                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3628                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3629            }
3630            checkTime(startTime, "startProcess: building args");
3631            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3632                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3633                        && mTopComponent != null
3634                        && app.processName.equals(mTopComponent.getPackageName())) {
3635                    uid = 0;
3636                }
3637                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3638                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3639                    uid = 0;
3640                }
3641            }
3642            int debugFlags = 0;
3643            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3644                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3645                // Also turn on CheckJNI for debuggable apps. It's quite
3646                // awkward to turn on otherwise.
3647                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3648            }
3649            // Run the app in safe mode if its manifest requests so or the
3650            // system is booted in safe mode.
3651            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3652                mSafeMode == true) {
3653                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3654            }
3655            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3656                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3657            }
3658            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3659            if ("true".equals(genDebugInfoProperty)) {
3660                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3661            }
3662            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3663                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3664            }
3665            if ("1".equals(SystemProperties.get("debug.assert"))) {
3666                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3667            }
3668            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3669                // Enable all debug flags required by the native debugger.
3670                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3671                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3672                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3673                mNativeDebuggingApp = null;
3674            }
3675
3676            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3677            if (requiredAbi == null) {
3678                requiredAbi = Build.SUPPORTED_ABIS[0];
3679            }
3680
3681            String instructionSet = null;
3682            if (app.info.primaryCpuAbi != null) {
3683                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3684            }
3685
3686            app.gids = gids;
3687            app.requiredAbi = requiredAbi;
3688            app.instructionSet = instructionSet;
3689
3690            // Start the process.  It will either succeed and return a result containing
3691            // the PID of the new process, or else throw a RuntimeException.
3692            boolean isActivityProcess = (entryPoint == null);
3693            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3694            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3695                    app.processName);
3696            checkTime(startTime, "startProcess: asking zygote to start proc");
3697            Process.ProcessStartResult startResult = Process.start(entryPoint,
3698                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3699                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3700                    app.info.dataDir, entryPointArgs);
3701            checkTime(startTime, "startProcess: returned from zygote!");
3702            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3703
3704            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3705            checkTime(startTime, "startProcess: done updating battery stats");
3706
3707            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3708                    UserHandle.getUserId(uid), startResult.pid, uid,
3709                    app.processName, hostingType,
3710                    hostingNameStr != null ? hostingNameStr : "");
3711
3712            try {
3713                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3714                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3715            } catch (RemoteException ex) {
3716                // Ignore
3717            }
3718
3719            if (app.persistent) {
3720                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3721            }
3722
3723            checkTime(startTime, "startProcess: building log message");
3724            StringBuilder buf = mStringBuilder;
3725            buf.setLength(0);
3726            buf.append("Start proc ");
3727            buf.append(startResult.pid);
3728            buf.append(':');
3729            buf.append(app.processName);
3730            buf.append('/');
3731            UserHandle.formatUid(buf, uid);
3732            if (!isActivityProcess) {
3733                buf.append(" [");
3734                buf.append(entryPoint);
3735                buf.append("]");
3736            }
3737            buf.append(" for ");
3738            buf.append(hostingType);
3739            if (hostingNameStr != null) {
3740                buf.append(" ");
3741                buf.append(hostingNameStr);
3742            }
3743            Slog.i(TAG, buf.toString());
3744            app.setPid(startResult.pid);
3745            app.usingWrapper = startResult.usingWrapper;
3746            app.removed = false;
3747            app.killed = false;
3748            app.killedByAm = false;
3749            checkTime(startTime, "startProcess: starting to update pids map");
3750            ProcessRecord oldApp;
3751            synchronized (mPidsSelfLocked) {
3752                oldApp = mPidsSelfLocked.get(startResult.pid);
3753            }
3754            // If there is already an app occupying that pid that hasn't been cleaned up
3755            if (oldApp != null && !app.isolated) {
3756                // Clean up anything relating to this pid first
3757                Slog.w(TAG, "Reusing pid " + startResult.pid
3758                        + " while app is still mapped to it");
3759                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3760                        true /*replacingPid*/);
3761            }
3762            synchronized (mPidsSelfLocked) {
3763                this.mPidsSelfLocked.put(startResult.pid, app);
3764                if (isActivityProcess) {
3765                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3766                    msg.obj = app;
3767                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3768                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3769                }
3770            }
3771            checkTime(startTime, "startProcess: done updating pids map");
3772        } catch (RuntimeException e) {
3773            Slog.e(TAG, "Failure starting process " + app.processName, e);
3774
3775            // Something went very wrong while trying to start this process; one
3776            // common case is when the package is frozen due to an active
3777            // upgrade. To recover, clean up any active bookkeeping related to
3778            // starting this process. (We already invoked this method once when
3779            // the package was initially frozen through KILL_APPLICATION_MSG, so
3780            // it doesn't hurt to use it again.)
3781            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3782                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3783        }
3784    }
3785
3786    void updateUsageStats(ActivityRecord component, boolean resumed) {
3787        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3788                "updateUsageStats: comp=" + component + "res=" + resumed);
3789        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3790        if (resumed) {
3791            if (mUsageStatsService != null) {
3792                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3793                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3794            }
3795            synchronized (stats) {
3796                stats.noteActivityResumedLocked(component.app.uid);
3797            }
3798        } else {
3799            if (mUsageStatsService != null) {
3800                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3801                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3802            }
3803            synchronized (stats) {
3804                stats.noteActivityPausedLocked(component.app.uid);
3805            }
3806        }
3807    }
3808
3809    Intent getHomeIntent() {
3810        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3811        intent.setComponent(mTopComponent);
3812        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3813        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3814            intent.addCategory(Intent.CATEGORY_HOME);
3815        }
3816        return intent;
3817    }
3818
3819    boolean startHomeActivityLocked(int userId, String reason) {
3820        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3821                && mTopAction == null) {
3822            // We are running in factory test mode, but unable to find
3823            // the factory test app, so just sit around displaying the
3824            // error message and don't try to start anything.
3825            return false;
3826        }
3827        Intent intent = getHomeIntent();
3828        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3829        if (aInfo != null) {
3830            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3831            // Don't do this if the home app is currently being
3832            // instrumented.
3833            aInfo = new ActivityInfo(aInfo);
3834            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3835            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3836                    aInfo.applicationInfo.uid, true);
3837            if (app == null || app.instrumentationClass == null) {
3838                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3839                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3840            }
3841        } else {
3842            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3843        }
3844
3845        return true;
3846    }
3847
3848    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3849        ActivityInfo ai = null;
3850        ComponentName comp = intent.getComponent();
3851        try {
3852            if (comp != null) {
3853                // Factory test.
3854                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3855            } else {
3856                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3857                        intent,
3858                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3859                        flags, userId);
3860
3861                if (info != null) {
3862                    ai = info.activityInfo;
3863                }
3864            }
3865        } catch (RemoteException e) {
3866            // ignore
3867        }
3868
3869        return ai;
3870    }
3871
3872    /**
3873     * Starts the "new version setup screen" if appropriate.
3874     */
3875    void startSetupActivityLocked() {
3876        // Only do this once per boot.
3877        if (mCheckedForSetup) {
3878            return;
3879        }
3880
3881        // We will show this screen if the current one is a different
3882        // version than the last one shown, and we are not running in
3883        // low-level factory test mode.
3884        final ContentResolver resolver = mContext.getContentResolver();
3885        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3886                Settings.Global.getInt(resolver,
3887                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3888            mCheckedForSetup = true;
3889
3890            // See if we should be showing the platform update setup UI.
3891            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3892            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3893                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3894            if (!ris.isEmpty()) {
3895                final ResolveInfo ri = ris.get(0);
3896                String vers = ri.activityInfo.metaData != null
3897                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3898                        : null;
3899                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3900                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3901                            Intent.METADATA_SETUP_VERSION);
3902                }
3903                String lastVers = Settings.Secure.getString(
3904                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3905                if (vers != null && !vers.equals(lastVers)) {
3906                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3907                    intent.setComponent(new ComponentName(
3908                            ri.activityInfo.packageName, ri.activityInfo.name));
3909                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3910                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3911                            null, 0, 0, 0, null, false, false, null, null, null);
3912                }
3913            }
3914        }
3915    }
3916
3917    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3918        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3919    }
3920
3921    void enforceNotIsolatedCaller(String caller) {
3922        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3923            throw new SecurityException("Isolated process not allowed to call " + caller);
3924        }
3925    }
3926
3927    void enforceShellRestriction(String restriction, int userHandle) {
3928        if (Binder.getCallingUid() == Process.SHELL_UID) {
3929            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3930                throw new SecurityException("Shell does not have permission to access user "
3931                        + userHandle);
3932            }
3933        }
3934    }
3935
3936    @Override
3937    public int getFrontActivityScreenCompatMode() {
3938        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3939        synchronized (this) {
3940            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3941        }
3942    }
3943
3944    @Override
3945    public void setFrontActivityScreenCompatMode(int mode) {
3946        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3947                "setFrontActivityScreenCompatMode");
3948        synchronized (this) {
3949            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3950        }
3951    }
3952
3953    @Override
3954    public int getPackageScreenCompatMode(String packageName) {
3955        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3956        synchronized (this) {
3957            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3958        }
3959    }
3960
3961    @Override
3962    public void setPackageScreenCompatMode(String packageName, int mode) {
3963        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3964                "setPackageScreenCompatMode");
3965        synchronized (this) {
3966            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3967        }
3968    }
3969
3970    @Override
3971    public boolean getPackageAskScreenCompat(String packageName) {
3972        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3973        synchronized (this) {
3974            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3975        }
3976    }
3977
3978    @Override
3979    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3980        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3981                "setPackageAskScreenCompat");
3982        synchronized (this) {
3983            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3984        }
3985    }
3986
3987    private boolean hasUsageStatsPermission(String callingPackage) {
3988        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3989                Binder.getCallingUid(), callingPackage);
3990        if (mode == AppOpsManager.MODE_DEFAULT) {
3991            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3992                    == PackageManager.PERMISSION_GRANTED;
3993        }
3994        return mode == AppOpsManager.MODE_ALLOWED;
3995    }
3996
3997    @Override
3998    public int getPackageProcessState(String packageName, String callingPackage) {
3999        if (!hasUsageStatsPermission(callingPackage)) {
4000            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4001                    "getPackageProcessState");
4002        }
4003
4004        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4005        synchronized (this) {
4006            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4007                final ProcessRecord proc = mLruProcesses.get(i);
4008                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4009                        || procState > proc.setProcState) {
4010                    if (proc.pkgList.containsKey(packageName)) {
4011                        procState = proc.setProcState;
4012                        break;
4013                    }
4014                    if (proc.pkgDeps != null && proc.pkgDeps.contains(packageName)) {
4015                        procState = proc.setProcState;
4016                    }
4017                }
4018            }
4019        }
4020        return procState;
4021    }
4022
4023    @Override
4024    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4025            throws RemoteException {
4026        synchronized (this) {
4027            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4028            if (app == null) {
4029                throw new IllegalArgumentException("Unknown process: " + process);
4030            }
4031            if (app.thread == null) {
4032                throw new IllegalArgumentException("Process has no app thread");
4033            }
4034            if (app.trimMemoryLevel >= level) {
4035                throw new IllegalArgumentException(
4036                        "Unable to set a higher trim level than current level");
4037            }
4038            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4039                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4040                throw new IllegalArgumentException("Unable to set a background trim level "
4041                    + "on a foreground process");
4042            }
4043            app.thread.scheduleTrimMemory(level);
4044            app.trimMemoryLevel = level;
4045            return true;
4046        }
4047    }
4048
4049    private void dispatchProcessesChanged() {
4050        int N;
4051        synchronized (this) {
4052            N = mPendingProcessChanges.size();
4053            if (mActiveProcessChanges.length < N) {
4054                mActiveProcessChanges = new ProcessChangeItem[N];
4055            }
4056            mPendingProcessChanges.toArray(mActiveProcessChanges);
4057            mPendingProcessChanges.clear();
4058            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4059                    "*** Delivering " + N + " process changes");
4060        }
4061
4062        int i = mProcessObservers.beginBroadcast();
4063        while (i > 0) {
4064            i--;
4065            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4066            if (observer != null) {
4067                try {
4068                    for (int j=0; j<N; j++) {
4069                        ProcessChangeItem item = mActiveProcessChanges[j];
4070                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4071                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4072                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4073                                    + item.uid + ": " + item.foregroundActivities);
4074                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4075                                    item.foregroundActivities);
4076                        }
4077                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4078                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4079                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4080                                    + ": " + item.processState);
4081                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4082                        }
4083                    }
4084                } catch (RemoteException e) {
4085                }
4086            }
4087        }
4088        mProcessObservers.finishBroadcast();
4089
4090        synchronized (this) {
4091            for (int j=0; j<N; j++) {
4092                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4093            }
4094        }
4095    }
4096
4097    private void dispatchProcessDied(int pid, int uid) {
4098        int i = mProcessObservers.beginBroadcast();
4099        while (i > 0) {
4100            i--;
4101            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4102            if (observer != null) {
4103                try {
4104                    observer.onProcessDied(pid, uid);
4105                } catch (RemoteException e) {
4106                }
4107            }
4108        }
4109        mProcessObservers.finishBroadcast();
4110    }
4111
4112    private void dispatchUidsChanged() {
4113        int N;
4114        synchronized (this) {
4115            N = mPendingUidChanges.size();
4116            if (mActiveUidChanges.length < N) {
4117                mActiveUidChanges = new UidRecord.ChangeItem[N];
4118            }
4119            for (int i=0; i<N; i++) {
4120                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4121                mActiveUidChanges[i] = change;
4122                if (change.uidRecord != null) {
4123                    change.uidRecord.pendingChange = null;
4124                    change.uidRecord = null;
4125                }
4126            }
4127            mPendingUidChanges.clear();
4128            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4129                    "*** Delivering " + N + " uid changes");
4130        }
4131
4132        int i = mUidObservers.beginBroadcast();
4133        while (i > 0) {
4134            i--;
4135            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4136            final UidObserverRegistration reg = (UidObserverRegistration)
4137                    mUidObservers.getBroadcastCookie(i);
4138            if (observer != null) {
4139                try {
4140                    for (int j=0; j<N; j++) {
4141                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4142                        final int change = item.change;
4143                        UidRecord validateUid = null;
4144                        if (VALIDATE_UID_STATES && i == 0) {
4145                            validateUid = mValidateUids.get(item.uid);
4146                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4147                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4148                                validateUid = new UidRecord(item.uid);
4149                                mValidateUids.put(item.uid, validateUid);
4150                            }
4151                        }
4152                        if (change == UidRecord.CHANGE_IDLE
4153                                || change == UidRecord.CHANGE_GONE_IDLE) {
4154                            if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4155                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4156                                        "UID idle uid=" + item.uid);
4157                                observer.onUidIdle(item.uid, item.ephemeral);
4158                            }
4159                            if (VALIDATE_UID_STATES && i == 0) {
4160                                if (validateUid != null) {
4161                                    validateUid.idle = true;
4162                                }
4163                            }
4164                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4165                            if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4166                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4167                                        "UID active uid=" + item.uid);
4168                                observer.onUidActive(item.uid);
4169                            }
4170                            if (VALIDATE_UID_STATES && i == 0) {
4171                                validateUid.idle = false;
4172                            }
4173                        }
4174                        if (change == UidRecord.CHANGE_GONE
4175                                || change == UidRecord.CHANGE_GONE_IDLE) {
4176                            if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4177                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4178                                        "UID gone uid=" + item.uid);
4179                                observer.onUidGone(item.uid, item.ephemeral);
4180                            }
4181                            if (reg.lastProcStates != null) {
4182                                reg.lastProcStates.delete(item.uid);
4183                            }
4184                            if (VALIDATE_UID_STATES && i == 0) {
4185                                if (validateUid != null) {
4186                                    mValidateUids.remove(item.uid);
4187                                }
4188                            }
4189                        } else {
4190                            if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4191                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4192                                        "UID CHANGED uid=" + item.uid
4193                                                + ": " + item.processState);
4194                                boolean doReport = true;
4195                                if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4196                                    final int lastState = reg.lastProcStates.get(item.uid,
4197                                            ActivityManager.PROCESS_STATE_UNKNOWN);
4198                                    if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4199                                        final boolean lastAboveCut = lastState <= reg.cutpoint;
4200                                        final boolean newAboveCut = item.processState <= reg.cutpoint;
4201                                        doReport = lastAboveCut != newAboveCut;
4202                                    } else {
4203                                        doReport = item.processState
4204                                                != ActivityManager.PROCESS_STATE_NONEXISTENT;
4205                                    }
4206                                }
4207                                if (doReport) {
4208                                    if (reg.lastProcStates != null) {
4209                                        reg.lastProcStates.put(item.uid, item.processState);
4210                                    }
4211                                    observer.onUidStateChanged(item.uid, item.processState);
4212                                }
4213                            }
4214                            if (VALIDATE_UID_STATES && i == 0) {
4215                                validateUid.curProcState = validateUid.setProcState
4216                                        = item.processState;
4217                            }
4218                        }
4219                    }
4220                } catch (RemoteException e) {
4221                }
4222            }
4223        }
4224        mUidObservers.finishBroadcast();
4225
4226        synchronized (this) {
4227            for (int j=0; j<N; j++) {
4228                mAvailUidChanges.add(mActiveUidChanges[j]);
4229            }
4230        }
4231    }
4232
4233    @Override
4234    public final int startActivity(IApplicationThread caller, String callingPackage,
4235            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4236            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4237        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4238                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4239                UserHandle.getCallingUserId());
4240    }
4241
4242    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4243        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4244        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4245                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4246                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4247
4248        // TODO: Switch to user app stacks here.
4249        String mimeType = intent.getType();
4250        final Uri data = intent.getData();
4251        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4252            mimeType = getProviderMimeType(data, userId);
4253        }
4254        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4255
4256        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4257        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4258                null, 0, 0, null, null, null, null, false, userId, container, null);
4259    }
4260
4261    @Override
4262    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4263            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4264            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4265        enforceNotIsolatedCaller("startActivity");
4266        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4267                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4268        // TODO: Switch to user app stacks here.
4269        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4270                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4271                profilerInfo, null, null, bOptions, false, userId, null, null);
4272    }
4273
4274    @Override
4275    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4276            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4277            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4278            int userId) {
4279
4280        // This is very dangerous -- it allows you to perform a start activity (including
4281        // permission grants) as any app that may launch one of your own activities.  So
4282        // we will only allow this to be done from activities that are part of the core framework,
4283        // and then only when they are running as the system.
4284        final ActivityRecord sourceRecord;
4285        final int targetUid;
4286        final String targetPackage;
4287        synchronized (this) {
4288            if (resultTo == null) {
4289                throw new SecurityException("Must be called from an activity");
4290            }
4291            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4292            if (sourceRecord == null) {
4293                throw new SecurityException("Called with bad activity token: " + resultTo);
4294            }
4295            if (!sourceRecord.info.packageName.equals("android")) {
4296                throw new SecurityException(
4297                        "Must be called from an activity that is declared in the android package");
4298            }
4299            if (sourceRecord.app == null) {
4300                throw new SecurityException("Called without a process attached to activity");
4301            }
4302            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4303                // This is still okay, as long as this activity is running under the
4304                // uid of the original calling activity.
4305                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4306                    throw new SecurityException(
4307                            "Calling activity in uid " + sourceRecord.app.uid
4308                                    + " must be system uid or original calling uid "
4309                                    + sourceRecord.launchedFromUid);
4310                }
4311            }
4312            if (ignoreTargetSecurity) {
4313                if (intent.getComponent() == null) {
4314                    throw new SecurityException(
4315                            "Component must be specified with ignoreTargetSecurity");
4316                }
4317                if (intent.getSelector() != null) {
4318                    throw new SecurityException(
4319                            "Selector not allowed with ignoreTargetSecurity");
4320                }
4321            }
4322            targetUid = sourceRecord.launchedFromUid;
4323            targetPackage = sourceRecord.launchedFromPackage;
4324        }
4325
4326        if (userId == UserHandle.USER_NULL) {
4327            userId = UserHandle.getUserId(sourceRecord.app.uid);
4328        }
4329
4330        // TODO: Switch to user app stacks here.
4331        try {
4332            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4333                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4334                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4335            return ret;
4336        } catch (SecurityException e) {
4337            // XXX need to figure out how to propagate to original app.
4338            // A SecurityException here is generally actually a fault of the original
4339            // calling activity (such as a fairly granting permissions), so propagate it
4340            // back to them.
4341            /*
4342            StringBuilder msg = new StringBuilder();
4343            msg.append("While launching");
4344            msg.append(intent.toString());
4345            msg.append(": ");
4346            msg.append(e.getMessage());
4347            */
4348            throw e;
4349        }
4350    }
4351
4352    @Override
4353    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4354            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4355            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4356        enforceNotIsolatedCaller("startActivityAndWait");
4357        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4358                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4359        WaitResult res = new WaitResult();
4360        // TODO: Switch to user app stacks here.
4361        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4362                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4363                bOptions, false, userId, null, null);
4364        return res;
4365    }
4366
4367    @Override
4368    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4369            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4370            int startFlags, Configuration config, Bundle bOptions, int userId) {
4371        enforceNotIsolatedCaller("startActivityWithConfig");
4372        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4373                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4374        // TODO: Switch to user app stacks here.
4375        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4376                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4377                null, null, config, bOptions, false, userId, null, null);
4378        return ret;
4379    }
4380
4381    @Override
4382    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4383            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4384            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4385            throws TransactionTooLargeException {
4386        enforceNotIsolatedCaller("startActivityIntentSender");
4387        // Refuse possible leaked file descriptors
4388        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4389            throw new IllegalArgumentException("File descriptors passed in Intent");
4390        }
4391
4392        IIntentSender sender = intent.getTarget();
4393        if (!(sender instanceof PendingIntentRecord)) {
4394            throw new IllegalArgumentException("Bad PendingIntent object");
4395        }
4396
4397        PendingIntentRecord pir = (PendingIntentRecord)sender;
4398
4399        synchronized (this) {
4400            // If this is coming from the currently resumed activity, it is
4401            // effectively saying that app switches are allowed at this point.
4402            final ActivityStack stack = getFocusedStack();
4403            if (stack.mResumedActivity != null &&
4404                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4405                mAppSwitchesAllowedTime = 0;
4406            }
4407        }
4408        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4409                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4410        return ret;
4411    }
4412
4413    @Override
4414    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4415            Intent intent, String resolvedType, IVoiceInteractionSession session,
4416            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4417            Bundle bOptions, int userId) {
4418        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4419                != PackageManager.PERMISSION_GRANTED) {
4420            String msg = "Permission Denial: startVoiceActivity() from pid="
4421                    + Binder.getCallingPid()
4422                    + ", uid=" + Binder.getCallingUid()
4423                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4424            Slog.w(TAG, msg);
4425            throw new SecurityException(msg);
4426        }
4427        if (session == null || interactor == null) {
4428            throw new NullPointerException("null session or interactor");
4429        }
4430        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4431                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4432        // TODO: Switch to user app stacks here.
4433        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4434                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4435                null, bOptions, false, userId, null, null);
4436    }
4437
4438    @Override
4439    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4440            throws RemoteException {
4441        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4442        synchronized (this) {
4443            ActivityRecord activity = getFocusedStack().topActivity();
4444            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4445                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4446            }
4447            if (mRunningVoice != null || activity.task.voiceSession != null
4448                    || activity.voiceSession != null) {
4449                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4450                return;
4451            }
4452            if (activity.pendingVoiceInteractionStart) {
4453                Slog.w(TAG, "Pending start of voice interaction already.");
4454                return;
4455            }
4456            activity.pendingVoiceInteractionStart = true;
4457        }
4458        LocalServices.getService(VoiceInteractionManagerInternal.class)
4459                .startLocalVoiceInteraction(callingActivity, options);
4460    }
4461
4462    @Override
4463    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4464        LocalServices.getService(VoiceInteractionManagerInternal.class)
4465                .stopLocalVoiceInteraction(callingActivity);
4466    }
4467
4468    @Override
4469    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4470        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4471                .supportsLocalVoiceInteraction();
4472    }
4473
4474    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4475            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4476        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4477        if (activityToCallback == null) return;
4478        activityToCallback.setVoiceSessionLocked(voiceSession);
4479
4480        // Inform the activity
4481        try {
4482            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4483                    voiceInteractor);
4484            long token = Binder.clearCallingIdentity();
4485            try {
4486                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4487            } finally {
4488                Binder.restoreCallingIdentity(token);
4489            }
4490            // TODO: VI Should we cache the activity so that it's easier to find later
4491            // rather than scan through all the stacks and activities?
4492        } catch (RemoteException re) {
4493            activityToCallback.clearVoiceSessionLocked();
4494            // TODO: VI Should this terminate the voice session?
4495        }
4496    }
4497
4498    @Override
4499    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4500        synchronized (this) {
4501            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4502                if (keepAwake) {
4503                    mVoiceWakeLock.acquire();
4504                } else {
4505                    mVoiceWakeLock.release();
4506                }
4507            }
4508        }
4509    }
4510
4511    @Override
4512    public boolean startNextMatchingActivity(IBinder callingActivity,
4513            Intent intent, Bundle bOptions) {
4514        // Refuse possible leaked file descriptors
4515        if (intent != null && intent.hasFileDescriptors() == true) {
4516            throw new IllegalArgumentException("File descriptors passed in Intent");
4517        }
4518        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4519
4520        synchronized (this) {
4521            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4522            if (r == null) {
4523                ActivityOptions.abort(options);
4524                return false;
4525            }
4526            if (r.app == null || r.app.thread == null) {
4527                // The caller is not running...  d'oh!
4528                ActivityOptions.abort(options);
4529                return false;
4530            }
4531            intent = new Intent(intent);
4532            // The caller is not allowed to change the data.
4533            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4534            // And we are resetting to find the next component...
4535            intent.setComponent(null);
4536
4537            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4538
4539            ActivityInfo aInfo = null;
4540            try {
4541                List<ResolveInfo> resolves =
4542                    AppGlobals.getPackageManager().queryIntentActivities(
4543                            intent, r.resolvedType,
4544                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4545                            UserHandle.getCallingUserId()).getList();
4546
4547                // Look for the original activity in the list...
4548                final int N = resolves != null ? resolves.size() : 0;
4549                for (int i=0; i<N; i++) {
4550                    ResolveInfo rInfo = resolves.get(i);
4551                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4552                            && rInfo.activityInfo.name.equals(r.info.name)) {
4553                        // We found the current one...  the next matching is
4554                        // after it.
4555                        i++;
4556                        if (i<N) {
4557                            aInfo = resolves.get(i).activityInfo;
4558                        }
4559                        if (debug) {
4560                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4561                                    + "/" + r.info.name);
4562                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4563                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4564                        }
4565                        break;
4566                    }
4567                }
4568            } catch (RemoteException e) {
4569            }
4570
4571            if (aInfo == null) {
4572                // Nobody who is next!
4573                ActivityOptions.abort(options);
4574                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4575                return false;
4576            }
4577
4578            intent.setComponent(new ComponentName(
4579                    aInfo.applicationInfo.packageName, aInfo.name));
4580            intent.setFlags(intent.getFlags()&~(
4581                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4582                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4583                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4584                    Intent.FLAG_ACTIVITY_NEW_TASK));
4585
4586            // Okay now we need to start the new activity, replacing the
4587            // currently running activity.  This is a little tricky because
4588            // we want to start the new one as if the current one is finished,
4589            // but not finish the current one first so that there is no flicker.
4590            // And thus...
4591            final boolean wasFinishing = r.finishing;
4592            r.finishing = true;
4593
4594            // Propagate reply information over to the new activity.
4595            final ActivityRecord resultTo = r.resultTo;
4596            final String resultWho = r.resultWho;
4597            final int requestCode = r.requestCode;
4598            r.resultTo = null;
4599            if (resultTo != null) {
4600                resultTo.removeResultsLocked(r, resultWho, requestCode);
4601            }
4602
4603            final long origId = Binder.clearCallingIdentity();
4604            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4605                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4606                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4607                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4608                    false, false, null, null, null);
4609            Binder.restoreCallingIdentity(origId);
4610
4611            r.finishing = wasFinishing;
4612            if (res != ActivityManager.START_SUCCESS) {
4613                return false;
4614            }
4615            return true;
4616        }
4617    }
4618
4619    @Override
4620    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4621        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4622            String msg = "Permission Denial: startActivityFromRecents called without " +
4623                    START_TASKS_FROM_RECENTS;
4624            Slog.w(TAG, msg);
4625            throw new SecurityException(msg);
4626        }
4627        final long origId = Binder.clearCallingIdentity();
4628        try {
4629            synchronized (this) {
4630                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4631            }
4632        } finally {
4633            Binder.restoreCallingIdentity(origId);
4634        }
4635    }
4636
4637    final int startActivityInPackage(int uid, String callingPackage,
4638            Intent intent, String resolvedType, IBinder resultTo,
4639            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4640            IActivityContainer container, TaskRecord inTask) {
4641
4642        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4643                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4644
4645        // TODO: Switch to user app stacks here.
4646        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4647                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4648                null, null, null, bOptions, false, userId, container, inTask);
4649        return ret;
4650    }
4651
4652    @Override
4653    public final int startActivities(IApplicationThread caller, String callingPackage,
4654            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4655            int userId) {
4656        enforceNotIsolatedCaller("startActivities");
4657        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4658                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4659        // TODO: Switch to user app stacks here.
4660        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4661                resolvedTypes, resultTo, bOptions, userId);
4662        return ret;
4663    }
4664
4665    final int startActivitiesInPackage(int uid, String callingPackage,
4666            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4667            Bundle bOptions, int userId) {
4668
4669        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4670                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4671        // TODO: Switch to user app stacks here.
4672        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4673                resultTo, bOptions, userId);
4674        return ret;
4675    }
4676
4677    @Override
4678    public void reportActivityFullyDrawn(IBinder token) {
4679        synchronized (this) {
4680            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4681            if (r == null) {
4682                return;
4683            }
4684            r.reportFullyDrawnLocked();
4685        }
4686    }
4687
4688    @Override
4689    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4690        synchronized (this) {
4691            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4692            if (r == null) {
4693                return;
4694            }
4695            final long origId = Binder.clearCallingIdentity();
4696            try {
4697                r.setRequestedOrientation(requestedOrientation);
4698            } finally {
4699                Binder.restoreCallingIdentity(origId);
4700            }
4701        }
4702    }
4703
4704    @Override
4705    public int getRequestedOrientation(IBinder token) {
4706        synchronized (this) {
4707            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4708            if (r == null) {
4709                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4710            }
4711            return mWindowManager.getAppOrientation(r.appToken);
4712        }
4713    }
4714
4715    @Override
4716    public final void requestActivityRelaunch(IBinder token) {
4717        synchronized(this) {
4718            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4719            if (r == null) {
4720                return;
4721            }
4722            final long origId = Binder.clearCallingIdentity();
4723            try {
4724                r.forceNewConfig = true;
4725                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4726                        false /* preserveWindow */);
4727            } finally {
4728                Binder.restoreCallingIdentity(origId);
4729            }
4730        }
4731    }
4732
4733    /**
4734     * This is the internal entry point for handling Activity.finish().
4735     *
4736     * @param token The Binder token referencing the Activity we want to finish.
4737     * @param resultCode Result code, if any, from this Activity.
4738     * @param resultData Result data (Intent), if any, from this Activity.
4739     * @param finishTask Whether to finish the task associated with this Activity.
4740     *
4741     * @return Returns true if the activity successfully finished, or false if it is still running.
4742     */
4743    @Override
4744    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4745            int finishTask) {
4746        // Refuse possible leaked file descriptors
4747        if (resultData != null && resultData.hasFileDescriptors() == true) {
4748            throw new IllegalArgumentException("File descriptors passed in Intent");
4749        }
4750
4751        synchronized(this) {
4752            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4753            if (r == null) {
4754                return true;
4755            }
4756            // Keep track of the root activity of the task before we finish it
4757            TaskRecord tr = r.task;
4758            ActivityRecord rootR = tr.getRootActivity();
4759            if (rootR == null) {
4760                Slog.w(TAG, "Finishing task with all activities already finished");
4761            }
4762            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4763            // finish.
4764            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4765                    mStackSupervisor.isLastLockedTask(tr)) {
4766                Slog.i(TAG, "Not finishing task in lock task mode");
4767                mStackSupervisor.showLockTaskToast();
4768                return false;
4769            }
4770            if (mController != null) {
4771                // Find the first activity that is not finishing.
4772                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
4773                if (next != null) {
4774                    // ask watcher if this is allowed
4775                    boolean resumeOK = true;
4776                    try {
4777                        resumeOK = mController.activityResuming(next.packageName);
4778                    } catch (RemoteException e) {
4779                        mController = null;
4780                        Watchdog.getInstance().setActivityController(null);
4781                    }
4782
4783                    if (!resumeOK) {
4784                        Slog.i(TAG, "Not finishing activity because controller resumed");
4785                        return false;
4786                    }
4787                }
4788            }
4789            final long origId = Binder.clearCallingIdentity();
4790            try {
4791                boolean res;
4792                final boolean finishWithRootActivity =
4793                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4794                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4795                        || (finishWithRootActivity && r == rootR)) {
4796                    // If requested, remove the task that is associated to this activity only if it
4797                    // was the root activity in the task. The result code and data is ignored
4798                    // because we don't support returning them across task boundaries. Also, to
4799                    // keep backwards compatibility we remove the task from recents when finishing
4800                    // task with root activity.
4801                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4802                    if (!res) {
4803                        Slog.i(TAG, "Removing task failed to finish activity");
4804                    }
4805                } else {
4806                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
4807                            resultData, "app-request", true);
4808                    if (!res) {
4809                        Slog.i(TAG, "Failed to finish by app-request");
4810                    }
4811                }
4812                return res;
4813            } finally {
4814                Binder.restoreCallingIdentity(origId);
4815            }
4816        }
4817    }
4818
4819    @Override
4820    public final void finishHeavyWeightApp() {
4821        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4822                != PackageManager.PERMISSION_GRANTED) {
4823            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4824                    + Binder.getCallingPid()
4825                    + ", uid=" + Binder.getCallingUid()
4826                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4827            Slog.w(TAG, msg);
4828            throw new SecurityException(msg);
4829        }
4830
4831        synchronized(this) {
4832            if (mHeavyWeightProcess == null) {
4833                return;
4834            }
4835
4836            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4837            for (int i = 0; i < activities.size(); i++) {
4838                ActivityRecord r = activities.get(i);
4839                if (!r.finishing && r.isInStackLocked()) {
4840                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
4841                            null, "finish-heavy", true);
4842                }
4843            }
4844
4845            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4846                    mHeavyWeightProcess.userId, 0));
4847            mHeavyWeightProcess = null;
4848        }
4849    }
4850
4851    @Override
4852    public void crashApplication(int uid, int initialPid, String packageName,
4853            String message) {
4854        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4855                != PackageManager.PERMISSION_GRANTED) {
4856            String msg = "Permission Denial: crashApplication() from pid="
4857                    + Binder.getCallingPid()
4858                    + ", uid=" + Binder.getCallingUid()
4859                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4860            Slog.w(TAG, msg);
4861            throw new SecurityException(msg);
4862        }
4863
4864        synchronized(this) {
4865            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4866        }
4867    }
4868
4869    @Override
4870    public final void finishSubActivity(IBinder token, String resultWho,
4871            int requestCode) {
4872        synchronized(this) {
4873            final long origId = Binder.clearCallingIdentity();
4874            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4875            if (r != null) {
4876                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
4877            }
4878            Binder.restoreCallingIdentity(origId);
4879        }
4880    }
4881
4882    @Override
4883    public boolean finishActivityAffinity(IBinder token) {
4884        synchronized(this) {
4885            final long origId = Binder.clearCallingIdentity();
4886            try {
4887                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4888                if (r == null) {
4889                    return false;
4890                }
4891
4892                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4893                // can finish.
4894                final TaskRecord task = r.task;
4895                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4896                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4897                    mStackSupervisor.showLockTaskToast();
4898                    return false;
4899                }
4900                return task.getStack().finishActivityAffinityLocked(r);
4901            } finally {
4902                Binder.restoreCallingIdentity(origId);
4903            }
4904        }
4905    }
4906
4907    @Override
4908    public void finishVoiceTask(IVoiceInteractionSession session) {
4909        synchronized (this) {
4910            final long origId = Binder.clearCallingIdentity();
4911            try {
4912                // TODO: VI Consider treating local voice interactions and voice tasks
4913                // differently here
4914                mStackSupervisor.finishVoiceTask(session);
4915            } finally {
4916                Binder.restoreCallingIdentity(origId);
4917            }
4918        }
4919
4920    }
4921
4922    @Override
4923    public boolean releaseActivityInstance(IBinder token) {
4924        synchronized(this) {
4925            final long origId = Binder.clearCallingIdentity();
4926            try {
4927                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4928                if (r == null) {
4929                    return false;
4930                }
4931                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
4932            } finally {
4933                Binder.restoreCallingIdentity(origId);
4934            }
4935        }
4936    }
4937
4938    @Override
4939    public void releaseSomeActivities(IApplicationThread appInt) {
4940        synchronized(this) {
4941            final long origId = Binder.clearCallingIdentity();
4942            try {
4943                ProcessRecord app = getRecordForAppLocked(appInt);
4944                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4945            } finally {
4946                Binder.restoreCallingIdentity(origId);
4947            }
4948        }
4949    }
4950
4951    @Override
4952    public boolean willActivityBeVisible(IBinder token) {
4953        synchronized(this) {
4954            ActivityStack stack = ActivityRecord.getStackLocked(token);
4955            if (stack != null) {
4956                return stack.willActivityBeVisibleLocked(token);
4957            }
4958            return false;
4959        }
4960    }
4961
4962    @Override
4963    public void overridePendingTransition(IBinder token, String packageName,
4964            int enterAnim, int exitAnim) {
4965        synchronized(this) {
4966            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4967            if (self == null) {
4968                return;
4969            }
4970
4971            final long origId = Binder.clearCallingIdentity();
4972
4973            if (self.state == ActivityState.RESUMED
4974                    || self.state == ActivityState.PAUSING) {
4975                mWindowManager.overridePendingAppTransition(packageName,
4976                        enterAnim, exitAnim, null);
4977            }
4978
4979            Binder.restoreCallingIdentity(origId);
4980        }
4981    }
4982
4983    /**
4984     * Main function for removing an existing process from the activity manager
4985     * as a result of that process going away.  Clears out all connections
4986     * to the process.
4987     */
4988    private final void handleAppDiedLocked(ProcessRecord app,
4989            boolean restarting, boolean allowRestart) {
4990        int pid = app.pid;
4991        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
4992                false /*replacingPid*/);
4993        if (!kept && !restarting) {
4994            removeLruProcessLocked(app);
4995            if (pid > 0) {
4996                ProcessList.remove(pid);
4997            }
4998        }
4999
5000        if (mProfileProc == app) {
5001            clearProfilerLocked();
5002        }
5003
5004        // Remove this application's activities from active lists.
5005        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5006
5007        app.activities.clear();
5008
5009        if (app.instrumentationClass != null) {
5010            Slog.w(TAG, "Crash of app " + app.processName
5011                  + " running instrumentation " + app.instrumentationClass);
5012            Bundle info = new Bundle();
5013            info.putString("shortMsg", "Process crashed.");
5014            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5015        }
5016
5017        mWindowManager.deferSurfaceLayout();
5018        try {
5019            if (!restarting && hasVisibleActivities
5020                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5021                // If there was nothing to resume, and we are not already restarting this process, but
5022                // there is a visible activity that is hosted by the process...  then make sure all
5023                // visible activities are running, taking care of restarting this process.
5024                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5025            }
5026        } finally {
5027            mWindowManager.continueSurfaceLayout();
5028        }
5029    }
5030
5031    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5032        IBinder threadBinder = thread.asBinder();
5033        // Find the application record.
5034        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5035            ProcessRecord rec = mLruProcesses.get(i);
5036            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5037                return i;
5038            }
5039        }
5040        return -1;
5041    }
5042
5043    final ProcessRecord getRecordForAppLocked(
5044            IApplicationThread thread) {
5045        if (thread == null) {
5046            return null;
5047        }
5048
5049        int appIndex = getLRURecordIndexForAppLocked(thread);
5050        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5051    }
5052
5053    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5054        // If there are no longer any background processes running,
5055        // and the app that died was not running instrumentation,
5056        // then tell everyone we are now low on memory.
5057        boolean haveBg = false;
5058        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5059            ProcessRecord rec = mLruProcesses.get(i);
5060            if (rec.thread != null
5061                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5062                haveBg = true;
5063                break;
5064            }
5065        }
5066
5067        if (!haveBg) {
5068            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5069            if (doReport) {
5070                long now = SystemClock.uptimeMillis();
5071                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5072                    doReport = false;
5073                } else {
5074                    mLastMemUsageReportTime = now;
5075                }
5076            }
5077            final ArrayList<ProcessMemInfo> memInfos
5078                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5079            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5080            long now = SystemClock.uptimeMillis();
5081            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5082                ProcessRecord rec = mLruProcesses.get(i);
5083                if (rec == dyingProc || rec.thread == null) {
5084                    continue;
5085                }
5086                if (doReport) {
5087                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5088                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5089                }
5090                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5091                    // The low memory report is overriding any current
5092                    // state for a GC request.  Make sure to do
5093                    // heavy/important/visible/foreground processes first.
5094                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5095                        rec.lastRequestedGc = 0;
5096                    } else {
5097                        rec.lastRequestedGc = rec.lastLowMemory;
5098                    }
5099                    rec.reportLowMemory = true;
5100                    rec.lastLowMemory = now;
5101                    mProcessesToGc.remove(rec);
5102                    addProcessToGcListLocked(rec);
5103                }
5104            }
5105            if (doReport) {
5106                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5107                mHandler.sendMessage(msg);
5108            }
5109            scheduleAppGcsLocked();
5110        }
5111    }
5112
5113    final void appDiedLocked(ProcessRecord app) {
5114       appDiedLocked(app, app.pid, app.thread, false);
5115    }
5116
5117    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5118            boolean fromBinderDied) {
5119        // First check if this ProcessRecord is actually active for the pid.
5120        synchronized (mPidsSelfLocked) {
5121            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5122            if (curProc != app) {
5123                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5124                return;
5125            }
5126        }
5127
5128        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5129        synchronized (stats) {
5130            stats.noteProcessDiedLocked(app.info.uid, pid);
5131        }
5132
5133        if (!app.killed) {
5134            if (!fromBinderDied) {
5135                Process.killProcessQuiet(pid);
5136            }
5137            killProcessGroup(app.uid, pid);
5138            app.killed = true;
5139        }
5140
5141        // Clean up already done if the process has been re-started.
5142        if (app.pid == pid && app.thread != null &&
5143                app.thread.asBinder() == thread.asBinder()) {
5144            boolean doLowMem = app.instrumentationClass == null;
5145            boolean doOomAdj = doLowMem;
5146            if (!app.killedByAm) {
5147                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5148                        + ") has died");
5149                mAllowLowerMemLevel = true;
5150            } else {
5151                // Note that we always want to do oom adj to update our state with the
5152                // new number of procs.
5153                mAllowLowerMemLevel = false;
5154                doLowMem = false;
5155            }
5156            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5157            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5158                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5159            handleAppDiedLocked(app, false, true);
5160
5161            if (doOomAdj) {
5162                updateOomAdjLocked();
5163            }
5164            if (doLowMem) {
5165                doLowMemReportIfNeededLocked(app);
5166            }
5167        } else if (app.pid != pid) {
5168            // A new process has already been started.
5169            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5170                    + ") has died and restarted (pid " + app.pid + ").");
5171            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5172        } else if (DEBUG_PROCESSES) {
5173            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5174                    + thread.asBinder());
5175        }
5176    }
5177
5178    /**
5179     * If a stack trace dump file is configured, dump process stack traces.
5180     * @param clearTraces causes the dump file to be erased prior to the new
5181     *    traces being written, if true; when false, the new traces will be
5182     *    appended to any existing file content.
5183     * @param firstPids of dalvik VM processes to dump stack traces for first
5184     * @param lastPids of dalvik VM processes to dump stack traces for last
5185     * @param nativeProcs optional list of native process names to dump stack crawls
5186     * @return file containing stack traces, or null if no dump file is configured
5187     */
5188    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5189            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5190        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5191        if (tracesPath == null || tracesPath.length() == 0) {
5192            return null;
5193        }
5194
5195        File tracesFile = new File(tracesPath);
5196        try {
5197            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5198            tracesFile.createNewFile();
5199            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5200        } catch (IOException e) {
5201            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5202            return null;
5203        }
5204
5205        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5206        return tracesFile;
5207    }
5208
5209    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5210            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5211        // Use a FileObserver to detect when traces finish writing.
5212        // The order of traces is considered important to maintain for legibility.
5213        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5214            @Override
5215            public synchronized void onEvent(int event, String path) { notify(); }
5216        };
5217
5218        try {
5219            observer.startWatching();
5220
5221            // First collect all of the stacks of the most important pids.
5222            if (firstPids != null) {
5223                try {
5224                    int num = firstPids.size();
5225                    for (int i = 0; i < num; i++) {
5226                        synchronized (observer) {
5227                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5228                                    + firstPids.get(i));
5229                            final long sime = SystemClock.elapsedRealtime();
5230                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5231                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5232                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5233                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5234                        }
5235                    }
5236                } catch (InterruptedException e) {
5237                    Slog.wtf(TAG, e);
5238                }
5239            }
5240
5241            // Next collect the stacks of the native pids
5242            if (nativeProcs != null) {
5243                int[] pids = Process.getPidsForCommands(nativeProcs);
5244                if (pids != null) {
5245                    for (int pid : pids) {
5246                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5247                        final long sime = SystemClock.elapsedRealtime();
5248                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5249                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5250                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5251                    }
5252                }
5253            }
5254
5255            // Lastly, measure CPU usage.
5256            if (processCpuTracker != null) {
5257                processCpuTracker.init();
5258                System.gc();
5259                processCpuTracker.update();
5260                try {
5261                    synchronized (processCpuTracker) {
5262                        processCpuTracker.wait(500); // measure over 1/2 second.
5263                    }
5264                } catch (InterruptedException e) {
5265                }
5266                processCpuTracker.update();
5267
5268                // We'll take the stack crawls of just the top apps using CPU.
5269                final int N = processCpuTracker.countWorkingStats();
5270                int numProcs = 0;
5271                for (int i=0; i<N && numProcs<5; i++) {
5272                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5273                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5274                        numProcs++;
5275                        try {
5276                            synchronized (observer) {
5277                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5278                                        + stats.pid);
5279                                final long stime = SystemClock.elapsedRealtime();
5280                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5281                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5282                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5283                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5284                            }
5285                        } catch (InterruptedException e) {
5286                            Slog.wtf(TAG, e);
5287                        }
5288                    } else if (DEBUG_ANR) {
5289                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5290                                + stats.pid);
5291                    }
5292                }
5293            }
5294        } finally {
5295            observer.stopWatching();
5296        }
5297    }
5298
5299    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5300        if (true || IS_USER_BUILD) {
5301            return;
5302        }
5303        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5304        if (tracesPath == null || tracesPath.length() == 0) {
5305            return;
5306        }
5307
5308        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5309        StrictMode.allowThreadDiskWrites();
5310        try {
5311            final File tracesFile = new File(tracesPath);
5312            final File tracesDir = tracesFile.getParentFile();
5313            final File tracesTmp = new File(tracesDir, "__tmp__");
5314            try {
5315                if (tracesFile.exists()) {
5316                    tracesTmp.delete();
5317                    tracesFile.renameTo(tracesTmp);
5318                }
5319                StringBuilder sb = new StringBuilder();
5320                Time tobj = new Time();
5321                tobj.set(System.currentTimeMillis());
5322                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5323                sb.append(": ");
5324                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5325                sb.append(" since ");
5326                sb.append(msg);
5327                FileOutputStream fos = new FileOutputStream(tracesFile);
5328                fos.write(sb.toString().getBytes());
5329                if (app == null) {
5330                    fos.write("\n*** No application process!".getBytes());
5331                }
5332                fos.close();
5333                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5334            } catch (IOException e) {
5335                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5336                return;
5337            }
5338
5339            if (app != null) {
5340                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5341                firstPids.add(app.pid);
5342                dumpStackTraces(tracesPath, firstPids, null, null, null);
5343            }
5344
5345            File lastTracesFile = null;
5346            File curTracesFile = null;
5347            for (int i=9; i>=0; i--) {
5348                String name = String.format(Locale.US, "slow%02d.txt", i);
5349                curTracesFile = new File(tracesDir, name);
5350                if (curTracesFile.exists()) {
5351                    if (lastTracesFile != null) {
5352                        curTracesFile.renameTo(lastTracesFile);
5353                    } else {
5354                        curTracesFile.delete();
5355                    }
5356                }
5357                lastTracesFile = curTracesFile;
5358            }
5359            tracesFile.renameTo(curTracesFile);
5360            if (tracesTmp.exists()) {
5361                tracesTmp.renameTo(tracesFile);
5362            }
5363        } finally {
5364            StrictMode.setThreadPolicy(oldPolicy);
5365        }
5366    }
5367
5368    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5369        if (!mLaunchWarningShown) {
5370            mLaunchWarningShown = true;
5371            mUiHandler.post(new Runnable() {
5372                @Override
5373                public void run() {
5374                    synchronized (ActivityManagerService.this) {
5375                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5376                        d.show();
5377                        mUiHandler.postDelayed(new Runnable() {
5378                            @Override
5379                            public void run() {
5380                                synchronized (ActivityManagerService.this) {
5381                                    d.dismiss();
5382                                    mLaunchWarningShown = false;
5383                                }
5384                            }
5385                        }, 4000);
5386                    }
5387                }
5388            });
5389        }
5390    }
5391
5392    @Override
5393    public boolean clearApplicationUserData(final String packageName,
5394            final IPackageDataObserver observer, int userId) {
5395        enforceNotIsolatedCaller("clearApplicationUserData");
5396        int uid = Binder.getCallingUid();
5397        int pid = Binder.getCallingPid();
5398        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5399                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5400
5401
5402        long callingId = Binder.clearCallingIdentity();
5403        try {
5404            IPackageManager pm = AppGlobals.getPackageManager();
5405            int pkgUid = -1;
5406            synchronized(this) {
5407                if (getPackageManagerInternalLocked().isPackageDataProtected(
5408                        userId, packageName)) {
5409                    throw new SecurityException(
5410                            "Cannot clear data for a protected package: " + packageName);
5411                }
5412
5413                try {
5414                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5415                } catch (RemoteException e) {
5416                }
5417                if (pkgUid == -1) {
5418                    Slog.w(TAG, "Invalid packageName: " + packageName);
5419                    if (observer != null) {
5420                        try {
5421                            observer.onRemoveCompleted(packageName, false);
5422                        } catch (RemoteException e) {
5423                            Slog.i(TAG, "Observer no longer exists.");
5424                        }
5425                    }
5426                    return false;
5427                }
5428                if (uid == pkgUid || checkComponentPermission(
5429                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5430                        pid, uid, -1, true)
5431                        == PackageManager.PERMISSION_GRANTED) {
5432                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5433                } else {
5434                    throw new SecurityException("PID " + pid + " does not have permission "
5435                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5436                                    + " of package " + packageName);
5437                }
5438
5439                // Remove all tasks match the cleared application package and user
5440                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5441                    final TaskRecord tr = mRecentTasks.get(i);
5442                    final String taskPackageName =
5443                            tr.getBaseIntent().getComponent().getPackageName();
5444                    if (tr.userId != userId) continue;
5445                    if (!taskPackageName.equals(packageName)) continue;
5446                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5447                }
5448            }
5449
5450            final int pkgUidF = pkgUid;
5451            final int userIdF = userId;
5452            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5453                @Override
5454                public void onRemoveCompleted(String packageName, boolean succeeded)
5455                        throws RemoteException {
5456                    synchronized (ActivityManagerService.this) {
5457                        finishForceStopPackageLocked(packageName, pkgUidF);
5458                    }
5459
5460                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5461                            Uri.fromParts("package", packageName, null));
5462                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5463                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5464                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5465                            null, null, 0, null, null, null, null, false, false, userIdF);
5466
5467                    if (observer != null) {
5468                        observer.onRemoveCompleted(packageName, succeeded);
5469                    }
5470                }
5471            };
5472
5473            try {
5474                // Clear application user data
5475                pm.clearApplicationUserData(packageName, localObserver, userId);
5476
5477                synchronized(this) {
5478                    // Remove all permissions granted from/to this package
5479                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5480                }
5481
5482                // Remove all zen rules created by this package; revoke it's zen access.
5483                INotificationManager inm = NotificationManager.getService();
5484                inm.removeAutomaticZenRules(packageName);
5485                inm.setNotificationPolicyAccessGranted(packageName, false);
5486
5487            } catch (RemoteException e) {
5488            }
5489        } finally {
5490            Binder.restoreCallingIdentity(callingId);
5491        }
5492        return true;
5493    }
5494
5495    @Override
5496    public void killBackgroundProcesses(final String packageName, int userId) {
5497        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5498                != PackageManager.PERMISSION_GRANTED &&
5499                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5500                        != PackageManager.PERMISSION_GRANTED) {
5501            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5502                    + Binder.getCallingPid()
5503                    + ", uid=" + Binder.getCallingUid()
5504                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5505            Slog.w(TAG, msg);
5506            throw new SecurityException(msg);
5507        }
5508
5509        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5510                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5511        long callingId = Binder.clearCallingIdentity();
5512        try {
5513            IPackageManager pm = AppGlobals.getPackageManager();
5514            synchronized(this) {
5515                int appId = -1;
5516                try {
5517                    appId = UserHandle.getAppId(
5518                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5519                } catch (RemoteException e) {
5520                }
5521                if (appId == -1) {
5522                    Slog.w(TAG, "Invalid packageName: " + packageName);
5523                    return;
5524                }
5525                killPackageProcessesLocked(packageName, appId, userId,
5526                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5527            }
5528        } finally {
5529            Binder.restoreCallingIdentity(callingId);
5530        }
5531    }
5532
5533    @Override
5534    public void killAllBackgroundProcesses() {
5535        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5536                != PackageManager.PERMISSION_GRANTED) {
5537            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5538                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5539                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5540            Slog.w(TAG, msg);
5541            throw new SecurityException(msg);
5542        }
5543
5544        final long callingId = Binder.clearCallingIdentity();
5545        try {
5546            synchronized (this) {
5547                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5548                final int NP = mProcessNames.getMap().size();
5549                for (int ip = 0; ip < NP; ip++) {
5550                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5551                    final int NA = apps.size();
5552                    for (int ia = 0; ia < NA; ia++) {
5553                        final ProcessRecord app = apps.valueAt(ia);
5554                        if (app.persistent) {
5555                            // We don't kill persistent processes.
5556                            continue;
5557                        }
5558                        if (app.removed) {
5559                            procs.add(app);
5560                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5561                            app.removed = true;
5562                            procs.add(app);
5563                        }
5564                    }
5565                }
5566
5567                final int N = procs.size();
5568                for (int i = 0; i < N; i++) {
5569                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5570                }
5571
5572                mAllowLowerMemLevel = true;
5573
5574                updateOomAdjLocked();
5575                doLowMemReportIfNeededLocked(null);
5576            }
5577        } finally {
5578            Binder.restoreCallingIdentity(callingId);
5579        }
5580    }
5581
5582    /**
5583     * Kills all background processes, except those matching any of the
5584     * specified properties.
5585     *
5586     * @param minTargetSdk the target SDK version at or above which to preserve
5587     *                     processes, or {@code -1} to ignore the target SDK
5588     * @param maxProcState the process state at or below which to preserve
5589     *                     processes, or {@code -1} to ignore the process state
5590     */
5591    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5592        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5593                != PackageManager.PERMISSION_GRANTED) {
5594            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5595                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5596                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5597            Slog.w(TAG, msg);
5598            throw new SecurityException(msg);
5599        }
5600
5601        final long callingId = Binder.clearCallingIdentity();
5602        try {
5603            synchronized (this) {
5604                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5605                final int NP = mProcessNames.getMap().size();
5606                for (int ip = 0; ip < NP; ip++) {
5607                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5608                    final int NA = apps.size();
5609                    for (int ia = 0; ia < NA; ia++) {
5610                        final ProcessRecord app = apps.valueAt(ia);
5611                        if (app.removed) {
5612                            procs.add(app);
5613                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5614                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5615                            app.removed = true;
5616                            procs.add(app);
5617                        }
5618                    }
5619                }
5620
5621                final int N = procs.size();
5622                for (int i = 0; i < N; i++) {
5623                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5624                }
5625            }
5626        } finally {
5627            Binder.restoreCallingIdentity(callingId);
5628        }
5629    }
5630
5631    @Override
5632    public void forceStopPackage(final String packageName, int userId) {
5633        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5634                != PackageManager.PERMISSION_GRANTED) {
5635            String msg = "Permission Denial: forceStopPackage() from pid="
5636                    + Binder.getCallingPid()
5637                    + ", uid=" + Binder.getCallingUid()
5638                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5639            Slog.w(TAG, msg);
5640            throw new SecurityException(msg);
5641        }
5642        final int callingPid = Binder.getCallingPid();
5643        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5644                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5645        long callingId = Binder.clearCallingIdentity();
5646        try {
5647            IPackageManager pm = AppGlobals.getPackageManager();
5648            synchronized(this) {
5649                int[] users = userId == UserHandle.USER_ALL
5650                        ? mUserController.getUsers() : new int[] { userId };
5651                for (int user : users) {
5652                    int pkgUid = -1;
5653                    try {
5654                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5655                                user);
5656                    } catch (RemoteException e) {
5657                    }
5658                    if (pkgUid == -1) {
5659                        Slog.w(TAG, "Invalid packageName: " + packageName);
5660                        continue;
5661                    }
5662                    try {
5663                        pm.setPackageStoppedState(packageName, true, user);
5664                    } catch (RemoteException e) {
5665                    } catch (IllegalArgumentException e) {
5666                        Slog.w(TAG, "Failed trying to unstop package "
5667                                + packageName + ": " + e);
5668                    }
5669                    if (mUserController.isUserRunningLocked(user, 0)) {
5670                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5671                        finishForceStopPackageLocked(packageName, pkgUid);
5672                    }
5673                }
5674            }
5675        } finally {
5676            Binder.restoreCallingIdentity(callingId);
5677        }
5678    }
5679
5680    @Override
5681    public void addPackageDependency(String packageName) {
5682        synchronized (this) {
5683            int callingPid = Binder.getCallingPid();
5684            if (callingPid == Process.myPid()) {
5685                //  Yeah, um, no.
5686                return;
5687            }
5688            ProcessRecord proc;
5689            synchronized (mPidsSelfLocked) {
5690                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5691            }
5692            if (proc != null) {
5693                if (proc.pkgDeps == null) {
5694                    proc.pkgDeps = new ArraySet<String>(1);
5695                }
5696                proc.pkgDeps.add(packageName);
5697            }
5698        }
5699    }
5700
5701    /*
5702     * The pkg name and app id have to be specified.
5703     */
5704    @Override
5705    public void killApplication(String pkg, int appId, int userId, String reason) {
5706        if (pkg == null) {
5707            return;
5708        }
5709        // Make sure the uid is valid.
5710        if (appId < 0) {
5711            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5712            return;
5713        }
5714        int callerUid = Binder.getCallingUid();
5715        // Only the system server can kill an application
5716        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5717            // Post an aysnc message to kill the application
5718            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5719            msg.arg1 = appId;
5720            msg.arg2 = userId;
5721            Bundle bundle = new Bundle();
5722            bundle.putString("pkg", pkg);
5723            bundle.putString("reason", reason);
5724            msg.obj = bundle;
5725            mHandler.sendMessage(msg);
5726        } else {
5727            throw new SecurityException(callerUid + " cannot kill pkg: " +
5728                    pkg);
5729        }
5730    }
5731
5732    @Override
5733    public void closeSystemDialogs(String reason) {
5734        enforceNotIsolatedCaller("closeSystemDialogs");
5735
5736        final int pid = Binder.getCallingPid();
5737        final int uid = Binder.getCallingUid();
5738        final long origId = Binder.clearCallingIdentity();
5739        try {
5740            synchronized (this) {
5741                // Only allow this from foreground processes, so that background
5742                // applications can't abuse it to prevent system UI from being shown.
5743                if (uid >= Process.FIRST_APPLICATION_UID) {
5744                    ProcessRecord proc;
5745                    synchronized (mPidsSelfLocked) {
5746                        proc = mPidsSelfLocked.get(pid);
5747                    }
5748                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5749                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5750                                + " from background process " + proc);
5751                        return;
5752                    }
5753                }
5754                closeSystemDialogsLocked(reason);
5755            }
5756        } finally {
5757            Binder.restoreCallingIdentity(origId);
5758        }
5759    }
5760
5761    void closeSystemDialogsLocked(String reason) {
5762        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5763        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5764                | Intent.FLAG_RECEIVER_FOREGROUND);
5765        if (reason != null) {
5766            intent.putExtra("reason", reason);
5767        }
5768        mWindowManager.closeSystemDialogs(reason);
5769
5770        mStackSupervisor.closeSystemDialogsLocked();
5771
5772        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5773                AppOpsManager.OP_NONE, null, false, false,
5774                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5775    }
5776
5777    @Override
5778    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5779        enforceNotIsolatedCaller("getProcessMemoryInfo");
5780        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5781        for (int i=pids.length-1; i>=0; i--) {
5782            ProcessRecord proc;
5783            int oomAdj;
5784            synchronized (this) {
5785                synchronized (mPidsSelfLocked) {
5786                    proc = mPidsSelfLocked.get(pids[i]);
5787                    oomAdj = proc != null ? proc.setAdj : 0;
5788                }
5789            }
5790            infos[i] = new Debug.MemoryInfo();
5791            Debug.getMemoryInfo(pids[i], infos[i]);
5792            if (proc != null) {
5793                synchronized (this) {
5794                    if (proc.thread != null && proc.setAdj == oomAdj) {
5795                        // Record this for posterity if the process has been stable.
5796                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5797                                infos[i].getTotalUss(), false, proc.pkgList);
5798                    }
5799                }
5800            }
5801        }
5802        return infos;
5803    }
5804
5805    @Override
5806    public long[] getProcessPss(int[] pids) {
5807        enforceNotIsolatedCaller("getProcessPss");
5808        long[] pss = new long[pids.length];
5809        for (int i=pids.length-1; i>=0; i--) {
5810            ProcessRecord proc;
5811            int oomAdj;
5812            synchronized (this) {
5813                synchronized (mPidsSelfLocked) {
5814                    proc = mPidsSelfLocked.get(pids[i]);
5815                    oomAdj = proc != null ? proc.setAdj : 0;
5816                }
5817            }
5818            long[] tmpUss = new long[1];
5819            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5820            if (proc != null) {
5821                synchronized (this) {
5822                    if (proc.thread != null && proc.setAdj == oomAdj) {
5823                        // Record this for posterity if the process has been stable.
5824                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5825                    }
5826                }
5827            }
5828        }
5829        return pss;
5830    }
5831
5832    @Override
5833    public void killApplicationProcess(String processName, int uid) {
5834        if (processName == null) {
5835            return;
5836        }
5837
5838        int callerUid = Binder.getCallingUid();
5839        // Only the system server can kill an application
5840        if (callerUid == Process.SYSTEM_UID) {
5841            synchronized (this) {
5842                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5843                if (app != null && app.thread != null) {
5844                    try {
5845                        app.thread.scheduleSuicide();
5846                    } catch (RemoteException e) {
5847                        // If the other end already died, then our work here is done.
5848                    }
5849                } else {
5850                    Slog.w(TAG, "Process/uid not found attempting kill of "
5851                            + processName + " / " + uid);
5852                }
5853            }
5854        } else {
5855            throw new SecurityException(callerUid + " cannot kill app process: " +
5856                    processName);
5857        }
5858    }
5859
5860    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5861        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5862                false, true, false, false, UserHandle.getUserId(uid), reason);
5863    }
5864
5865    private void finishForceStopPackageLocked(final String packageName, int uid) {
5866        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5867                Uri.fromParts("package", packageName, null));
5868        if (!mProcessesReady) {
5869            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5870                    | Intent.FLAG_RECEIVER_FOREGROUND);
5871        }
5872        intent.putExtra(Intent.EXTRA_UID, uid);
5873        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5874        broadcastIntentLocked(null, null, intent,
5875                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5876                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5877    }
5878
5879
5880    private final boolean killPackageProcessesLocked(String packageName, int appId,
5881            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5882            boolean doit, boolean evenPersistent, String reason) {
5883        ArrayList<ProcessRecord> procs = new ArrayList<>();
5884
5885        // Remove all processes this package may have touched: all with the
5886        // same UID (except for the system or root user), and all whose name
5887        // matches the package name.
5888        final int NP = mProcessNames.getMap().size();
5889        for (int ip=0; ip<NP; ip++) {
5890            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5891            final int NA = apps.size();
5892            for (int ia=0; ia<NA; ia++) {
5893                ProcessRecord app = apps.valueAt(ia);
5894                if (app.persistent && !evenPersistent) {
5895                    // we don't kill persistent processes
5896                    continue;
5897                }
5898                if (app.removed) {
5899                    if (doit) {
5900                        procs.add(app);
5901                    }
5902                    continue;
5903                }
5904
5905                // Skip process if it doesn't meet our oom adj requirement.
5906                if (app.setAdj < minOomAdj) {
5907                    continue;
5908                }
5909
5910                // If no package is specified, we call all processes under the
5911                // give user id.
5912                if (packageName == null) {
5913                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5914                        continue;
5915                    }
5916                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5917                        continue;
5918                    }
5919                // Package has been specified, we want to hit all processes
5920                // that match it.  We need to qualify this by the processes
5921                // that are running under the specified app and user ID.
5922                } else {
5923                    final boolean isDep = app.pkgDeps != null
5924                            && app.pkgDeps.contains(packageName);
5925                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5926                        continue;
5927                    }
5928                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5929                        continue;
5930                    }
5931                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5932                        continue;
5933                    }
5934                }
5935
5936                // Process has passed all conditions, kill it!
5937                if (!doit) {
5938                    return true;
5939                }
5940                app.removed = true;
5941                procs.add(app);
5942            }
5943        }
5944
5945        int N = procs.size();
5946        for (int i=0; i<N; i++) {
5947            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5948        }
5949        updateOomAdjLocked();
5950        return N > 0;
5951    }
5952
5953    private void cleanupDisabledPackageComponentsLocked(
5954            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5955
5956        Set<String> disabledClasses = null;
5957        boolean packageDisabled = false;
5958        IPackageManager pm = AppGlobals.getPackageManager();
5959
5960        if (changedClasses == null) {
5961            // Nothing changed...
5962            return;
5963        }
5964
5965        // Determine enable/disable state of the package and its components.
5966        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5967        for (int i = changedClasses.length - 1; i >= 0; i--) {
5968            final String changedClass = changedClasses[i];
5969
5970            if (changedClass.equals(packageName)) {
5971                try {
5972                    // Entire package setting changed
5973                    enabled = pm.getApplicationEnabledSetting(packageName,
5974                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5975                } catch (Exception e) {
5976                    // No such package/component; probably racing with uninstall.  In any
5977                    // event it means we have nothing further to do here.
5978                    return;
5979                }
5980                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5981                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5982                if (packageDisabled) {
5983                    // Entire package is disabled.
5984                    // No need to continue to check component states.
5985                    disabledClasses = null;
5986                    break;
5987                }
5988            } else {
5989                try {
5990                    enabled = pm.getComponentEnabledSetting(
5991                            new ComponentName(packageName, changedClass),
5992                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5993                } catch (Exception e) {
5994                    // As above, probably racing with uninstall.
5995                    return;
5996                }
5997                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5998                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5999                    if (disabledClasses == null) {
6000                        disabledClasses = new ArraySet<>(changedClasses.length);
6001                    }
6002                    disabledClasses.add(changedClass);
6003                }
6004            }
6005        }
6006
6007        if (!packageDisabled && disabledClasses == null) {
6008            // Nothing to do here...
6009            return;
6010        }
6011
6012        // Clean-up disabled activities.
6013        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6014                packageName, disabledClasses, true, false, userId) && mBooted) {
6015            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6016            mStackSupervisor.scheduleIdleLocked();
6017        }
6018
6019        // Clean-up disabled tasks
6020        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6021
6022        // Clean-up disabled services.
6023        mServices.bringDownDisabledPackageServicesLocked(
6024                packageName, disabledClasses, userId, false, killProcess, true);
6025
6026        // Clean-up disabled providers.
6027        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6028        mProviderMap.collectPackageProvidersLocked(
6029                packageName, disabledClasses, true, false, userId, providers);
6030        for (int i = providers.size() - 1; i >= 0; i--) {
6031            removeDyingProviderLocked(null, providers.get(i), true);
6032        }
6033
6034        // Clean-up disabled broadcast receivers.
6035        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6036            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6037                    packageName, disabledClasses, userId, true);
6038        }
6039
6040    }
6041
6042    final boolean clearBroadcastQueueForUserLocked(int userId) {
6043        boolean didSomething = false;
6044        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6045            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6046                    null, null, userId, true);
6047        }
6048        return didSomething;
6049    }
6050
6051    final boolean forceStopPackageLocked(String packageName, int appId,
6052            boolean callerWillRestart, boolean purgeCache, boolean doit,
6053            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6054        int i;
6055
6056        if (userId == UserHandle.USER_ALL && packageName == null) {
6057            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6058        }
6059
6060        if (appId < 0 && packageName != null) {
6061            try {
6062                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6063                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6064            } catch (RemoteException e) {
6065            }
6066        }
6067
6068        if (doit) {
6069            if (packageName != null) {
6070                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6071                        + " user=" + userId + ": " + reason);
6072            } else {
6073                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6074            }
6075
6076            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6077        }
6078
6079        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6080                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6081                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6082
6083        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6084
6085        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6086                packageName, null, doit, evenPersistent, userId)) {
6087            if (!doit) {
6088                return true;
6089            }
6090            didSomething = true;
6091        }
6092
6093        if (mServices.bringDownDisabledPackageServicesLocked(
6094                packageName, null, userId, evenPersistent, true, doit)) {
6095            if (!doit) {
6096                return true;
6097            }
6098            didSomething = true;
6099        }
6100
6101        if (packageName == null) {
6102            // Remove all sticky broadcasts from this user.
6103            mStickyBroadcasts.remove(userId);
6104        }
6105
6106        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6107        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6108                userId, providers)) {
6109            if (!doit) {
6110                return true;
6111            }
6112            didSomething = true;
6113        }
6114        for (i = providers.size() - 1; i >= 0; i--) {
6115            removeDyingProviderLocked(null, providers.get(i), true);
6116        }
6117
6118        // Remove transient permissions granted from/to this package/user
6119        removeUriPermissionsForPackageLocked(packageName, userId, false);
6120
6121        if (doit) {
6122            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6123                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6124                        packageName, null, userId, doit);
6125            }
6126        }
6127
6128        if (packageName == null || uninstalling) {
6129            // Remove pending intents.  For now we only do this when force
6130            // stopping users, because we have some problems when doing this
6131            // for packages -- app widgets are not currently cleaned up for
6132            // such packages, so they can be left with bad pending intents.
6133            if (mIntentSenderRecords.size() > 0) {
6134                Iterator<WeakReference<PendingIntentRecord>> it
6135                        = mIntentSenderRecords.values().iterator();
6136                while (it.hasNext()) {
6137                    WeakReference<PendingIntentRecord> wpir = it.next();
6138                    if (wpir == null) {
6139                        it.remove();
6140                        continue;
6141                    }
6142                    PendingIntentRecord pir = wpir.get();
6143                    if (pir == null) {
6144                        it.remove();
6145                        continue;
6146                    }
6147                    if (packageName == null) {
6148                        // Stopping user, remove all objects for the user.
6149                        if (pir.key.userId != userId) {
6150                            // Not the same user, skip it.
6151                            continue;
6152                        }
6153                    } else {
6154                        if (UserHandle.getAppId(pir.uid) != appId) {
6155                            // Different app id, skip it.
6156                            continue;
6157                        }
6158                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6159                            // Different user, skip it.
6160                            continue;
6161                        }
6162                        if (!pir.key.packageName.equals(packageName)) {
6163                            // Different package, skip it.
6164                            continue;
6165                        }
6166                    }
6167                    if (!doit) {
6168                        return true;
6169                    }
6170                    didSomething = true;
6171                    it.remove();
6172                    pir.canceled = true;
6173                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6174                        pir.key.activity.pendingResults.remove(pir.ref);
6175                    }
6176                }
6177            }
6178        }
6179
6180        if (doit) {
6181            if (purgeCache && packageName != null) {
6182                AttributeCache ac = AttributeCache.instance();
6183                if (ac != null) {
6184                    ac.removePackage(packageName);
6185                }
6186            }
6187            if (mBooted) {
6188                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6189                mStackSupervisor.scheduleIdleLocked();
6190            }
6191        }
6192
6193        return didSomething;
6194    }
6195
6196    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6197        ProcessRecord old = mProcessNames.remove(name, uid);
6198        if (old != null) {
6199            old.uidRecord.numProcs--;
6200            if (old.uidRecord.numProcs == 0) {
6201                // No more processes using this uid, tell clients it is gone.
6202                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6203                        "No more processes in " + old.uidRecord);
6204                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6205                mActiveUids.remove(uid);
6206                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6207            }
6208            old.uidRecord = null;
6209        }
6210        mIsolatedProcesses.remove(uid);
6211        return old;
6212    }
6213
6214    private final void addProcessNameLocked(ProcessRecord proc) {
6215        // We shouldn't already have a process under this name, but just in case we
6216        // need to clean up whatever may be there now.
6217        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6218        if (old == proc && proc.persistent) {
6219            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6220            Slog.w(TAG, "Re-adding persistent process " + proc);
6221        } else if (old != null) {
6222            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6223        }
6224        UidRecord uidRec = mActiveUids.get(proc.uid);
6225        if (uidRec == null) {
6226            uidRec = new UidRecord(proc.uid);
6227            // This is the first appearance of the uid, report it now!
6228            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6229                    "Creating new process uid: " + uidRec);
6230            mActiveUids.put(proc.uid, uidRec);
6231            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6232            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6233        }
6234        proc.uidRecord = uidRec;
6235
6236        // Reset render thread tid if it was already set, so new process can set it again.
6237        proc.renderThreadTid = 0;
6238        uidRec.numProcs++;
6239        mProcessNames.put(proc.processName, proc.uid, proc);
6240        if (proc.isolated) {
6241            mIsolatedProcesses.put(proc.uid, proc);
6242        }
6243    }
6244
6245    boolean removeProcessLocked(ProcessRecord app,
6246            boolean callerWillRestart, boolean allowRestart, String reason) {
6247        final String name = app.processName;
6248        final int uid = app.uid;
6249        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6250            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6251
6252        ProcessRecord old = mProcessNames.get(name, uid);
6253        if (old != app) {
6254            // This process is no longer active, so nothing to do.
6255            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6256            return false;
6257        }
6258        removeProcessNameLocked(name, uid);
6259        if (mHeavyWeightProcess == app) {
6260            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6261                    mHeavyWeightProcess.userId, 0));
6262            mHeavyWeightProcess = null;
6263        }
6264        boolean needRestart = false;
6265        if (app.pid > 0 && app.pid != MY_PID) {
6266            int pid = app.pid;
6267            synchronized (mPidsSelfLocked) {
6268                mPidsSelfLocked.remove(pid);
6269                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6270            }
6271            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6272            if (app.isolated) {
6273                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6274            }
6275            boolean willRestart = false;
6276            if (app.persistent && !app.isolated) {
6277                if (!callerWillRestart) {
6278                    willRestart = true;
6279                } else {
6280                    needRestart = true;
6281                }
6282            }
6283            app.kill(reason, true);
6284            handleAppDiedLocked(app, willRestart, allowRestart);
6285            if (willRestart) {
6286                removeLruProcessLocked(app);
6287                addAppLocked(app.info, false, null /* ABI override */);
6288            }
6289        } else {
6290            mRemovedProcesses.add(app);
6291        }
6292
6293        return needRestart;
6294    }
6295
6296    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6297        cleanupAppInLaunchingProvidersLocked(app, true);
6298        removeProcessLocked(app, false, true, "timeout publishing content providers");
6299    }
6300
6301    private final void processStartTimedOutLocked(ProcessRecord app) {
6302        final int pid = app.pid;
6303        boolean gone = false;
6304        synchronized (mPidsSelfLocked) {
6305            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6306            if (knownApp != null && knownApp.thread == null) {
6307                mPidsSelfLocked.remove(pid);
6308                gone = true;
6309            }
6310        }
6311
6312        if (gone) {
6313            Slog.w(TAG, "Process " + app + " failed to attach");
6314            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6315                    pid, app.uid, app.processName);
6316            removeProcessNameLocked(app.processName, app.uid);
6317            if (mHeavyWeightProcess == app) {
6318                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6319                        mHeavyWeightProcess.userId, 0));
6320                mHeavyWeightProcess = null;
6321            }
6322            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6323            if (app.isolated) {
6324                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6325            }
6326            // Take care of any launching providers waiting for this process.
6327            cleanupAppInLaunchingProvidersLocked(app, true);
6328            // Take care of any services that are waiting for the process.
6329            mServices.processStartTimedOutLocked(app);
6330            app.kill("start timeout", true);
6331            removeLruProcessLocked(app);
6332            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6333                Slog.w(TAG, "Unattached app died before backup, skipping");
6334                mHandler.post(new Runnable() {
6335                @Override
6336                    public void run(){
6337                        try {
6338                            IBackupManager bm = IBackupManager.Stub.asInterface(
6339                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6340                            bm.agentDisconnected(app.info.packageName);
6341                        } catch (RemoteException e) {
6342                            // Can't happen; the backup manager is local
6343                        }
6344                    }
6345                });
6346            }
6347            if (isPendingBroadcastProcessLocked(pid)) {
6348                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6349                skipPendingBroadcastLocked(pid);
6350            }
6351        } else {
6352            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6353        }
6354    }
6355
6356    private final boolean attachApplicationLocked(IApplicationThread thread,
6357            int pid) {
6358
6359        // Find the application record that is being attached...  either via
6360        // the pid if we are running in multiple processes, or just pull the
6361        // next app record if we are emulating process with anonymous threads.
6362        ProcessRecord app;
6363        if (pid != MY_PID && pid >= 0) {
6364            synchronized (mPidsSelfLocked) {
6365                app = mPidsSelfLocked.get(pid);
6366            }
6367        } else {
6368            app = null;
6369        }
6370
6371        if (app == null) {
6372            Slog.w(TAG, "No pending application record for pid " + pid
6373                    + " (IApplicationThread " + thread + "); dropping process");
6374            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6375            if (pid > 0 && pid != MY_PID) {
6376                Process.killProcessQuiet(pid);
6377                //TODO: killProcessGroup(app.info.uid, pid);
6378            } else {
6379                try {
6380                    thread.scheduleExit();
6381                } catch (Exception e) {
6382                    // Ignore exceptions.
6383                }
6384            }
6385            return false;
6386        }
6387
6388        // If this application record is still attached to a previous
6389        // process, clean it up now.
6390        if (app.thread != null) {
6391            handleAppDiedLocked(app, true, true);
6392        }
6393
6394        // Tell the process all about itself.
6395
6396        if (DEBUG_ALL) Slog.v(
6397                TAG, "Binding process pid " + pid + " to record " + app);
6398
6399        final String processName = app.processName;
6400        try {
6401            AppDeathRecipient adr = new AppDeathRecipient(
6402                    app, pid, thread);
6403            thread.asBinder().linkToDeath(adr, 0);
6404            app.deathRecipient = adr;
6405        } catch (RemoteException e) {
6406            app.resetPackageList(mProcessStats);
6407            startProcessLocked(app, "link fail", processName);
6408            return false;
6409        }
6410
6411        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6412
6413        app.makeActive(thread, mProcessStats);
6414        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6415        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6416        app.forcingToForeground = null;
6417        updateProcessForegroundLocked(app, false, false);
6418        app.hasShownUi = false;
6419        app.debugging = false;
6420        app.cached = false;
6421        app.killedByAm = false;
6422        app.killed = false;
6423
6424
6425        // We carefully use the same state that PackageManager uses for
6426        // filtering, since we use this flag to decide if we need to install
6427        // providers when user is unlocked later
6428        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6429
6430        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6431
6432        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6433        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6434
6435        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6436            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6437            msg.obj = app;
6438            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6439        }
6440
6441        if (!normalMode) {
6442            Slog.i(TAG, "Launching preboot mode app: " + app);
6443        }
6444
6445        if (DEBUG_ALL) Slog.v(
6446            TAG, "New app record " + app
6447            + " thread=" + thread.asBinder() + " pid=" + pid);
6448        try {
6449            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6450            if (mDebugApp != null && mDebugApp.equals(processName)) {
6451                testMode = mWaitForDebugger
6452                    ? ApplicationThreadConstants.DEBUG_WAIT
6453                    : ApplicationThreadConstants.DEBUG_ON;
6454                app.debugging = true;
6455                if (mDebugTransient) {
6456                    mDebugApp = mOrigDebugApp;
6457                    mWaitForDebugger = mOrigWaitForDebugger;
6458                }
6459            }
6460            String profileFile = app.instrumentationProfileFile;
6461            ParcelFileDescriptor profileFd = null;
6462            int samplingInterval = 0;
6463            boolean profileAutoStop = false;
6464            if (mProfileApp != null && mProfileApp.equals(processName)) {
6465                mProfileProc = app;
6466                profileFile = mProfileFile;
6467                profileFd = mProfileFd;
6468                samplingInterval = mSamplingInterval;
6469                profileAutoStop = mAutoStopProfiler;
6470            }
6471            boolean enableTrackAllocation = false;
6472            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6473                enableTrackAllocation = true;
6474                mTrackAllocationApp = null;
6475            }
6476
6477            // If the app is being launched for restore or full backup, set it up specially
6478            boolean isRestrictedBackupMode = false;
6479            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6480                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6481                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6482                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6483                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6484            }
6485
6486            if (app.instrumentationClass != null) {
6487                notifyPackageUse(app.instrumentationClass.getPackageName(),
6488                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6489            }
6490            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6491                    + processName + " with config " + getGlobalConfiguration());
6492            ApplicationInfo appInfo = app.instrumentationInfo != null
6493                    ? app.instrumentationInfo : app.info;
6494            app.compat = compatibilityInfoForPackageLocked(appInfo);
6495            if (profileFd != null) {
6496                profileFd = profileFd.dup();
6497            }
6498            ProfilerInfo profilerInfo = profileFile == null ? null
6499                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6500
6501            // We deprecated Build.SERIAL and only apps that target pre NMR1
6502            // SDK can see it. Since access to the serial is now behind a
6503            // permission we push down the value.
6504            String buildSerial = Build.UNKNOWN;
6505            // TODO: SHTOPSHIP Uncomment the check when clients migrate
6506//            if (appInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
6507                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6508                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6509                        .getSerial();
6510//            }
6511
6512            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6513                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6514                    app.instrumentationUiAutomationConnection, testMode,
6515                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6516                    isRestrictedBackupMode || !normalMode, app.persistent,
6517                    new Configuration(getGlobalConfiguration()), app.compat,
6518                    getCommonServicesLocked(app.isolated),
6519                    mCoreSettingsObserver.getCoreSettingsLocked(),
6520                    buildSerial);
6521
6522            updateLruProcessLocked(app, false, null);
6523            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6524        } catch (Exception e) {
6525            // todo: Yikes!  What should we do?  For now we will try to
6526            // start another process, but that could easily get us in
6527            // an infinite loop of restarting processes...
6528            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6529
6530            app.resetPackageList(mProcessStats);
6531            app.unlinkDeathRecipient();
6532            startProcessLocked(app, "bind fail", processName);
6533            return false;
6534        }
6535
6536        // Remove this record from the list of starting applications.
6537        mPersistentStartingProcesses.remove(app);
6538        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6539                "Attach application locked removing on hold: " + app);
6540        mProcessesOnHold.remove(app);
6541
6542        boolean badApp = false;
6543        boolean didSomething = false;
6544
6545        // See if the top visible activity is waiting to run in this process...
6546        if (normalMode) {
6547            try {
6548                if (mStackSupervisor.attachApplicationLocked(app)) {
6549                    didSomething = true;
6550                }
6551            } catch (Exception e) {
6552                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6553                badApp = true;
6554            }
6555        }
6556
6557        // Find any services that should be running in this process...
6558        if (!badApp) {
6559            try {
6560                didSomething |= mServices.attachApplicationLocked(app, processName);
6561            } catch (Exception e) {
6562                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6563                badApp = true;
6564            }
6565        }
6566
6567        // Check if a next-broadcast receiver is in this process...
6568        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6569            try {
6570                didSomething |= sendPendingBroadcastsLocked(app);
6571            } catch (Exception e) {
6572                // If the app died trying to launch the receiver we declare it 'bad'
6573                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6574                badApp = true;
6575            }
6576        }
6577
6578        // Check whether the next backup agent is in this process...
6579        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6580            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6581                    "New app is backup target, launching agent for " + app);
6582            notifyPackageUse(mBackupTarget.appInfo.packageName,
6583                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6584            try {
6585                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6586                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6587                        mBackupTarget.backupMode);
6588            } catch (Exception e) {
6589                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6590                badApp = true;
6591            }
6592        }
6593
6594        if (badApp) {
6595            app.kill("error during init", true);
6596            handleAppDiedLocked(app, false, true);
6597            return false;
6598        }
6599
6600        if (!didSomething) {
6601            updateOomAdjLocked();
6602        }
6603
6604        return true;
6605    }
6606
6607    @Override
6608    public final void attachApplication(IApplicationThread thread) {
6609        synchronized (this) {
6610            int callingPid = Binder.getCallingPid();
6611            final long origId = Binder.clearCallingIdentity();
6612            attachApplicationLocked(thread, callingPid);
6613            Binder.restoreCallingIdentity(origId);
6614        }
6615    }
6616
6617    @Override
6618    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6619        final long origId = Binder.clearCallingIdentity();
6620        synchronized (this) {
6621            ActivityStack stack = ActivityRecord.getStackLocked(token);
6622            if (stack != null) {
6623                ActivityRecord r =
6624                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6625                if (stopProfiling) {
6626                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6627                        try {
6628                            mProfileFd.close();
6629                        } catch (IOException e) {
6630                        }
6631                        clearProfilerLocked();
6632                    }
6633                }
6634            }
6635        }
6636        Binder.restoreCallingIdentity(origId);
6637    }
6638
6639    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6640        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6641                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6642    }
6643
6644    void enableScreenAfterBoot() {
6645        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6646                SystemClock.uptimeMillis());
6647        mWindowManager.enableScreenAfterBoot();
6648
6649        synchronized (this) {
6650            updateEventDispatchingLocked();
6651        }
6652    }
6653
6654    @Override
6655    public void showBootMessage(final CharSequence msg, final boolean always) {
6656        if (Binder.getCallingUid() != Process.myUid()) {
6657            throw new SecurityException();
6658        }
6659        mWindowManager.showBootMessage(msg, always);
6660    }
6661
6662    @Override
6663    public void keyguardGoingAway(int flags) {
6664        enforceNotIsolatedCaller("keyguardGoingAway");
6665        final long token = Binder.clearCallingIdentity();
6666        try {
6667            synchronized (this) {
6668                mKeyguardController.keyguardGoingAway(flags);
6669            }
6670        } finally {
6671            Binder.restoreCallingIdentity(token);
6672        }
6673    }
6674
6675    final void finishBooting() {
6676        synchronized (this) {
6677            if (!mBootAnimationComplete) {
6678                mCallFinishBooting = true;
6679                return;
6680            }
6681            mCallFinishBooting = false;
6682        }
6683
6684        ArraySet<String> completedIsas = new ArraySet<String>();
6685        for (String abi : Build.SUPPORTED_ABIS) {
6686            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6687            final String instructionSet = VMRuntime.getInstructionSet(abi);
6688            if (!completedIsas.contains(instructionSet)) {
6689                try {
6690                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6691                } catch (InstallerException e) {
6692                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6693                            e.getMessage() +")");
6694                }
6695                completedIsas.add(instructionSet);
6696            }
6697        }
6698
6699        IntentFilter pkgFilter = new IntentFilter();
6700        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6701        pkgFilter.addDataScheme("package");
6702        mContext.registerReceiver(new BroadcastReceiver() {
6703            @Override
6704            public void onReceive(Context context, Intent intent) {
6705                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6706                if (pkgs != null) {
6707                    for (String pkg : pkgs) {
6708                        synchronized (ActivityManagerService.this) {
6709                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6710                                    0, "query restart")) {
6711                                setResultCode(Activity.RESULT_OK);
6712                                return;
6713                            }
6714                        }
6715                    }
6716                }
6717            }
6718        }, pkgFilter);
6719
6720        IntentFilter dumpheapFilter = new IntentFilter();
6721        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6722        mContext.registerReceiver(new BroadcastReceiver() {
6723            @Override
6724            public void onReceive(Context context, Intent intent) {
6725                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6726                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6727                } else {
6728                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6729                }
6730            }
6731        }, dumpheapFilter);
6732
6733        // Let system services know.
6734        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6735
6736        synchronized (this) {
6737            // Ensure that any processes we had put on hold are now started
6738            // up.
6739            final int NP = mProcessesOnHold.size();
6740            if (NP > 0) {
6741                ArrayList<ProcessRecord> procs =
6742                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6743                for (int ip=0; ip<NP; ip++) {
6744                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6745                            + procs.get(ip));
6746                    startProcessLocked(procs.get(ip), "on-hold", null);
6747                }
6748            }
6749
6750            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6751                // Start looking for apps that are abusing wake locks.
6752                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6753                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6754                // Tell anyone interested that we are done booting!
6755                SystemProperties.set("sys.boot_completed", "1");
6756
6757                // And trigger dev.bootcomplete if we are not showing encryption progress
6758                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6759                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6760                    SystemProperties.set("dev.bootcomplete", "1");
6761                }
6762                mUserController.sendBootCompletedLocked(
6763                        new IIntentReceiver.Stub() {
6764                            @Override
6765                            public void performReceive(Intent intent, int resultCode,
6766                                    String data, Bundle extras, boolean ordered,
6767                                    boolean sticky, int sendingUser) {
6768                                synchronized (ActivityManagerService.this) {
6769                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6770                                            true, false);
6771                                }
6772                            }
6773                        });
6774                scheduleStartProfilesLocked();
6775            }
6776        }
6777    }
6778
6779    @Override
6780    public void bootAnimationComplete() {
6781        final boolean callFinishBooting;
6782        synchronized (this) {
6783            callFinishBooting = mCallFinishBooting;
6784            mBootAnimationComplete = true;
6785        }
6786        if (callFinishBooting) {
6787            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6788            finishBooting();
6789            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6790        }
6791    }
6792
6793    final void ensureBootCompleted() {
6794        boolean booting;
6795        boolean enableScreen;
6796        synchronized (this) {
6797            booting = mBooting;
6798            mBooting = false;
6799            enableScreen = !mBooted;
6800            mBooted = true;
6801        }
6802
6803        if (booting) {
6804            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6805            finishBooting();
6806            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6807        }
6808
6809        if (enableScreen) {
6810            enableScreenAfterBoot();
6811        }
6812    }
6813
6814    @Override
6815    public final void activityResumed(IBinder token) {
6816        final long origId = Binder.clearCallingIdentity();
6817        synchronized(this) {
6818            ActivityRecord.activityResumedLocked(token);
6819            mWindowManager.notifyAppResumedFinished(token);
6820        }
6821        Binder.restoreCallingIdentity(origId);
6822    }
6823
6824    @Override
6825    public final void activityPaused(IBinder token) {
6826        final long origId = Binder.clearCallingIdentity();
6827        synchronized(this) {
6828            ActivityStack stack = ActivityRecord.getStackLocked(token);
6829            if (stack != null) {
6830                stack.activityPausedLocked(token, false);
6831            }
6832        }
6833        Binder.restoreCallingIdentity(origId);
6834    }
6835
6836    @Override
6837    public final void activityStopped(IBinder token, Bundle icicle,
6838            PersistableBundle persistentState, CharSequence description) {
6839        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6840
6841        // Refuse possible leaked file descriptors
6842        if (icicle != null && icicle.hasFileDescriptors()) {
6843            throw new IllegalArgumentException("File descriptors passed in Bundle");
6844        }
6845
6846        final long origId = Binder.clearCallingIdentity();
6847
6848        synchronized (this) {
6849            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6850            if (r != null) {
6851                r.activityStoppedLocked(icicle, persistentState, description);
6852            }
6853        }
6854
6855        trimApplications();
6856
6857        Binder.restoreCallingIdentity(origId);
6858    }
6859
6860    @Override
6861    public final void activityDestroyed(IBinder token) {
6862        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6863        synchronized (this) {
6864            ActivityStack stack = ActivityRecord.getStackLocked(token);
6865            if (stack != null) {
6866                stack.activityDestroyedLocked(token, "activityDestroyed");
6867            }
6868        }
6869    }
6870
6871    @Override
6872    public final void activityRelaunched(IBinder token) {
6873        final long origId = Binder.clearCallingIdentity();
6874        synchronized (this) {
6875            mStackSupervisor.activityRelaunchedLocked(token);
6876        }
6877        Binder.restoreCallingIdentity(origId);
6878    }
6879
6880    @Override
6881    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6882            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6883        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6884                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6885        synchronized (this) {
6886            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6887            if (record == null) {
6888                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6889                        + "found for: " + token);
6890            }
6891            record.setSizeConfigurations(horizontalSizeConfiguration,
6892                    verticalSizeConfigurations, smallestSizeConfigurations);
6893        }
6894    }
6895
6896    @Override
6897    public final void backgroundResourcesReleased(IBinder token) {
6898        final long origId = Binder.clearCallingIdentity();
6899        try {
6900            synchronized (this) {
6901                ActivityStack stack = ActivityRecord.getStackLocked(token);
6902                if (stack != null) {
6903                    stack.backgroundResourcesReleased();
6904                }
6905            }
6906        } finally {
6907            Binder.restoreCallingIdentity(origId);
6908        }
6909    }
6910
6911    @Override
6912    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6913        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6914    }
6915
6916    @Override
6917    public final void notifyEnterAnimationComplete(IBinder token) {
6918        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6919    }
6920
6921    @Override
6922    public String getCallingPackage(IBinder token) {
6923        synchronized (this) {
6924            ActivityRecord r = getCallingRecordLocked(token);
6925            return r != null ? r.info.packageName : null;
6926        }
6927    }
6928
6929    @Override
6930    public ComponentName getCallingActivity(IBinder token) {
6931        synchronized (this) {
6932            ActivityRecord r = getCallingRecordLocked(token);
6933            return r != null ? r.intent.getComponent() : null;
6934        }
6935    }
6936
6937    private ActivityRecord getCallingRecordLocked(IBinder token) {
6938        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6939        if (r == null) {
6940            return null;
6941        }
6942        return r.resultTo;
6943    }
6944
6945    @Override
6946    public ComponentName getActivityClassForToken(IBinder token) {
6947        synchronized(this) {
6948            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6949            if (r == null) {
6950                return null;
6951            }
6952            return r.intent.getComponent();
6953        }
6954    }
6955
6956    @Override
6957    public String getPackageForToken(IBinder token) {
6958        synchronized(this) {
6959            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6960            if (r == null) {
6961                return null;
6962            }
6963            return r.packageName;
6964        }
6965    }
6966
6967    @Override
6968    public boolean isRootVoiceInteraction(IBinder token) {
6969        synchronized(this) {
6970            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6971            if (r == null) {
6972                return false;
6973            }
6974            return r.rootVoiceInteraction;
6975        }
6976    }
6977
6978    @Override
6979    public IIntentSender getIntentSender(int type,
6980            String packageName, IBinder token, String resultWho,
6981            int requestCode, Intent[] intents, String[] resolvedTypes,
6982            int flags, Bundle bOptions, int userId) {
6983        enforceNotIsolatedCaller("getIntentSender");
6984        // Refuse possible leaked file descriptors
6985        if (intents != null) {
6986            if (intents.length < 1) {
6987                throw new IllegalArgumentException("Intents array length must be >= 1");
6988            }
6989            for (int i=0; i<intents.length; i++) {
6990                Intent intent = intents[i];
6991                if (intent != null) {
6992                    if (intent.hasFileDescriptors()) {
6993                        throw new IllegalArgumentException("File descriptors passed in Intent");
6994                    }
6995                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6996                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6997                        throw new IllegalArgumentException(
6998                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6999                    }
7000                    intents[i] = new Intent(intent);
7001                }
7002            }
7003            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7004                throw new IllegalArgumentException(
7005                        "Intent array length does not match resolvedTypes length");
7006            }
7007        }
7008        if (bOptions != null) {
7009            if (bOptions.hasFileDescriptors()) {
7010                throw new IllegalArgumentException("File descriptors passed in options");
7011            }
7012        }
7013
7014        synchronized(this) {
7015            int callingUid = Binder.getCallingUid();
7016            int origUserId = userId;
7017            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7018                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7019                    ALLOW_NON_FULL, "getIntentSender", null);
7020            if (origUserId == UserHandle.USER_CURRENT) {
7021                // We don't want to evaluate this until the pending intent is
7022                // actually executed.  However, we do want to always do the
7023                // security checking for it above.
7024                userId = UserHandle.USER_CURRENT;
7025            }
7026            try {
7027                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7028                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7029                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7030                    if (!UserHandle.isSameApp(callingUid, uid)) {
7031                        String msg = "Permission Denial: getIntentSender() from pid="
7032                            + Binder.getCallingPid()
7033                            + ", uid=" + Binder.getCallingUid()
7034                            + ", (need uid=" + uid + ")"
7035                            + " is not allowed to send as package " + packageName;
7036                        Slog.w(TAG, msg);
7037                        throw new SecurityException(msg);
7038                    }
7039                }
7040
7041                return getIntentSenderLocked(type, packageName, callingUid, userId,
7042                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7043
7044            } catch (RemoteException e) {
7045                throw new SecurityException(e);
7046            }
7047        }
7048    }
7049
7050    IIntentSender getIntentSenderLocked(int type, String packageName,
7051            int callingUid, int userId, IBinder token, String resultWho,
7052            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7053            Bundle bOptions) {
7054        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7055        ActivityRecord activity = null;
7056        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7057            activity = ActivityRecord.isInStackLocked(token);
7058            if (activity == null) {
7059                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7060                return null;
7061            }
7062            if (activity.finishing) {
7063                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7064                return null;
7065            }
7066        }
7067
7068        // We're going to be splicing together extras before sending, so we're
7069        // okay poking into any contained extras.
7070        if (intents != null) {
7071            for (int i = 0; i < intents.length; i++) {
7072                intents[i].setDefusable(true);
7073            }
7074        }
7075        Bundle.setDefusable(bOptions, true);
7076
7077        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7078        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7079        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7080        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7081                |PendingIntent.FLAG_UPDATE_CURRENT);
7082
7083        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7084                type, packageName, activity, resultWho,
7085                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7086        WeakReference<PendingIntentRecord> ref;
7087        ref = mIntentSenderRecords.get(key);
7088        PendingIntentRecord rec = ref != null ? ref.get() : null;
7089        if (rec != null) {
7090            if (!cancelCurrent) {
7091                if (updateCurrent) {
7092                    if (rec.key.requestIntent != null) {
7093                        rec.key.requestIntent.replaceExtras(intents != null ?
7094                                intents[intents.length - 1] : null);
7095                    }
7096                    if (intents != null) {
7097                        intents[intents.length-1] = rec.key.requestIntent;
7098                        rec.key.allIntents = intents;
7099                        rec.key.allResolvedTypes = resolvedTypes;
7100                    } else {
7101                        rec.key.allIntents = null;
7102                        rec.key.allResolvedTypes = null;
7103                    }
7104                }
7105                return rec;
7106            }
7107            rec.canceled = true;
7108            mIntentSenderRecords.remove(key);
7109        }
7110        if (noCreate) {
7111            return rec;
7112        }
7113        rec = new PendingIntentRecord(this, key, callingUid);
7114        mIntentSenderRecords.put(key, rec.ref);
7115        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7116            if (activity.pendingResults == null) {
7117                activity.pendingResults
7118                        = new HashSet<WeakReference<PendingIntentRecord>>();
7119            }
7120            activity.pendingResults.add(rec.ref);
7121        }
7122        return rec;
7123    }
7124
7125    @Override
7126    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7127            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7128        if (target instanceof PendingIntentRecord) {
7129            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7130                    finishedReceiver, requiredPermission, options);
7131        } else {
7132            if (intent == null) {
7133                // Weird case: someone has given us their own custom IIntentSender, and now
7134                // they have someone else trying to send to it but of course this isn't
7135                // really a PendingIntent, so there is no base Intent, and the caller isn't
7136                // supplying an Intent... but we never want to dispatch a null Intent to
7137                // a receiver, so um...  let's make something up.
7138                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7139                intent = new Intent(Intent.ACTION_MAIN);
7140            }
7141            try {
7142                target.send(code, intent, resolvedType, null, requiredPermission, options);
7143            } catch (RemoteException e) {
7144            }
7145            // Platform code can rely on getting a result back when the send is done, but if
7146            // this intent sender is from outside of the system we can't rely on it doing that.
7147            // So instead we don't give it the result receiver, and instead just directly
7148            // report the finish immediately.
7149            if (finishedReceiver != null) {
7150                try {
7151                    finishedReceiver.performReceive(intent, 0,
7152                            null, null, false, false, UserHandle.getCallingUserId());
7153                } catch (RemoteException e) {
7154                }
7155            }
7156            return 0;
7157        }
7158    }
7159
7160    /**
7161     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7162     *
7163     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7164     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7165     */
7166    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7167        if (DEBUG_WHITELISTS) {
7168            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7169                    + targetUid + ", " + duration + ")");
7170        }
7171        synchronized (mPidsSelfLocked) {
7172            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7173            if (pr == null) {
7174                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7175                return;
7176            }
7177            if (!pr.whitelistManager) {
7178                if (DEBUG_WHITELISTS) {
7179                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7180                            + callerPid + " is not allowed");
7181                }
7182                return;
7183            }
7184        }
7185
7186        final long token = Binder.clearCallingIdentity();
7187        try {
7188            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7189                    true, "pe from uid:" + callerUid);
7190        } finally {
7191            Binder.restoreCallingIdentity(token);
7192        }
7193    }
7194
7195    @Override
7196    public void cancelIntentSender(IIntentSender sender) {
7197        if (!(sender instanceof PendingIntentRecord)) {
7198            return;
7199        }
7200        synchronized(this) {
7201            PendingIntentRecord rec = (PendingIntentRecord)sender;
7202            try {
7203                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7204                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7205                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7206                    String msg = "Permission Denial: cancelIntentSender() from pid="
7207                        + Binder.getCallingPid()
7208                        + ", uid=" + Binder.getCallingUid()
7209                        + " is not allowed to cancel packges "
7210                        + rec.key.packageName;
7211                    Slog.w(TAG, msg);
7212                    throw new SecurityException(msg);
7213                }
7214            } catch (RemoteException e) {
7215                throw new SecurityException(e);
7216            }
7217            cancelIntentSenderLocked(rec, true);
7218        }
7219    }
7220
7221    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7222        rec.canceled = true;
7223        mIntentSenderRecords.remove(rec.key);
7224        if (cleanActivity && rec.key.activity != null) {
7225            rec.key.activity.pendingResults.remove(rec.ref);
7226        }
7227    }
7228
7229    @Override
7230    public String getPackageForIntentSender(IIntentSender pendingResult) {
7231        if (!(pendingResult instanceof PendingIntentRecord)) {
7232            return null;
7233        }
7234        try {
7235            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7236            return res.key.packageName;
7237        } catch (ClassCastException e) {
7238        }
7239        return null;
7240    }
7241
7242    @Override
7243    public int getUidForIntentSender(IIntentSender sender) {
7244        if (sender instanceof PendingIntentRecord) {
7245            try {
7246                PendingIntentRecord res = (PendingIntentRecord)sender;
7247                return res.uid;
7248            } catch (ClassCastException e) {
7249            }
7250        }
7251        return -1;
7252    }
7253
7254    @Override
7255    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7256        if (!(pendingResult instanceof PendingIntentRecord)) {
7257            return false;
7258        }
7259        try {
7260            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7261            if (res.key.allIntents == null) {
7262                return false;
7263            }
7264            for (int i=0; i<res.key.allIntents.length; i++) {
7265                Intent intent = res.key.allIntents[i];
7266                if (intent.getPackage() != null && intent.getComponent() != null) {
7267                    return false;
7268                }
7269            }
7270            return true;
7271        } catch (ClassCastException e) {
7272        }
7273        return false;
7274    }
7275
7276    @Override
7277    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7278        if (!(pendingResult instanceof PendingIntentRecord)) {
7279            return false;
7280        }
7281        try {
7282            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7283            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7284                return true;
7285            }
7286            return false;
7287        } catch (ClassCastException e) {
7288        }
7289        return false;
7290    }
7291
7292    @Override
7293    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7294        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7295                "getIntentForIntentSender()");
7296        if (!(pendingResult instanceof PendingIntentRecord)) {
7297            return null;
7298        }
7299        try {
7300            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7301            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7302        } catch (ClassCastException e) {
7303        }
7304        return null;
7305    }
7306
7307    @Override
7308    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7309        if (!(pendingResult instanceof PendingIntentRecord)) {
7310            return null;
7311        }
7312        try {
7313            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7314            synchronized (this) {
7315                return getTagForIntentSenderLocked(res, prefix);
7316            }
7317        } catch (ClassCastException e) {
7318        }
7319        return null;
7320    }
7321
7322    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7323        final Intent intent = res.key.requestIntent;
7324        if (intent != null) {
7325            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7326                    || res.lastTagPrefix.equals(prefix))) {
7327                return res.lastTag;
7328            }
7329            res.lastTagPrefix = prefix;
7330            final StringBuilder sb = new StringBuilder(128);
7331            if (prefix != null) {
7332                sb.append(prefix);
7333            }
7334            if (intent.getAction() != null) {
7335                sb.append(intent.getAction());
7336            } else if (intent.getComponent() != null) {
7337                intent.getComponent().appendShortString(sb);
7338            } else {
7339                sb.append("?");
7340            }
7341            return res.lastTag = sb.toString();
7342        }
7343        return null;
7344    }
7345
7346    @Override
7347    public void setProcessLimit(int max) {
7348        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7349                "setProcessLimit()");
7350        synchronized (this) {
7351            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7352            mProcessLimitOverride = max;
7353        }
7354        trimApplications();
7355    }
7356
7357    @Override
7358    public int getProcessLimit() {
7359        synchronized (this) {
7360            return mProcessLimitOverride;
7361        }
7362    }
7363
7364    void foregroundTokenDied(ForegroundToken token) {
7365        synchronized (ActivityManagerService.this) {
7366            synchronized (mPidsSelfLocked) {
7367                ForegroundToken cur
7368                    = mForegroundProcesses.get(token.pid);
7369                if (cur != token) {
7370                    return;
7371                }
7372                mForegroundProcesses.remove(token.pid);
7373                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7374                if (pr == null) {
7375                    return;
7376                }
7377                pr.forcingToForeground = null;
7378                updateProcessForegroundLocked(pr, false, false);
7379            }
7380            updateOomAdjLocked();
7381        }
7382    }
7383
7384    @Override
7385    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7386        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7387                "setProcessForeground()");
7388        synchronized(this) {
7389            boolean changed = false;
7390
7391            synchronized (mPidsSelfLocked) {
7392                ProcessRecord pr = mPidsSelfLocked.get(pid);
7393                if (pr == null && isForeground) {
7394                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7395                    return;
7396                }
7397                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7398                if (oldToken != null) {
7399                    oldToken.token.unlinkToDeath(oldToken, 0);
7400                    mForegroundProcesses.remove(pid);
7401                    if (pr != null) {
7402                        pr.forcingToForeground = null;
7403                    }
7404                    changed = true;
7405                }
7406                if (isForeground && token != null) {
7407                    ForegroundToken newToken = new ForegroundToken() {
7408                        @Override
7409                        public void binderDied() {
7410                            foregroundTokenDied(this);
7411                        }
7412                    };
7413                    newToken.pid = pid;
7414                    newToken.token = token;
7415                    try {
7416                        token.linkToDeath(newToken, 0);
7417                        mForegroundProcesses.put(pid, newToken);
7418                        pr.forcingToForeground = token;
7419                        changed = true;
7420                    } catch (RemoteException e) {
7421                        // If the process died while doing this, we will later
7422                        // do the cleanup with the process death link.
7423                    }
7424                }
7425            }
7426
7427            if (changed) {
7428                updateOomAdjLocked();
7429            }
7430        }
7431    }
7432
7433    @Override
7434    public boolean isAppForeground(int uid) throws RemoteException {
7435        synchronized (this) {
7436            UidRecord uidRec = mActiveUids.get(uid);
7437            if (uidRec == null || uidRec.idle) {
7438                return false;
7439            }
7440            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7441        }
7442    }
7443
7444    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7445    // be guarded by permission checking.
7446    int getUidState(int uid) {
7447        synchronized (this) {
7448            UidRecord uidRec = mActiveUids.get(uid);
7449            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7450        }
7451    }
7452
7453    @Override
7454    public boolean isInMultiWindowMode(IBinder token) {
7455        final long origId = Binder.clearCallingIdentity();
7456        try {
7457            synchronized(this) {
7458                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7459                if (r == null) {
7460                    return false;
7461                }
7462                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7463                return !r.task.mFullscreen;
7464            }
7465        } finally {
7466            Binder.restoreCallingIdentity(origId);
7467        }
7468    }
7469
7470    @Override
7471    public boolean isInPictureInPictureMode(IBinder token) {
7472        final long origId = Binder.clearCallingIdentity();
7473        try {
7474            synchronized(this) {
7475                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7476                if (stack == null) {
7477                    return false;
7478                }
7479                return stack.mStackId == PINNED_STACK_ID;
7480            }
7481        } finally {
7482            Binder.restoreCallingIdentity(origId);
7483        }
7484    }
7485
7486    @Override
7487    public void enterPictureInPictureMode(IBinder token) {
7488        enterPictureInPictureMode(token, DEFAULT_DISPLAY, null /* aspectRatio */);
7489    }
7490
7491    @Override
7492    public void enterPictureInPictureModeWithAspectRatio(IBinder token, float aspectRatio) {
7493        enterPictureInPictureMode(token, DEFAULT_DISPLAY, aspectRatio);
7494    }
7495
7496    public void enterPictureInPictureMode(IBinder token, int displayId, Float aspectRatio) {
7497        final long origId = Binder.clearCallingIdentity();
7498        try {
7499            synchronized(this) {
7500                if (!mSupportsPictureInPicture) {
7501                    throw new IllegalStateException("enterPictureInPictureMode: "
7502                            + "Device doesn't support picture-in-picture mode.");
7503                }
7504
7505                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7506                if (r == null) {
7507                    throw new IllegalStateException("enterPictureInPictureMode: "
7508                            + "Can't find activity for token=" + token);
7509                }
7510
7511                if (!r.supportsPictureInPicture()) {
7512                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7513                            + "Picture-In-Picture not supported for r=" + r);
7514                }
7515
7516                if (aspectRatio != null && !isValidPictureInPictureAspectRatio(aspectRatio)) {
7517                    throw new IllegalArgumentException(String.format("enterPictureInPictureMode: "
7518                            + "Aspect ratio is too extreme (must be between %f and %f).",
7519                                    mMinPipAspectRatio, mMaxPipAspectRatio));
7520                }
7521
7522                final Rect bounds = isValidPictureInPictureAspectRatio(aspectRatio)
7523                        ? mWindowManager.getPictureInPictureBounds(displayId, aspectRatio)
7524                        : mWindowManager.getPictureInPictureDefaultBounds(displayId);
7525                mStackSupervisor.moveActivityToPinnedStackLocked(r, "enterPictureInPictureMode",
7526                        bounds);
7527            }
7528        } finally {
7529            Binder.restoreCallingIdentity(origId);
7530        }
7531    }
7532
7533    @Override
7534    public void setPictureInPictureAspectRatio(IBinder token, float aspectRatio) {
7535        final long origId = Binder.clearCallingIdentity();
7536        try {
7537            synchronized(this) {
7538                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7539                if (r == null || r.getStack().mStackId != PINNED_STACK_ID) {
7540                    throw new IllegalStateException("setPictureInPictureAspectRatio: "
7541                            + "Requesting activity must be in picture-in-picture mode.");
7542                }
7543
7544                if (!isValidPictureInPictureAspectRatio(aspectRatio)) {
7545                    throw new IllegalArgumentException(String.format(
7546                            "setPictureInPictureAspectRatio: Aspect ratio is too extreme (must be "
7547                                    + "between %f and %f).", mMinPipAspectRatio,
7548                            mMaxPipAspectRatio));
7549                }
7550
7551                mWindowManager.setPictureInPictureAspectRatio(aspectRatio);
7552            }
7553        } finally {
7554            Binder.restoreCallingIdentity(origId);
7555        }
7556    }
7557
7558    private boolean isValidPictureInPictureAspectRatio(Float aspectRatio) {
7559        if (aspectRatio == null) {
7560            return false;
7561        }
7562        return mMinPipAspectRatio <= aspectRatio && aspectRatio <= mMaxPipAspectRatio;
7563    }
7564
7565    // =========================================================
7566    // PROCESS INFO
7567    // =========================================================
7568
7569    static class ProcessInfoService extends IProcessInfoService.Stub {
7570        final ActivityManagerService mActivityManagerService;
7571        ProcessInfoService(ActivityManagerService activityManagerService) {
7572            mActivityManagerService = activityManagerService;
7573        }
7574
7575        @Override
7576        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7577            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7578                    /*in*/ pids, /*out*/ states, null);
7579        }
7580
7581        @Override
7582        public void getProcessStatesAndOomScoresFromPids(
7583                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7584            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7585                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7586        }
7587    }
7588
7589    /**
7590     * For each PID in the given input array, write the current process state
7591     * for that process into the states array, or -1 to indicate that no
7592     * process with the given PID exists. If scores array is provided, write
7593     * the oom score for the process into the scores array, with INVALID_ADJ
7594     * indicating the PID doesn't exist.
7595     */
7596    public void getProcessStatesAndOomScoresForPIDs(
7597            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7598        if (scores != null) {
7599            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7600                    "getProcessStatesAndOomScoresForPIDs()");
7601        }
7602
7603        if (pids == null) {
7604            throw new NullPointerException("pids");
7605        } else if (states == null) {
7606            throw new NullPointerException("states");
7607        } else if (pids.length != states.length) {
7608            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7609        } else if (scores != null && pids.length != scores.length) {
7610            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7611        }
7612
7613        synchronized (mPidsSelfLocked) {
7614            for (int i = 0; i < pids.length; i++) {
7615                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7616                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7617                        pr.curProcState;
7618                if (scores != null) {
7619                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7620                }
7621            }
7622        }
7623    }
7624
7625    // =========================================================
7626    // PERMISSIONS
7627    // =========================================================
7628
7629    static class PermissionController extends IPermissionController.Stub {
7630        ActivityManagerService mActivityManagerService;
7631        PermissionController(ActivityManagerService activityManagerService) {
7632            mActivityManagerService = activityManagerService;
7633        }
7634
7635        @Override
7636        public boolean checkPermission(String permission, int pid, int uid) {
7637            return mActivityManagerService.checkPermission(permission, pid,
7638                    uid) == PackageManager.PERMISSION_GRANTED;
7639        }
7640
7641        @Override
7642        public String[] getPackagesForUid(int uid) {
7643            return mActivityManagerService.mContext.getPackageManager()
7644                    .getPackagesForUid(uid);
7645        }
7646
7647        @Override
7648        public boolean isRuntimePermission(String permission) {
7649            try {
7650                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7651                        .getPermissionInfo(permission, 0);
7652                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
7653                        == PermissionInfo.PROTECTION_DANGEROUS;
7654            } catch (NameNotFoundException nnfe) {
7655                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7656            }
7657            return false;
7658        }
7659    }
7660
7661    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7662        @Override
7663        public int checkComponentPermission(String permission, int pid, int uid,
7664                int owningUid, boolean exported) {
7665            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7666                    owningUid, exported);
7667        }
7668
7669        @Override
7670        public Object getAMSLock() {
7671            return ActivityManagerService.this;
7672        }
7673    }
7674
7675    /**
7676     * This can be called with or without the global lock held.
7677     */
7678    int checkComponentPermission(String permission, int pid, int uid,
7679            int owningUid, boolean exported) {
7680        if (pid == MY_PID) {
7681            return PackageManager.PERMISSION_GRANTED;
7682        }
7683        return ActivityManager.checkComponentPermission(permission, uid,
7684                owningUid, exported);
7685    }
7686
7687    /**
7688     * As the only public entry point for permissions checking, this method
7689     * can enforce the semantic that requesting a check on a null global
7690     * permission is automatically denied.  (Internally a null permission
7691     * string is used when calling {@link #checkComponentPermission} in cases
7692     * when only uid-based security is needed.)
7693     *
7694     * This can be called with or without the global lock held.
7695     */
7696    @Override
7697    public int checkPermission(String permission, int pid, int uid) {
7698        if (permission == null) {
7699            return PackageManager.PERMISSION_DENIED;
7700        }
7701        return checkComponentPermission(permission, pid, uid, -1, true);
7702    }
7703
7704    @Override
7705    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7706        if (permission == null) {
7707            return PackageManager.PERMISSION_DENIED;
7708        }
7709
7710        // We might be performing an operation on behalf of an indirect binder
7711        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7712        // client identity accordingly before proceeding.
7713        Identity tlsIdentity = sCallerIdentity.get();
7714        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7715            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7716                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7717            uid = tlsIdentity.uid;
7718            pid = tlsIdentity.pid;
7719        }
7720
7721        return checkComponentPermission(permission, pid, uid, -1, true);
7722    }
7723
7724    /**
7725     * Binder IPC calls go through the public entry point.
7726     * This can be called with or without the global lock held.
7727     */
7728    int checkCallingPermission(String permission) {
7729        return checkPermission(permission,
7730                Binder.getCallingPid(),
7731                UserHandle.getAppId(Binder.getCallingUid()));
7732    }
7733
7734    /**
7735     * This can be called with or without the global lock held.
7736     */
7737    void enforceCallingPermission(String permission, String func) {
7738        if (checkCallingPermission(permission)
7739                == PackageManager.PERMISSION_GRANTED) {
7740            return;
7741        }
7742
7743        String msg = "Permission Denial: " + func + " from pid="
7744                + Binder.getCallingPid()
7745                + ", uid=" + Binder.getCallingUid()
7746                + " requires " + permission;
7747        Slog.w(TAG, msg);
7748        throw new SecurityException(msg);
7749    }
7750
7751    /**
7752     * Determine if UID is holding permissions required to access {@link Uri} in
7753     * the given {@link ProviderInfo}. Final permission checking is always done
7754     * in {@link ContentProvider}.
7755     */
7756    private final boolean checkHoldingPermissionsLocked(
7757            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7758        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7759                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7760        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7761            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7762                    != PERMISSION_GRANTED) {
7763                return false;
7764            }
7765        }
7766        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7767    }
7768
7769    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7770            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7771        if (pi.applicationInfo.uid == uid) {
7772            return true;
7773        } else if (!pi.exported) {
7774            return false;
7775        }
7776
7777        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7778        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7779        try {
7780            // check if target holds top-level <provider> permissions
7781            if (!readMet && pi.readPermission != null && considerUidPermissions
7782                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7783                readMet = true;
7784            }
7785            if (!writeMet && pi.writePermission != null && considerUidPermissions
7786                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7787                writeMet = true;
7788            }
7789
7790            // track if unprotected read/write is allowed; any denied
7791            // <path-permission> below removes this ability
7792            boolean allowDefaultRead = pi.readPermission == null;
7793            boolean allowDefaultWrite = pi.writePermission == null;
7794
7795            // check if target holds any <path-permission> that match uri
7796            final PathPermission[] pps = pi.pathPermissions;
7797            if (pps != null) {
7798                final String path = grantUri.uri.getPath();
7799                int i = pps.length;
7800                while (i > 0 && (!readMet || !writeMet)) {
7801                    i--;
7802                    PathPermission pp = pps[i];
7803                    if (pp.match(path)) {
7804                        if (!readMet) {
7805                            final String pprperm = pp.getReadPermission();
7806                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7807                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7808                                    + ": match=" + pp.match(path)
7809                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7810                            if (pprperm != null) {
7811                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7812                                        == PERMISSION_GRANTED) {
7813                                    readMet = true;
7814                                } else {
7815                                    allowDefaultRead = false;
7816                                }
7817                            }
7818                        }
7819                        if (!writeMet) {
7820                            final String ppwperm = pp.getWritePermission();
7821                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7822                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7823                                    + ": match=" + pp.match(path)
7824                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7825                            if (ppwperm != null) {
7826                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7827                                        == PERMISSION_GRANTED) {
7828                                    writeMet = true;
7829                                } else {
7830                                    allowDefaultWrite = false;
7831                                }
7832                            }
7833                        }
7834                    }
7835                }
7836            }
7837
7838            // grant unprotected <provider> read/write, if not blocked by
7839            // <path-permission> above
7840            if (allowDefaultRead) readMet = true;
7841            if (allowDefaultWrite) writeMet = true;
7842
7843        } catch (RemoteException e) {
7844            return false;
7845        }
7846
7847        return readMet && writeMet;
7848    }
7849
7850    public int getAppStartMode(int uid, String packageName) {
7851        synchronized (this) {
7852            return checkAllowBackgroundLocked(uid, packageName, -1, false);
7853        }
7854    }
7855
7856    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7857            boolean alwaysRestrict) {
7858        UidRecord uidRec = mActiveUids.get(uid);
7859        if (uidRec == null || alwaysRestrict || uidRec.idle) {
7860            boolean ephemeral;
7861            if (uidRec == null) {
7862                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
7863                        UserHandle.getUserId(uid), packageName);
7864            } else {
7865                ephemeral = uidRec.ephemeral;
7866            }
7867
7868            if (ephemeral) {
7869                // We are hard-core about ephemeral apps not running in the background.
7870                return ActivityManager.APP_START_MODE_DISABLED;
7871            } else {
7872                if (callingPid >= 0) {
7873                    ProcessRecord proc;
7874                    synchronized (mPidsSelfLocked) {
7875                        proc = mPidsSelfLocked.get(callingPid);
7876                    }
7877                    if (proc != null && proc.curProcState
7878                            < ActivityManager.PROCESS_STATE_RECEIVER) {
7879                        // Whoever is instigating this is in the foreground, so we will allow it
7880                        // to go through.
7881                        return ActivityManager.APP_START_MODE_NORMAL;
7882                    }
7883                }
7884                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7885                        packageName) != AppOpsManager.MODE_ALLOWED) {
7886                    return ActivityManager.APP_START_MODE_DELAYED;
7887                }
7888            }
7889        }
7890        return ActivityManager.APP_START_MODE_NORMAL;
7891    }
7892
7893    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7894        ProviderInfo pi = null;
7895        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7896        if (cpr != null) {
7897            pi = cpr.info;
7898        } else {
7899            try {
7900                pi = AppGlobals.getPackageManager().resolveContentProvider(
7901                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7902                        userHandle);
7903            } catch (RemoteException ex) {
7904            }
7905        }
7906        return pi;
7907    }
7908
7909    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7910        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7911        if (targetUris != null) {
7912            return targetUris.get(grantUri);
7913        }
7914        return null;
7915    }
7916
7917    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7918            String targetPkg, int targetUid, GrantUri grantUri) {
7919        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7920        if (targetUris == null) {
7921            targetUris = Maps.newArrayMap();
7922            mGrantedUriPermissions.put(targetUid, targetUris);
7923        }
7924
7925        UriPermission perm = targetUris.get(grantUri);
7926        if (perm == null) {
7927            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7928            targetUris.put(grantUri, perm);
7929        }
7930
7931        return perm;
7932    }
7933
7934    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7935            final int modeFlags) {
7936        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7937        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7938                : UriPermission.STRENGTH_OWNED;
7939
7940        // Root gets to do everything.
7941        if (uid == 0) {
7942            return true;
7943        }
7944
7945        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7946        if (perms == null) return false;
7947
7948        // First look for exact match
7949        final UriPermission exactPerm = perms.get(grantUri);
7950        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7951            return true;
7952        }
7953
7954        // No exact match, look for prefixes
7955        final int N = perms.size();
7956        for (int i = 0; i < N; i++) {
7957            final UriPermission perm = perms.valueAt(i);
7958            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7959                    && perm.getStrength(modeFlags) >= minStrength) {
7960                return true;
7961            }
7962        }
7963
7964        return false;
7965    }
7966
7967    /**
7968     * @param uri This uri must NOT contain an embedded userId.
7969     * @param userId The userId in which the uri is to be resolved.
7970     */
7971    @Override
7972    public int checkUriPermission(Uri uri, int pid, int uid,
7973            final int modeFlags, int userId, IBinder callerToken) {
7974        enforceNotIsolatedCaller("checkUriPermission");
7975
7976        // Another redirected-binder-call permissions check as in
7977        // {@link checkPermissionWithToken}.
7978        Identity tlsIdentity = sCallerIdentity.get();
7979        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7980            uid = tlsIdentity.uid;
7981            pid = tlsIdentity.pid;
7982        }
7983
7984        // Our own process gets to do everything.
7985        if (pid == MY_PID) {
7986            return PackageManager.PERMISSION_GRANTED;
7987        }
7988        synchronized (this) {
7989            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7990                    ? PackageManager.PERMISSION_GRANTED
7991                    : PackageManager.PERMISSION_DENIED;
7992        }
7993    }
7994
7995    /**
7996     * Check if the targetPkg can be granted permission to access uri by
7997     * the callingUid using the given modeFlags.  Throws a security exception
7998     * if callingUid is not allowed to do this.  Returns the uid of the target
7999     * if the URI permission grant should be performed; returns -1 if it is not
8000     * needed (for example targetPkg already has permission to access the URI).
8001     * If you already know the uid of the target, you can supply it in
8002     * lastTargetUid else set that to -1.
8003     */
8004    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8005            final int modeFlags, int lastTargetUid) {
8006        if (!Intent.isAccessUriMode(modeFlags)) {
8007            return -1;
8008        }
8009
8010        if (targetPkg != null) {
8011            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8012                    "Checking grant " + targetPkg + " permission to " + grantUri);
8013        }
8014
8015        final IPackageManager pm = AppGlobals.getPackageManager();
8016
8017        // If this is not a content: uri, we can't do anything with it.
8018        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8019            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8020                    "Can't grant URI permission for non-content URI: " + grantUri);
8021            return -1;
8022        }
8023
8024        final String authority = grantUri.uri.getAuthority();
8025        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8026                MATCH_DEBUG_TRIAGED_MISSING);
8027        if (pi == null) {
8028            Slog.w(TAG, "No content provider found for permission check: " +
8029                    grantUri.uri.toSafeString());
8030            return -1;
8031        }
8032
8033        int targetUid = lastTargetUid;
8034        if (targetUid < 0 && targetPkg != null) {
8035            try {
8036                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8037                        UserHandle.getUserId(callingUid));
8038                if (targetUid < 0) {
8039                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8040                            "Can't grant URI permission no uid for: " + targetPkg);
8041                    return -1;
8042                }
8043            } catch (RemoteException ex) {
8044                return -1;
8045            }
8046        }
8047
8048        if (targetUid >= 0) {
8049            // First...  does the target actually need this permission?
8050            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8051                // No need to grant the target this permission.
8052                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8053                        "Target " + targetPkg + " already has full permission to " + grantUri);
8054                return -1;
8055            }
8056        } else {
8057            // First...  there is no target package, so can anyone access it?
8058            boolean allowed = pi.exported;
8059            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8060                if (pi.readPermission != null) {
8061                    allowed = false;
8062                }
8063            }
8064            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8065                if (pi.writePermission != null) {
8066                    allowed = false;
8067                }
8068            }
8069            if (allowed) {
8070                return -1;
8071            }
8072        }
8073
8074        /* There is a special cross user grant if:
8075         * - The target is on another user.
8076         * - Apps on the current user can access the uri without any uid permissions.
8077         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8078         * grant uri permissions.
8079         */
8080        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8081                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8082                modeFlags, false /*without considering the uid permissions*/);
8083
8084        // Second...  is the provider allowing granting of URI permissions?
8085        if (!specialCrossUserGrant) {
8086            if (!pi.grantUriPermissions) {
8087                throw new SecurityException("Provider " + pi.packageName
8088                        + "/" + pi.name
8089                        + " does not allow granting of Uri permissions (uri "
8090                        + grantUri + ")");
8091            }
8092            if (pi.uriPermissionPatterns != null) {
8093                final int N = pi.uriPermissionPatterns.length;
8094                boolean allowed = false;
8095                for (int i=0; i<N; i++) {
8096                    if (pi.uriPermissionPatterns[i] != null
8097                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8098                        allowed = true;
8099                        break;
8100                    }
8101                }
8102                if (!allowed) {
8103                    throw new SecurityException("Provider " + pi.packageName
8104                            + "/" + pi.name
8105                            + " does not allow granting of permission to path of Uri "
8106                            + grantUri);
8107                }
8108            }
8109        }
8110
8111        // Third...  does the caller itself have permission to access
8112        // this uri?
8113        final int callingAppId = UserHandle.getAppId(callingUid);
8114        if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8115            Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8116                    + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8117            return -1;
8118        } else {
8119            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8120                // Require they hold a strong enough Uri permission
8121                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8122                    throw new SecurityException("Uid " + callingUid
8123                            + " does not have permission to uri " + grantUri);
8124                }
8125            }
8126        }
8127        return targetUid;
8128    }
8129
8130    /**
8131     * @param uri This uri must NOT contain an embedded userId.
8132     * @param userId The userId in which the uri is to be resolved.
8133     */
8134    @Override
8135    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8136            final int modeFlags, int userId) {
8137        enforceNotIsolatedCaller("checkGrantUriPermission");
8138        synchronized(this) {
8139            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8140                    new GrantUri(userId, uri, false), modeFlags, -1);
8141        }
8142    }
8143
8144    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8145            final int modeFlags, UriPermissionOwner owner) {
8146        if (!Intent.isAccessUriMode(modeFlags)) {
8147            return;
8148        }
8149
8150        // So here we are: the caller has the assumed permission
8151        // to the uri, and the target doesn't.  Let's now give this to
8152        // the target.
8153
8154        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8155                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8156
8157        final String authority = grantUri.uri.getAuthority();
8158        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8159                MATCH_DEBUG_TRIAGED_MISSING);
8160        if (pi == null) {
8161            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8162            return;
8163        }
8164
8165        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8166            grantUri.prefix = true;
8167        }
8168        final UriPermission perm = findOrCreateUriPermissionLocked(
8169                pi.packageName, targetPkg, targetUid, grantUri);
8170        perm.grantModes(modeFlags, owner);
8171    }
8172
8173    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8174            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8175        if (targetPkg == null) {
8176            throw new NullPointerException("targetPkg");
8177        }
8178        int targetUid;
8179        final IPackageManager pm = AppGlobals.getPackageManager();
8180        try {
8181            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8182        } catch (RemoteException ex) {
8183            return;
8184        }
8185
8186        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8187                targetUid);
8188        if (targetUid < 0) {
8189            return;
8190        }
8191
8192        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8193                owner);
8194    }
8195
8196    static class NeededUriGrants extends ArrayList<GrantUri> {
8197        final String targetPkg;
8198        final int targetUid;
8199        final int flags;
8200
8201        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8202            this.targetPkg = targetPkg;
8203            this.targetUid = targetUid;
8204            this.flags = flags;
8205        }
8206    }
8207
8208    /**
8209     * Like checkGrantUriPermissionLocked, but takes an Intent.
8210     */
8211    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8212            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8213        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8214                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8215                + " clip=" + (intent != null ? intent.getClipData() : null)
8216                + " from " + intent + "; flags=0x"
8217                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8218
8219        if (targetPkg == null) {
8220            throw new NullPointerException("targetPkg");
8221        }
8222
8223        if (intent == null) {
8224            return null;
8225        }
8226        Uri data = intent.getData();
8227        ClipData clip = intent.getClipData();
8228        if (data == null && clip == null) {
8229            return null;
8230        }
8231        // Default userId for uris in the intent (if they don't specify it themselves)
8232        int contentUserHint = intent.getContentUserHint();
8233        if (contentUserHint == UserHandle.USER_CURRENT) {
8234            contentUserHint = UserHandle.getUserId(callingUid);
8235        }
8236        final IPackageManager pm = AppGlobals.getPackageManager();
8237        int targetUid;
8238        if (needed != null) {
8239            targetUid = needed.targetUid;
8240        } else {
8241            try {
8242                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8243                        targetUserId);
8244            } catch (RemoteException ex) {
8245                return null;
8246            }
8247            if (targetUid < 0) {
8248                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8249                        "Can't grant URI permission no uid for: " + targetPkg
8250                        + " on user " + targetUserId);
8251                return null;
8252            }
8253        }
8254        if (data != null) {
8255            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8256            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8257                    targetUid);
8258            if (targetUid > 0) {
8259                if (needed == null) {
8260                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8261                }
8262                needed.add(grantUri);
8263            }
8264        }
8265        if (clip != null) {
8266            for (int i=0; i<clip.getItemCount(); i++) {
8267                Uri uri = clip.getItemAt(i).getUri();
8268                if (uri != null) {
8269                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8270                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8271                            targetUid);
8272                    if (targetUid > 0) {
8273                        if (needed == null) {
8274                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8275                        }
8276                        needed.add(grantUri);
8277                    }
8278                } else {
8279                    Intent clipIntent = clip.getItemAt(i).getIntent();
8280                    if (clipIntent != null) {
8281                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8282                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8283                        if (newNeeded != null) {
8284                            needed = newNeeded;
8285                        }
8286                    }
8287                }
8288            }
8289        }
8290
8291        return needed;
8292    }
8293
8294    /**
8295     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8296     */
8297    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8298            UriPermissionOwner owner) {
8299        if (needed != null) {
8300            for (int i=0; i<needed.size(); i++) {
8301                GrantUri grantUri = needed.get(i);
8302                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8303                        grantUri, needed.flags, owner);
8304            }
8305        }
8306    }
8307
8308    void grantUriPermissionFromIntentLocked(int callingUid,
8309            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8310        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8311                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8312        if (needed == null) {
8313            return;
8314        }
8315
8316        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8317    }
8318
8319    /**
8320     * @param uri This uri must NOT contain an embedded userId.
8321     * @param userId The userId in which the uri is to be resolved.
8322     */
8323    @Override
8324    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8325            final int modeFlags, int userId) {
8326        enforceNotIsolatedCaller("grantUriPermission");
8327        GrantUri grantUri = new GrantUri(userId, uri, false);
8328        synchronized(this) {
8329            final ProcessRecord r = getRecordForAppLocked(caller);
8330            if (r == null) {
8331                throw new SecurityException("Unable to find app for caller "
8332                        + caller
8333                        + " when granting permission to uri " + grantUri);
8334            }
8335            if (targetPkg == null) {
8336                throw new IllegalArgumentException("null target");
8337            }
8338            if (grantUri == null) {
8339                throw new IllegalArgumentException("null uri");
8340            }
8341
8342            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8343                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8344                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8345                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8346
8347            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8348                    UserHandle.getUserId(r.uid));
8349        }
8350    }
8351
8352    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8353        if (perm.modeFlags == 0) {
8354            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8355                    perm.targetUid);
8356            if (perms != null) {
8357                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8358                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8359
8360                perms.remove(perm.uri);
8361                if (perms.isEmpty()) {
8362                    mGrantedUriPermissions.remove(perm.targetUid);
8363                }
8364            }
8365        }
8366    }
8367
8368    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8369        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8370                "Revoking all granted permissions to " + grantUri);
8371
8372        final IPackageManager pm = AppGlobals.getPackageManager();
8373        final String authority = grantUri.uri.getAuthority();
8374        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8375                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8376        if (pi == null) {
8377            Slog.w(TAG, "No content provider found for permission revoke: "
8378                    + grantUri.toSafeString());
8379            return;
8380        }
8381
8382        // Does the caller have this permission on the URI?
8383        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8384            // If they don't have direct access to the URI, then revoke any
8385            // ownerless URI permissions that have been granted to them.
8386            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8387            if (perms != null) {
8388                boolean persistChanged = false;
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 non-owned " + perm.targetUid
8395                                + " permission to " + perm.uri);
8396                        persistChanged |= perm.revokeModes(
8397                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8398                        if (perm.modeFlags == 0) {
8399                            it.remove();
8400                        }
8401                    }
8402                }
8403                if (perms.isEmpty()) {
8404                    mGrantedUriPermissions.remove(callingUid);
8405                }
8406                if (persistChanged) {
8407                    schedulePersistUriGrants();
8408                }
8409            }
8410            return;
8411        }
8412
8413        boolean persistChanged = false;
8414
8415        // Go through all of the permissions and remove any that match.
8416        int N = mGrantedUriPermissions.size();
8417        for (int i = 0; i < N; i++) {
8418            final int targetUid = mGrantedUriPermissions.keyAt(i);
8419            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8420
8421            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8422                final UriPermission perm = it.next();
8423                if (perm.uri.sourceUserId == grantUri.sourceUserId
8424                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8425                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8426                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8427                    persistChanged |= perm.revokeModes(
8428                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8429                    if (perm.modeFlags == 0) {
8430                        it.remove();
8431                    }
8432                }
8433            }
8434
8435            if (perms.isEmpty()) {
8436                mGrantedUriPermissions.remove(targetUid);
8437                N--;
8438                i--;
8439            }
8440        }
8441
8442        if (persistChanged) {
8443            schedulePersistUriGrants();
8444        }
8445    }
8446
8447    /**
8448     * @param uri This uri must NOT contain an embedded userId.
8449     * @param userId The userId in which the uri is to be resolved.
8450     */
8451    @Override
8452    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8453            int userId) {
8454        enforceNotIsolatedCaller("revokeUriPermission");
8455        synchronized(this) {
8456            final ProcessRecord r = getRecordForAppLocked(caller);
8457            if (r == null) {
8458                throw new SecurityException("Unable to find app for caller "
8459                        + caller
8460                        + " when revoking permission to uri " + uri);
8461            }
8462            if (uri == null) {
8463                Slog.w(TAG, "revokeUriPermission: null uri");
8464                return;
8465            }
8466
8467            if (!Intent.isAccessUriMode(modeFlags)) {
8468                return;
8469            }
8470
8471            final String authority = uri.getAuthority();
8472            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8473                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8474            if (pi == null) {
8475                Slog.w(TAG, "No content provider found for permission revoke: "
8476                        + uri.toSafeString());
8477                return;
8478            }
8479
8480            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8481        }
8482    }
8483
8484    /**
8485     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8486     * given package.
8487     *
8488     * @param packageName Package name to match, or {@code null} to apply to all
8489     *            packages.
8490     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8491     *            to all users.
8492     * @param persistable If persistable grants should be removed.
8493     */
8494    private void removeUriPermissionsForPackageLocked(
8495            String packageName, int userHandle, boolean persistable) {
8496        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8497            throw new IllegalArgumentException("Must narrow by either package or user");
8498        }
8499
8500        boolean persistChanged = false;
8501
8502        int N = mGrantedUriPermissions.size();
8503        for (int i = 0; i < N; i++) {
8504            final int targetUid = mGrantedUriPermissions.keyAt(i);
8505            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8506
8507            // Only inspect grants matching user
8508            if (userHandle == UserHandle.USER_ALL
8509                    || userHandle == UserHandle.getUserId(targetUid)) {
8510                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8511                    final UriPermission perm = it.next();
8512
8513                    // Only inspect grants matching package
8514                    if (packageName == null || perm.sourcePkg.equals(packageName)
8515                            || perm.targetPkg.equals(packageName)) {
8516                        persistChanged |= perm.revokeModes(persistable
8517                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8518
8519                        // Only remove when no modes remain; any persisted grants
8520                        // will keep this alive.
8521                        if (perm.modeFlags == 0) {
8522                            it.remove();
8523                        }
8524                    }
8525                }
8526
8527                if (perms.isEmpty()) {
8528                    mGrantedUriPermissions.remove(targetUid);
8529                    N--;
8530                    i--;
8531                }
8532            }
8533        }
8534
8535        if (persistChanged) {
8536            schedulePersistUriGrants();
8537        }
8538    }
8539
8540    @Override
8541    public IBinder newUriPermissionOwner(String name) {
8542        enforceNotIsolatedCaller("newUriPermissionOwner");
8543        synchronized(this) {
8544            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8545            return owner.getExternalTokenLocked();
8546        }
8547    }
8548
8549    @Override
8550    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8551        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8552        synchronized(this) {
8553            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8554            if (r == null) {
8555                throw new IllegalArgumentException("Activity does not exist; token="
8556                        + activityToken);
8557            }
8558            return r.getUriPermissionsLocked().getExternalTokenLocked();
8559        }
8560    }
8561    /**
8562     * @param uri This uri must NOT contain an embedded userId.
8563     * @param sourceUserId The userId in which the uri is to be resolved.
8564     * @param targetUserId The userId of the app that receives the grant.
8565     */
8566    @Override
8567    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8568            final int modeFlags, int sourceUserId, int targetUserId) {
8569        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8570                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8571                "grantUriPermissionFromOwner", null);
8572        synchronized(this) {
8573            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8574            if (owner == null) {
8575                throw new IllegalArgumentException("Unknown owner: " + token);
8576            }
8577            if (fromUid != Binder.getCallingUid()) {
8578                if (Binder.getCallingUid() != Process.myUid()) {
8579                    // Only system code can grant URI permissions on behalf
8580                    // of other users.
8581                    throw new SecurityException("nice try");
8582                }
8583            }
8584            if (targetPkg == null) {
8585                throw new IllegalArgumentException("null target");
8586            }
8587            if (uri == null) {
8588                throw new IllegalArgumentException("null uri");
8589            }
8590
8591            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8592                    modeFlags, owner, targetUserId);
8593        }
8594    }
8595
8596    /**
8597     * @param uri This uri must NOT contain an embedded userId.
8598     * @param userId The userId in which the uri is to be resolved.
8599     */
8600    @Override
8601    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8602        synchronized(this) {
8603            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8604            if (owner == null) {
8605                throw new IllegalArgumentException("Unknown owner: " + token);
8606            }
8607
8608            if (uri == null) {
8609                owner.removeUriPermissionsLocked(mode);
8610            } else {
8611                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8612                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8613            }
8614        }
8615    }
8616
8617    private void schedulePersistUriGrants() {
8618        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8619            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8620                    10 * DateUtils.SECOND_IN_MILLIS);
8621        }
8622    }
8623
8624    private void writeGrantedUriPermissions() {
8625        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8626
8627        // Snapshot permissions so we can persist without lock
8628        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8629        synchronized (this) {
8630            final int size = mGrantedUriPermissions.size();
8631            for (int i = 0; i < size; i++) {
8632                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8633                for (UriPermission perm : perms.values()) {
8634                    if (perm.persistedModeFlags != 0) {
8635                        persist.add(perm.snapshot());
8636                    }
8637                }
8638            }
8639        }
8640
8641        FileOutputStream fos = null;
8642        try {
8643            fos = mGrantFile.startWrite();
8644
8645            XmlSerializer out = new FastXmlSerializer();
8646            out.setOutput(fos, StandardCharsets.UTF_8.name());
8647            out.startDocument(null, true);
8648            out.startTag(null, TAG_URI_GRANTS);
8649            for (UriPermission.Snapshot perm : persist) {
8650                out.startTag(null, TAG_URI_GRANT);
8651                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8652                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8653                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8654                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8655                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8656                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8657                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8658                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8659                out.endTag(null, TAG_URI_GRANT);
8660            }
8661            out.endTag(null, TAG_URI_GRANTS);
8662            out.endDocument();
8663
8664            mGrantFile.finishWrite(fos);
8665        } catch (IOException e) {
8666            if (fos != null) {
8667                mGrantFile.failWrite(fos);
8668            }
8669        }
8670    }
8671
8672    private void readGrantedUriPermissionsLocked() {
8673        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8674
8675        final long now = System.currentTimeMillis();
8676
8677        FileInputStream fis = null;
8678        try {
8679            fis = mGrantFile.openRead();
8680            final XmlPullParser in = Xml.newPullParser();
8681            in.setInput(fis, StandardCharsets.UTF_8.name());
8682
8683            int type;
8684            while ((type = in.next()) != END_DOCUMENT) {
8685                final String tag = in.getName();
8686                if (type == START_TAG) {
8687                    if (TAG_URI_GRANT.equals(tag)) {
8688                        final int sourceUserId;
8689                        final int targetUserId;
8690                        final int userHandle = readIntAttribute(in,
8691                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8692                        if (userHandle != UserHandle.USER_NULL) {
8693                            // For backwards compatibility.
8694                            sourceUserId = userHandle;
8695                            targetUserId = userHandle;
8696                        } else {
8697                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8698                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8699                        }
8700                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8701                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8702                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8703                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8704                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8705                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8706
8707                        // Sanity check that provider still belongs to source package
8708                        // Both direct boot aware and unaware packages are fine as we
8709                        // will do filtering at query time to avoid multiple parsing.
8710                        final ProviderInfo pi = getProviderInfoLocked(
8711                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8712                                        | MATCH_DIRECT_BOOT_UNAWARE);
8713                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8714                            int targetUid = -1;
8715                            try {
8716                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8717                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8718                            } catch (RemoteException e) {
8719                            }
8720                            if (targetUid != -1) {
8721                                final UriPermission perm = findOrCreateUriPermissionLocked(
8722                                        sourcePkg, targetPkg, targetUid,
8723                                        new GrantUri(sourceUserId, uri, prefix));
8724                                perm.initPersistedModes(modeFlags, createdTime);
8725                            }
8726                        } else {
8727                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8728                                    + " but instead found " + pi);
8729                        }
8730                    }
8731                }
8732            }
8733        } catch (FileNotFoundException e) {
8734            // Missing grants is okay
8735        } catch (IOException e) {
8736            Slog.wtf(TAG, "Failed reading Uri grants", e);
8737        } catch (XmlPullParserException e) {
8738            Slog.wtf(TAG, "Failed reading Uri grants", e);
8739        } finally {
8740            IoUtils.closeQuietly(fis);
8741        }
8742    }
8743
8744    /**
8745     * @param uri This uri must NOT contain an embedded userId.
8746     * @param userId The userId in which the uri is to be resolved.
8747     */
8748    @Override
8749    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8750        enforceNotIsolatedCaller("takePersistableUriPermission");
8751
8752        Preconditions.checkFlagsArgument(modeFlags,
8753                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8754
8755        synchronized (this) {
8756            final int callingUid = Binder.getCallingUid();
8757            boolean persistChanged = false;
8758            GrantUri grantUri = new GrantUri(userId, uri, false);
8759
8760            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8761                    new GrantUri(userId, uri, false));
8762            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8763                    new GrantUri(userId, uri, true));
8764
8765            final boolean exactValid = (exactPerm != null)
8766                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8767            final boolean prefixValid = (prefixPerm != null)
8768                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8769
8770            if (!(exactValid || prefixValid)) {
8771                throw new SecurityException("No persistable permission grants found for UID "
8772                        + callingUid + " and Uri " + grantUri.toSafeString());
8773            }
8774
8775            if (exactValid) {
8776                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8777            }
8778            if (prefixValid) {
8779                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8780            }
8781
8782            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8783
8784            if (persistChanged) {
8785                schedulePersistUriGrants();
8786            }
8787        }
8788    }
8789
8790    /**
8791     * @param uri This uri must NOT contain an embedded userId.
8792     * @param userId The userId in which the uri is to be resolved.
8793     */
8794    @Override
8795    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8796        enforceNotIsolatedCaller("releasePersistableUriPermission");
8797
8798        Preconditions.checkFlagsArgument(modeFlags,
8799                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8800
8801        synchronized (this) {
8802            final int callingUid = Binder.getCallingUid();
8803            boolean persistChanged = false;
8804
8805            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8806                    new GrantUri(userId, uri, false));
8807            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8808                    new GrantUri(userId, uri, true));
8809            if (exactPerm == null && prefixPerm == null) {
8810                throw new SecurityException("No permission grants found for UID " + callingUid
8811                        + " and Uri " + uri.toSafeString());
8812            }
8813
8814            if (exactPerm != null) {
8815                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8816                removeUriPermissionIfNeededLocked(exactPerm);
8817            }
8818            if (prefixPerm != null) {
8819                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8820                removeUriPermissionIfNeededLocked(prefixPerm);
8821            }
8822
8823            if (persistChanged) {
8824                schedulePersistUriGrants();
8825            }
8826        }
8827    }
8828
8829    /**
8830     * Prune any older {@link UriPermission} for the given UID until outstanding
8831     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8832     *
8833     * @return if any mutations occured that require persisting.
8834     */
8835    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8836        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8837        if (perms == null) return false;
8838        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8839
8840        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8841        for (UriPermission perm : perms.values()) {
8842            if (perm.persistedModeFlags != 0) {
8843                persisted.add(perm);
8844            }
8845        }
8846
8847        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8848        if (trimCount <= 0) return false;
8849
8850        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8851        for (int i = 0; i < trimCount; i++) {
8852            final UriPermission perm = persisted.get(i);
8853
8854            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8855                    "Trimming grant created at " + perm.persistedCreateTime);
8856
8857            perm.releasePersistableModes(~0);
8858            removeUriPermissionIfNeededLocked(perm);
8859        }
8860
8861        return true;
8862    }
8863
8864    @Override
8865    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8866            String packageName, boolean incoming) {
8867        enforceNotIsolatedCaller("getPersistedUriPermissions");
8868        Preconditions.checkNotNull(packageName, "packageName");
8869
8870        final int callingUid = Binder.getCallingUid();
8871        final int callingUserId = UserHandle.getUserId(callingUid);
8872        final IPackageManager pm = AppGlobals.getPackageManager();
8873        try {
8874            final int packageUid = pm.getPackageUid(packageName,
8875                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8876            if (packageUid != callingUid) {
8877                throw new SecurityException(
8878                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8879            }
8880        } catch (RemoteException e) {
8881            throw new SecurityException("Failed to verify package name ownership");
8882        }
8883
8884        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8885        synchronized (this) {
8886            if (incoming) {
8887                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8888                        callingUid);
8889                if (perms == null) {
8890                    Slog.w(TAG, "No permission grants found for " + packageName);
8891                } else {
8892                    for (UriPermission perm : perms.values()) {
8893                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8894                            result.add(perm.buildPersistedPublicApiObject());
8895                        }
8896                    }
8897                }
8898            } else {
8899                final int size = mGrantedUriPermissions.size();
8900                for (int i = 0; i < size; i++) {
8901                    final ArrayMap<GrantUri, UriPermission> perms =
8902                            mGrantedUriPermissions.valueAt(i);
8903                    for (UriPermission perm : perms.values()) {
8904                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8905                            result.add(perm.buildPersistedPublicApiObject());
8906                        }
8907                    }
8908                }
8909            }
8910        }
8911        return new ParceledListSlice<android.content.UriPermission>(result);
8912    }
8913
8914    @Override
8915    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8916            String packageName, int userId) {
8917        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8918                "getGrantedUriPermissions");
8919
8920        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8921        synchronized (this) {
8922            final int size = mGrantedUriPermissions.size();
8923            for (int i = 0; i < size; i++) {
8924                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8925                for (UriPermission perm : perms.values()) {
8926                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8927                            && perm.persistedModeFlags != 0) {
8928                        result.add(perm.buildPersistedPublicApiObject());
8929                    }
8930                }
8931            }
8932        }
8933        return new ParceledListSlice<android.content.UriPermission>(result);
8934    }
8935
8936    @Override
8937    public void clearGrantedUriPermissions(String packageName, int userId) {
8938        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8939                "clearGrantedUriPermissions");
8940        removeUriPermissionsForPackageLocked(packageName, userId, true);
8941    }
8942
8943    @Override
8944    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8945        synchronized (this) {
8946            ProcessRecord app =
8947                who != null ? getRecordForAppLocked(who) : null;
8948            if (app == null) return;
8949
8950            Message msg = Message.obtain();
8951            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8952            msg.obj = app;
8953            msg.arg1 = waiting ? 1 : 0;
8954            mUiHandler.sendMessage(msg);
8955        }
8956    }
8957
8958    @Override
8959    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8960        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8961        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8962        outInfo.availMem = Process.getFreeMemory();
8963        outInfo.totalMem = Process.getTotalMemory();
8964        outInfo.threshold = homeAppMem;
8965        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8966        outInfo.hiddenAppThreshold = cachedAppMem;
8967        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8968                ProcessList.SERVICE_ADJ);
8969        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8970                ProcessList.VISIBLE_APP_ADJ);
8971        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8972                ProcessList.FOREGROUND_APP_ADJ);
8973    }
8974
8975    // =========================================================
8976    // TASK MANAGEMENT
8977    // =========================================================
8978
8979    @Override
8980    public List<IBinder> getAppTasks(String callingPackage) {
8981        int callingUid = Binder.getCallingUid();
8982        long ident = Binder.clearCallingIdentity();
8983
8984        synchronized(this) {
8985            ArrayList<IBinder> list = new ArrayList<IBinder>();
8986            try {
8987                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8988
8989                final int N = mRecentTasks.size();
8990                for (int i = 0; i < N; i++) {
8991                    TaskRecord tr = mRecentTasks.get(i);
8992                    // Skip tasks that do not match the caller.  We don't need to verify
8993                    // callingPackage, because we are also limiting to callingUid and know
8994                    // that will limit to the correct security sandbox.
8995                    if (tr.effectiveUid != callingUid) {
8996                        continue;
8997                    }
8998                    Intent intent = tr.getBaseIntent();
8999                    if (intent == null ||
9000                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9001                        continue;
9002                    }
9003                    ActivityManager.RecentTaskInfo taskInfo =
9004                            createRecentTaskInfoFromTaskRecord(tr);
9005                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9006                    list.add(taskImpl.asBinder());
9007                }
9008            } finally {
9009                Binder.restoreCallingIdentity(ident);
9010            }
9011            return list;
9012        }
9013    }
9014
9015    @Override
9016    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9017        final int callingUid = Binder.getCallingUid();
9018        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9019
9020        synchronized(this) {
9021            if (DEBUG_ALL) Slog.v(
9022                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9023
9024            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9025                    callingUid);
9026
9027            // TODO: Improve with MRU list from all ActivityStacks.
9028            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9029        }
9030
9031        return list;
9032    }
9033
9034    /**
9035     * Creates a new RecentTaskInfo from a TaskRecord.
9036     */
9037    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9038        // Update the task description to reflect any changes in the task stack
9039        tr.updateTaskDescription();
9040
9041        // Compose the recent task info
9042        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9043        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9044        rti.persistentId = tr.taskId;
9045        rti.baseIntent = new Intent(tr.getBaseIntent());
9046        rti.origActivity = tr.origActivity;
9047        rti.realActivity = tr.realActivity;
9048        rti.description = tr.lastDescription;
9049        rti.stackId = tr.getStackId();
9050        rti.userId = tr.userId;
9051        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9052        rti.firstActiveTime = tr.firstActiveTime;
9053        rti.lastActiveTime = tr.lastActiveTime;
9054        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9055        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9056        rti.numActivities = 0;
9057        if (tr.mBounds != null) {
9058            rti.bounds = new Rect(tr.mBounds);
9059        }
9060        rti.isDockable = tr.canGoInDockedStack();
9061        rti.resizeMode = tr.mResizeMode;
9062
9063        ActivityRecord base = null;
9064        ActivityRecord top = null;
9065        ActivityRecord tmp;
9066
9067        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9068            tmp = tr.mActivities.get(i);
9069            if (tmp.finishing) {
9070                continue;
9071            }
9072            base = tmp;
9073            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9074                top = base;
9075            }
9076            rti.numActivities++;
9077        }
9078
9079        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9080        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9081
9082        return rti;
9083    }
9084
9085    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9086        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9087                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9088        if (!allowed) {
9089            if (checkPermission(android.Manifest.permission.GET_TASKS,
9090                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9091                // Temporary compatibility: some existing apps on the system image may
9092                // still be requesting the old permission and not switched to the new
9093                // one; if so, we'll still allow them full access.  This means we need
9094                // to see if they are holding the old permission and are a system app.
9095                try {
9096                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9097                        allowed = true;
9098                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9099                                + " is using old GET_TASKS but privileged; allowing");
9100                    }
9101                } catch (RemoteException e) {
9102                }
9103            }
9104        }
9105        if (!allowed) {
9106            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9107                    + " does not hold REAL_GET_TASKS; limiting output");
9108        }
9109        return allowed;
9110    }
9111
9112    @Override
9113    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9114            int userId) {
9115        final int callingUid = Binder.getCallingUid();
9116        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9117                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9118
9119        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9120        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9121        synchronized (this) {
9122            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9123                    callingUid);
9124            final boolean detailed = checkCallingPermission(
9125                    android.Manifest.permission.GET_DETAILED_TASKS)
9126                    == PackageManager.PERMISSION_GRANTED;
9127
9128            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9129                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9130                return ParceledListSlice.emptyList();
9131            }
9132            mRecentTasks.loadUserRecentsLocked(userId);
9133
9134            final int recentsCount = mRecentTasks.size();
9135            ArrayList<ActivityManager.RecentTaskInfo> res =
9136                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9137
9138            final Set<Integer> includedUsers;
9139            if (includeProfiles) {
9140                includedUsers = mUserController.getProfileIds(userId);
9141            } else {
9142                includedUsers = new HashSet<>();
9143            }
9144            includedUsers.add(Integer.valueOf(userId));
9145
9146            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9147                TaskRecord tr = mRecentTasks.get(i);
9148                // Only add calling user or related users recent tasks
9149                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9150                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9151                    continue;
9152                }
9153
9154                if (tr.realActivitySuspended) {
9155                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9156                    continue;
9157                }
9158
9159                // Return the entry if desired by the caller.  We always return
9160                // the first entry, because callers always expect this to be the
9161                // foreground app.  We may filter others if the caller has
9162                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9163                // we should exclude the entry.
9164
9165                if (i == 0
9166                        || withExcluded
9167                        || (tr.intent == null)
9168                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9169                                == 0)) {
9170                    if (!allowed) {
9171                        // If the caller doesn't have the GET_TASKS permission, then only
9172                        // allow them to see a small subset of tasks -- their own and home.
9173                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9174                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9175                            continue;
9176                        }
9177                    }
9178                    final ActivityStack stack = tr.getStack();
9179                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9180                        if (stack != null && stack.isHomeStack()) {
9181                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9182                                    "Skipping, home stack task: " + tr);
9183                            continue;
9184                        }
9185                    }
9186                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9187                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9188                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9189                                    "Skipping, top task in docked stack: " + tr);
9190                            continue;
9191                        }
9192                    }
9193                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9194                        if (stack != null && stack.isPinnedStack()) {
9195                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9196                                    "Skipping, pinned stack task: " + tr);
9197                            continue;
9198                        }
9199                    }
9200                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9201                        // Don't include auto remove tasks that are finished or finishing.
9202                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9203                                "Skipping, auto-remove without activity: " + tr);
9204                        continue;
9205                    }
9206                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9207                            && !tr.isAvailable) {
9208                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9209                                "Skipping, unavail real act: " + tr);
9210                        continue;
9211                    }
9212
9213                    if (!tr.mUserSetupComplete) {
9214                        // Don't include task launched while user is not done setting-up.
9215                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9216                                "Skipping, user setup not complete: " + tr);
9217                        continue;
9218                    }
9219
9220                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9221                    if (!detailed) {
9222                        rti.baseIntent.replaceExtras((Bundle)null);
9223                    }
9224
9225                    res.add(rti);
9226                    maxNum--;
9227                }
9228            }
9229            return new ParceledListSlice<>(res);
9230        }
9231    }
9232
9233    @Override
9234    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9235        synchronized (this) {
9236            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9237                    "getTaskThumbnail()");
9238            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9239                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9240            if (tr != null) {
9241                return tr.getTaskThumbnailLocked();
9242            }
9243        }
9244        return null;
9245    }
9246
9247    @Override
9248    public int addAppTask(IBinder activityToken, Intent intent,
9249            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9250        final int callingUid = Binder.getCallingUid();
9251        final long callingIdent = Binder.clearCallingIdentity();
9252
9253        try {
9254            synchronized (this) {
9255                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9256                if (r == null) {
9257                    throw new IllegalArgumentException("Activity does not exist; token="
9258                            + activityToken);
9259                }
9260                ComponentName comp = intent.getComponent();
9261                if (comp == null) {
9262                    throw new IllegalArgumentException("Intent " + intent
9263                            + " must specify explicit component");
9264                }
9265                if (thumbnail.getWidth() != mThumbnailWidth
9266                        || thumbnail.getHeight() != mThumbnailHeight) {
9267                    throw new IllegalArgumentException("Bad thumbnail size: got "
9268                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9269                            + mThumbnailWidth + "x" + mThumbnailHeight);
9270                }
9271                if (intent.getSelector() != null) {
9272                    intent.setSelector(null);
9273                }
9274                if (intent.getSourceBounds() != null) {
9275                    intent.setSourceBounds(null);
9276                }
9277                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9278                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9279                        // The caller has added this as an auto-remove task...  that makes no
9280                        // sense, so turn off auto-remove.
9281                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9282                    }
9283                }
9284                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9285                    mLastAddedTaskActivity = null;
9286                }
9287                ActivityInfo ainfo = mLastAddedTaskActivity;
9288                if (ainfo == null) {
9289                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9290                            comp, 0, UserHandle.getUserId(callingUid));
9291                    if (ainfo.applicationInfo.uid != callingUid) {
9292                        throw new SecurityException(
9293                                "Can't add task for another application: target uid="
9294                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9295                    }
9296                }
9297
9298                TaskRecord task = new TaskRecord(this,
9299                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9300                        ainfo, intent, description, new TaskThumbnailInfo());
9301
9302                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9303                if (trimIdx >= 0) {
9304                    // If this would have caused a trim, then we'll abort because that
9305                    // means it would be added at the end of the list but then just removed.
9306                    return INVALID_TASK_ID;
9307                }
9308
9309                final int N = mRecentTasks.size();
9310                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9311                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9312                    tr.removedFromRecents();
9313                }
9314
9315                task.inRecents = true;
9316                mRecentTasks.add(task);
9317                r.getStack().addTask(task, false, "addAppTask");
9318
9319                task.setLastThumbnailLocked(thumbnail);
9320                task.freeLastThumbnail();
9321                return task.taskId;
9322            }
9323        } finally {
9324            Binder.restoreCallingIdentity(callingIdent);
9325        }
9326    }
9327
9328    @Override
9329    public Point getAppTaskThumbnailSize() {
9330        synchronized (this) {
9331            return new Point(mThumbnailWidth,  mThumbnailHeight);
9332        }
9333    }
9334
9335    @Override
9336    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9337        synchronized (this) {
9338            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9339            if (r != null) {
9340                r.setTaskDescription(td);
9341                r.task.updateTaskDescription();
9342                mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td);
9343            }
9344        }
9345    }
9346
9347    @Override
9348    public void setTaskResizeable(int taskId, int resizeableMode) {
9349        synchronized (this) {
9350            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9351                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9352            if (task == null) {
9353                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9354                return;
9355            }
9356            if (task.mResizeMode != resizeableMode) {
9357                task.mResizeMode = resizeableMode;
9358                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9359                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9360                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9361            }
9362        }
9363    }
9364
9365    @Override
9366    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9367        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9368        long ident = Binder.clearCallingIdentity();
9369        try {
9370            synchronized (this) {
9371                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9372                if (task == null) {
9373                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9374                    return;
9375                }
9376                // Place the task in the right stack if it isn't there already based on
9377                // the requested bounds.
9378                // The stack transition logic is:
9379                // - a null bounds on a freeform task moves that task to fullscreen
9380                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9381                //   that task to freeform
9382                // - otherwise the task is not moved
9383                int stackId = task.getStackId();
9384                if (!StackId.isTaskResizeAllowed(stackId)) {
9385                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9386                }
9387                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9388                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9389                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9390                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9391                }
9392                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9393                if (stackId != task.getStackId()) {
9394                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9395                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9396                    preserveWindow = false;
9397                }
9398
9399                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9400                        false /* deferResume */);
9401            }
9402        } finally {
9403            Binder.restoreCallingIdentity(ident);
9404        }
9405    }
9406
9407    @Override
9408    public Rect getTaskBounds(int taskId) {
9409        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9410        long ident = Binder.clearCallingIdentity();
9411        Rect rect = new Rect();
9412        try {
9413            synchronized (this) {
9414                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9415                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9416                if (task == null) {
9417                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9418                    return rect;
9419                }
9420                if (task.getStack() != null) {
9421                    // Return the bounds from window manager since it will be adjusted for various
9422                    // things like the presense of a docked stack for tasks that aren't resizeable.
9423                    mWindowManager.getTaskBounds(task.taskId, rect);
9424                } else {
9425                    // Task isn't in window manager yet since it isn't associated with a stack.
9426                    // Return the persist value from activity manager
9427                    if (task.mBounds != null) {
9428                        rect.set(task.mBounds);
9429                    } else if (task.mLastNonFullscreenBounds != null) {
9430                        rect.set(task.mLastNonFullscreenBounds);
9431                    }
9432                }
9433            }
9434        } finally {
9435            Binder.restoreCallingIdentity(ident);
9436        }
9437        return rect;
9438    }
9439
9440    @Override
9441    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9442        if (userId != UserHandle.getCallingUserId()) {
9443            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9444                    "getTaskDescriptionIcon");
9445        }
9446        final File passedIconFile = new File(filePath);
9447        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9448                passedIconFile.getName());
9449        if (!legitIconFile.getPath().equals(filePath)
9450                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9451            throw new IllegalArgumentException("Bad file path: " + filePath
9452                    + " passed for userId " + userId);
9453        }
9454        return mRecentTasks.getTaskDescriptionIcon(filePath);
9455    }
9456
9457    @Override
9458    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
9459            throws RemoteException {
9460        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
9461        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9462                activityOptions.getCustomInPlaceResId() == 0) {
9463            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9464                    "with valid animation");
9465        }
9466        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9467        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
9468                activityOptions.getCustomInPlaceResId());
9469        mWindowManager.executeAppTransition();
9470    }
9471
9472    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9473            boolean removeFromRecents) {
9474        if (removeFromRecents) {
9475            mRecentTasks.remove(tr);
9476            tr.removedFromRecents();
9477        }
9478        ComponentName component = tr.getBaseIntent().getComponent();
9479        if (component == null) {
9480            Slog.w(TAG, "No component for base intent of task: " + tr);
9481            return;
9482        }
9483
9484        // Find any running services associated with this app and stop if needed.
9485        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9486
9487        if (!killProcess) {
9488            return;
9489        }
9490
9491        // Determine if the process(es) for this task should be killed.
9492        final String pkg = component.getPackageName();
9493        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9494        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9495        for (int i = 0; i < pmap.size(); i++) {
9496
9497            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9498            for (int j = 0; j < uids.size(); j++) {
9499                ProcessRecord proc = uids.valueAt(j);
9500                if (proc.userId != tr.userId) {
9501                    // Don't kill process for a different user.
9502                    continue;
9503                }
9504                if (proc == mHomeProcess) {
9505                    // Don't kill the home process along with tasks from the same package.
9506                    continue;
9507                }
9508                if (!proc.pkgList.containsKey(pkg)) {
9509                    // Don't kill process that is not associated with this task.
9510                    continue;
9511                }
9512
9513                for (int k = 0; k < proc.activities.size(); k++) {
9514                    TaskRecord otherTask = proc.activities.get(k).task;
9515                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9516                        // Don't kill process(es) that has an activity in a different task that is
9517                        // also in recents.
9518                        return;
9519                    }
9520                }
9521
9522                if (proc.foregroundServices) {
9523                    // Don't kill process(es) with foreground service.
9524                    return;
9525                }
9526
9527                // Add process to kill list.
9528                procsToKill.add(proc);
9529            }
9530        }
9531
9532        // Kill the running processes.
9533        for (int i = 0; i < procsToKill.size(); i++) {
9534            ProcessRecord pr = procsToKill.get(i);
9535            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9536                    && pr.curReceivers.isEmpty()) {
9537                pr.kill("remove task", true);
9538            } else {
9539                // We delay killing processes that are not in the background or running a receiver.
9540                pr.waitingToKill = "remove task";
9541            }
9542        }
9543    }
9544
9545    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9546        // Remove all tasks with activities in the specified package from the list of recent tasks
9547        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9548            TaskRecord tr = mRecentTasks.get(i);
9549            if (tr.userId != userId) continue;
9550
9551            ComponentName cn = tr.intent.getComponent();
9552            if (cn != null && cn.getPackageName().equals(packageName)) {
9553                // If the package name matches, remove the task.
9554                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9555            }
9556        }
9557    }
9558
9559    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9560            int userId) {
9561
9562        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9563            TaskRecord tr = mRecentTasks.get(i);
9564            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9565                continue;
9566            }
9567
9568            ComponentName cn = tr.intent.getComponent();
9569            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9570                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9571            if (sameComponent) {
9572                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9573            }
9574        }
9575    }
9576
9577    /**
9578     * Removes the task with the specified task id.
9579     *
9580     * @param taskId Identifier of the task to be removed.
9581     * @param killProcess Kill any process associated with the task if possible.
9582     * @param removeFromRecents Whether to also remove the task from recents.
9583     * @return Returns true if the given task was found and removed.
9584     */
9585    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9586            boolean removeFromRecents) {
9587        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9588                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9589        if (tr != null) {
9590            tr.removeTaskActivitiesLocked();
9591            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9592            if (tr.isPersistable) {
9593                notifyTaskPersisterLocked(null, true);
9594            }
9595            return true;
9596        }
9597        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9598        return false;
9599    }
9600
9601    @Override
9602    public void removeStack(int stackId) {
9603        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9604        if (stackId == HOME_STACK_ID) {
9605            throw new IllegalArgumentException("Removing home stack is not allowed.");
9606        }
9607
9608        synchronized (this) {
9609            final long ident = Binder.clearCallingIdentity();
9610            try {
9611                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9612                if (stack == null) {
9613                    return;
9614                }
9615                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9616                for (int i = tasks.size() - 1; i >= 0; i--) {
9617                    removeTaskByIdLocked(
9618                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9619                }
9620            } finally {
9621                Binder.restoreCallingIdentity(ident);
9622            }
9623        }
9624    }
9625
9626    @Override
9627    public void moveStackToDisplay(int stackId, int displayId) {
9628        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
9629
9630        synchronized (this) {
9631            final long ident = Binder.clearCallingIdentity();
9632            try {
9633                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
9634                        + " to displayId=" + displayId);
9635                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId);
9636            } finally {
9637                Binder.restoreCallingIdentity(ident);
9638            }
9639        }
9640    }
9641
9642    @Override
9643    public boolean removeTask(int taskId) {
9644        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9645        synchronized (this) {
9646            final long ident = Binder.clearCallingIdentity();
9647            try {
9648                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9649            } finally {
9650                Binder.restoreCallingIdentity(ident);
9651            }
9652        }
9653    }
9654
9655    /**
9656     * TODO: Add mController hook
9657     */
9658    @Override
9659    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9660        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9661
9662        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9663        synchronized(this) {
9664            moveTaskToFrontLocked(taskId, flags, bOptions);
9665        }
9666    }
9667
9668    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9669        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9670
9671        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9672                Binder.getCallingUid(), -1, -1, "Task to front")) {
9673            ActivityOptions.abort(options);
9674            return;
9675        }
9676        final long origId = Binder.clearCallingIdentity();
9677        try {
9678            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9679            if (task == null) {
9680                Slog.d(TAG, "Could not find task for id: "+ taskId);
9681                return;
9682            }
9683            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9684                mStackSupervisor.showLockTaskToast();
9685                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9686                return;
9687            }
9688            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9689            if (prev != null && prev.isRecentsActivity()) {
9690                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9691            }
9692            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9693                    false /* forceNonResizable */);
9694        } finally {
9695            Binder.restoreCallingIdentity(origId);
9696        }
9697        ActivityOptions.abort(options);
9698    }
9699
9700    /**
9701     * Moves an activity, and all of the other activities within the same task, to the bottom
9702     * of the history stack.  The activity's order within the task is unchanged.
9703     *
9704     * @param token A reference to the activity we wish to move
9705     * @param nonRoot If false then this only works if the activity is the root
9706     *                of a task; if true it will work for any activity in a task.
9707     * @return Returns true if the move completed, false if not.
9708     */
9709    @Override
9710    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9711        enforceNotIsolatedCaller("moveActivityTaskToBack");
9712        synchronized(this) {
9713            final long origId = Binder.clearCallingIdentity();
9714            try {
9715                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9716                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9717                if (task != null) {
9718                    if (mStackSupervisor.isLockedTask(task)) {
9719                        mStackSupervisor.showLockTaskToast();
9720                        return false;
9721                    }
9722                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9723                }
9724            } finally {
9725                Binder.restoreCallingIdentity(origId);
9726            }
9727        }
9728        return false;
9729    }
9730
9731    @Override
9732    public void moveTaskBackwards(int task) {
9733        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9734                "moveTaskBackwards()");
9735
9736        synchronized(this) {
9737            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9738                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9739                return;
9740            }
9741            final long origId = Binder.clearCallingIdentity();
9742            moveTaskBackwardsLocked(task);
9743            Binder.restoreCallingIdentity(origId);
9744        }
9745    }
9746
9747    private final void moveTaskBackwardsLocked(int task) {
9748        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9749    }
9750
9751    @Override
9752    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9753            IActivityContainerCallback callback) throws RemoteException {
9754        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9755        synchronized (this) {
9756            if (parentActivityToken == null) {
9757                throw new IllegalArgumentException("parent token must not be null");
9758            }
9759            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9760            if (r == null) {
9761                return null;
9762            }
9763            if (callback == null) {
9764                throw new IllegalArgumentException("callback must not be null");
9765            }
9766            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9767        }
9768    }
9769
9770    @Override
9771    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9772        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9773        synchronized (this) {
9774            final int stackId = mStackSupervisor.getNextStackId();
9775            final ActivityStack stack =
9776                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9777            if (stack == null) {
9778                return null;
9779            }
9780            return stack.mActivityContainer;
9781        }
9782    }
9783
9784    @Override
9785    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9786        synchronized (this) {
9787            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9788            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9789                return stack.mActivityContainer.getDisplayId();
9790            }
9791            return DEFAULT_DISPLAY;
9792        }
9793    }
9794
9795    @Override
9796    public int getActivityStackId(IBinder token) throws RemoteException {
9797        synchronized (this) {
9798            ActivityStack stack = ActivityRecord.getStackLocked(token);
9799            if (stack == null) {
9800                return INVALID_STACK_ID;
9801            }
9802            return stack.mStackId;
9803        }
9804    }
9805
9806    @Override
9807    public void exitFreeformMode(IBinder token) throws RemoteException {
9808        synchronized (this) {
9809            long ident = Binder.clearCallingIdentity();
9810            try {
9811                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9812                if (r == null) {
9813                    throw new IllegalArgumentException(
9814                            "exitFreeformMode: No activity record matching token=" + token);
9815                }
9816                final ActivityStack stack = r.getStackLocked(token);
9817                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9818                    throw new IllegalStateException(
9819                            "exitFreeformMode: You can only go fullscreen from freeform.");
9820                }
9821                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9822                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9823                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9824            } finally {
9825                Binder.restoreCallingIdentity(ident);
9826            }
9827        }
9828    }
9829
9830    @Override
9831    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9832        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9833        if (stackId == HOME_STACK_ID) {
9834            throw new IllegalArgumentException(
9835                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9836        }
9837        synchronized (this) {
9838            long ident = Binder.clearCallingIdentity();
9839            try {
9840                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9841                        + " to stackId=" + stackId + " toTop=" + toTop);
9842                if (stackId == DOCKED_STACK_ID) {
9843                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9844                            null /* initialBounds */);
9845                }
9846                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9847                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9848                if (result && stackId == DOCKED_STACK_ID) {
9849                    // If task moved to docked stack - show recents if needed.
9850                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9851                            "moveTaskToDockedStack");
9852                }
9853            } finally {
9854                Binder.restoreCallingIdentity(ident);
9855            }
9856        }
9857    }
9858
9859    @Override
9860    public void swapDockedAndFullscreenStack() throws RemoteException {
9861        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9862        synchronized (this) {
9863            long ident = Binder.clearCallingIdentity();
9864            try {
9865                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9866                        FULLSCREEN_WORKSPACE_STACK_ID);
9867                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9868                        : null;
9869                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9870                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9871                        : null;
9872                if (topTask == null || tasks == null || tasks.size() == 0) {
9873                    Slog.w(TAG,
9874                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9875                    return;
9876                }
9877
9878                // TODO: App transition
9879                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9880
9881                // Defer the resume so resume/pausing while moving stacks is dangerous.
9882                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9883                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9884                        ANIMATE, true /* deferResume */);
9885                final int size = tasks.size();
9886                for (int i = 0; i < size; i++) {
9887                    final int id = tasks.get(i).taskId;
9888                    if (id == topTask.taskId) {
9889                        continue;
9890                    }
9891                    mStackSupervisor.moveTaskToStackLocked(id,
9892                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9893                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9894                }
9895
9896                // Because we deferred the resume, to avoid conflicts with stack switches while
9897                // resuming, we need to do it after all the tasks are moved.
9898                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9899                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9900
9901                mWindowManager.executeAppTransition();
9902            } finally {
9903                Binder.restoreCallingIdentity(ident);
9904            }
9905        }
9906    }
9907
9908    /**
9909     * Moves the input task to the docked stack.
9910     *
9911     * @param taskId Id of task to move.
9912     * @param createMode The mode the docked stack should be created in if it doesn't exist
9913     *                   already. See
9914     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9915     *                   and
9916     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9917     * @param toTop If the task and stack should be moved to the top.
9918     * @param animate Whether we should play an animation for the moving the task
9919     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9920     *                      docked stack. Pass {@code null} to use default bounds.
9921     */
9922    @Override
9923    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9924            Rect initialBounds, boolean moveHomeStackFront) {
9925        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9926        synchronized (this) {
9927            long ident = Binder.clearCallingIdentity();
9928            try {
9929                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9930                        + " to createMode=" + createMode + " toTop=" + toTop);
9931                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9932                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9933                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9934                        animate, DEFER_RESUME);
9935                if (moved) {
9936                    if (moveHomeStackFront) {
9937                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9938                    }
9939                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9940                }
9941                return moved;
9942            } finally {
9943                Binder.restoreCallingIdentity(ident);
9944            }
9945        }
9946    }
9947
9948    /**
9949     * Moves the top activity in the input stackId to the pinned stack.
9950     *
9951     * @param stackId Id of stack to move the top activity to pinned stack.
9952     * @param bounds Bounds to use for pinned stack.
9953     *
9954     * @return True if the top activity of the input stack was successfully moved to the pinned
9955     *          stack.
9956     */
9957    @Override
9958    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9959        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9960        synchronized (this) {
9961            if (!mSupportsPictureInPicture) {
9962                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9963                        + "Device doesn't support picture-in-pciture mode");
9964            }
9965
9966            long ident = Binder.clearCallingIdentity();
9967            try {
9968                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9969            } finally {
9970                Binder.restoreCallingIdentity(ident);
9971            }
9972        }
9973    }
9974
9975    @Override
9976    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9977            boolean preserveWindows, boolean animate, int animationDuration) {
9978        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9979        long ident = Binder.clearCallingIdentity();
9980        try {
9981            synchronized (this) {
9982                if (animate) {
9983                    if (stackId == PINNED_STACK_ID) {
9984                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9985                    } else {
9986                        throw new IllegalArgumentException("Stack: " + stackId
9987                                + " doesn't support animated resize.");
9988                    }
9989                } else {
9990                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9991                            null /* tempTaskInsetBounds */, preserveWindows,
9992                            allowResizeInDockedMode, !DEFER_RESUME);
9993                }
9994            }
9995        } finally {
9996            Binder.restoreCallingIdentity(ident);
9997        }
9998    }
9999
10000    @Override
10001    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10002            Rect tempDockedTaskInsetBounds,
10003            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10004        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10005                "resizeDockedStack()");
10006        long ident = Binder.clearCallingIdentity();
10007        try {
10008            synchronized (this) {
10009                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10010                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10011                        PRESERVE_WINDOWS);
10012            }
10013        } finally {
10014            Binder.restoreCallingIdentity(ident);
10015        }
10016    }
10017
10018    @Override
10019    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10020        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10021                "resizePinnedStack()");
10022        final long ident = Binder.clearCallingIdentity();
10023        try {
10024            synchronized (this) {
10025                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10026            }
10027        } finally {
10028            Binder.restoreCallingIdentity(ident);
10029        }
10030    }
10031
10032    @Override
10033    public void positionTaskInStack(int taskId, int stackId, int position) {
10034        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10035        if (stackId == HOME_STACK_ID) {
10036            throw new IllegalArgumentException(
10037                    "positionTaskInStack: Attempt to change the position of task "
10038                    + taskId + " in/to home stack");
10039        }
10040        synchronized (this) {
10041            long ident = Binder.clearCallingIdentity();
10042            try {
10043                if (DEBUG_STACK) Slog.d(TAG_STACK,
10044                        "positionTaskInStack: positioning task=" + taskId
10045                        + " in stackId=" + stackId + " at position=" + position);
10046                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10047            } finally {
10048                Binder.restoreCallingIdentity(ident);
10049            }
10050        }
10051    }
10052
10053    @Override
10054    public List<StackInfo> getAllStackInfos() {
10055        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10056        long ident = Binder.clearCallingIdentity();
10057        try {
10058            synchronized (this) {
10059                return mStackSupervisor.getAllStackInfosLocked();
10060            }
10061        } finally {
10062            Binder.restoreCallingIdentity(ident);
10063        }
10064    }
10065
10066    @Override
10067    public StackInfo getStackInfo(int stackId) {
10068        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10069        long ident = Binder.clearCallingIdentity();
10070        try {
10071            synchronized (this) {
10072                return mStackSupervisor.getStackInfoLocked(stackId);
10073            }
10074        } finally {
10075            Binder.restoreCallingIdentity(ident);
10076        }
10077    }
10078
10079    @Override
10080    public boolean isInHomeStack(int taskId) {
10081        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10082        long ident = Binder.clearCallingIdentity();
10083        try {
10084            synchronized (this) {
10085                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10086                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10087                final ActivityStack stack = tr != null ? tr.getStack() : null;
10088                return stack != null && stack.isHomeStack();
10089            }
10090        } finally {
10091            Binder.restoreCallingIdentity(ident);
10092        }
10093    }
10094
10095    @Override
10096    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10097        synchronized(this) {
10098            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10099        }
10100    }
10101
10102    @Override
10103    public void updateDeviceOwner(String packageName) {
10104        final int callingUid = Binder.getCallingUid();
10105        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10106            throw new SecurityException("updateDeviceOwner called from non-system process");
10107        }
10108        synchronized (this) {
10109            mDeviceOwnerName = packageName;
10110        }
10111    }
10112
10113    @Override
10114    public void updateLockTaskPackages(int userId, String[] packages) {
10115        final int callingUid = Binder.getCallingUid();
10116        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10117            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10118                    "updateLockTaskPackages()");
10119        }
10120        synchronized (this) {
10121            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10122                    Arrays.toString(packages));
10123            mLockTaskPackages.put(userId, packages);
10124            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10125        }
10126    }
10127
10128
10129    void startLockTaskModeLocked(TaskRecord task) {
10130        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10131        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10132            return;
10133        }
10134
10135        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10136        // is initiated by system after the pinning request was shown and locked mode is initiated
10137        // by an authorized app directly
10138        final int callingUid = Binder.getCallingUid();
10139        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10140        long ident = Binder.clearCallingIdentity();
10141        try {
10142            if (!isSystemInitiated) {
10143                task.mLockTaskUid = callingUid;
10144                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10145                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10146                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10147                    StatusBarManagerInternal statusBarManager =
10148                            LocalServices.getService(StatusBarManagerInternal.class);
10149                    if (statusBarManager != null) {
10150                        statusBarManager.showScreenPinningRequest(task.taskId);
10151                    }
10152                    return;
10153                }
10154
10155                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10156                if (stack == null || task != stack.topTask()) {
10157                    throw new IllegalArgumentException("Invalid task, not in foreground");
10158                }
10159            }
10160            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10161                    "Locking fully");
10162            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10163                    ActivityManager.LOCK_TASK_MODE_PINNED :
10164                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10165                    "startLockTask", true);
10166        } finally {
10167            Binder.restoreCallingIdentity(ident);
10168        }
10169    }
10170
10171    @Override
10172    public void startLockTaskModeById(int taskId) {
10173        synchronized (this) {
10174            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10175            if (task != null) {
10176                startLockTaskModeLocked(task);
10177            }
10178        }
10179    }
10180
10181    @Override
10182    public void startLockTaskModeByToken(IBinder token) {
10183        synchronized (this) {
10184            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10185            if (r == null) {
10186                return;
10187            }
10188            final TaskRecord task = r.task;
10189            if (task != null) {
10190                startLockTaskModeLocked(task);
10191            }
10192        }
10193    }
10194
10195    @Override
10196    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10197        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10198        // This makes inner call to look as if it was initiated by system.
10199        long ident = Binder.clearCallingIdentity();
10200        try {
10201            synchronized (this) {
10202                startLockTaskModeById(taskId);
10203            }
10204        } finally {
10205            Binder.restoreCallingIdentity(ident);
10206        }
10207    }
10208
10209    @Override
10210    public void stopLockTaskMode() {
10211        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10212        if (lockTask == null) {
10213            // Our work here is done.
10214            return;
10215        }
10216
10217        final int callingUid = Binder.getCallingUid();
10218        final int lockTaskUid = lockTask.mLockTaskUid;
10219        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10220        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10221            // Done.
10222            return;
10223        } else {
10224            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10225            // It is possible lockTaskMode was started by the system process because
10226            // android:lockTaskMode is set to a locking value in the application manifest
10227            // instead of the app calling startLockTaskMode. In this case
10228            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10229            // {@link TaskRecord.effectiveUid} instead. Also caller with
10230            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10231            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10232                    && callingUid != lockTaskUid
10233                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10234                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10235                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10236            }
10237        }
10238        long ident = Binder.clearCallingIdentity();
10239        try {
10240            Log.d(TAG, "stopLockTaskMode");
10241            // Stop lock task
10242            synchronized (this) {
10243                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10244                        "stopLockTask", true);
10245            }
10246            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10247            if (tm != null) {
10248                tm.showInCallScreen(false);
10249            }
10250        } finally {
10251            Binder.restoreCallingIdentity(ident);
10252        }
10253    }
10254
10255    /**
10256     * This API should be called by SystemUI only when user perform certain action to dismiss
10257     * lock task mode. We should only dismiss pinned lock task mode in this case.
10258     */
10259    @Override
10260    public void stopSystemLockTaskMode() throws RemoteException {
10261        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10262            stopLockTaskMode();
10263        } else {
10264            mStackSupervisor.showLockTaskToast();
10265        }
10266    }
10267
10268    @Override
10269    public boolean isInLockTaskMode() {
10270        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10271    }
10272
10273    @Override
10274    public int getLockTaskModeState() {
10275        synchronized (this) {
10276            return mStackSupervisor.getLockTaskModeState();
10277        }
10278    }
10279
10280    @Override
10281    public void showLockTaskEscapeMessage(IBinder token) {
10282        synchronized (this) {
10283            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10284            if (r == null) {
10285                return;
10286            }
10287            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10288        }
10289    }
10290
10291    // =========================================================
10292    // CONTENT PROVIDERS
10293    // =========================================================
10294
10295    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10296        List<ProviderInfo> providers = null;
10297        try {
10298            providers = AppGlobals.getPackageManager()
10299                    .queryContentProviders(app.processName, app.uid,
10300                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10301                                    | MATCH_DEBUG_TRIAGED_MISSING)
10302                    .getList();
10303        } catch (RemoteException ex) {
10304        }
10305        if (DEBUG_MU) Slog.v(TAG_MU,
10306                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10307        int userId = app.userId;
10308        if (providers != null) {
10309            int N = providers.size();
10310            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10311            for (int i=0; i<N; i++) {
10312                // TODO: keep logic in sync with installEncryptionUnawareProviders
10313                ProviderInfo cpi =
10314                    (ProviderInfo)providers.get(i);
10315                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10316                        cpi.name, cpi.flags);
10317                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10318                    // This is a singleton provider, but a user besides the
10319                    // default user is asking to initialize a process it runs
10320                    // in...  well, no, it doesn't actually run in this process,
10321                    // it runs in the process of the default user.  Get rid of it.
10322                    providers.remove(i);
10323                    N--;
10324                    i--;
10325                    continue;
10326                }
10327
10328                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10329                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10330                if (cpr == null) {
10331                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10332                    mProviderMap.putProviderByClass(comp, cpr);
10333                }
10334                if (DEBUG_MU) Slog.v(TAG_MU,
10335                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10336                app.pubProviders.put(cpi.name, cpr);
10337                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10338                    // Don't add this if it is a platform component that is marked
10339                    // to run in multiple processes, because this is actually
10340                    // part of the framework so doesn't make sense to track as a
10341                    // separate apk in the process.
10342                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10343                            mProcessStats);
10344                }
10345                notifyPackageUse(cpi.applicationInfo.packageName,
10346                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10347            }
10348        }
10349        return providers;
10350    }
10351
10352    /**
10353     * Check if the calling UID has a possible chance at accessing the provider
10354     * at the given authority and user.
10355     */
10356    public String checkContentProviderAccess(String authority, int userId) {
10357        if (userId == UserHandle.USER_ALL) {
10358            mContext.enforceCallingOrSelfPermission(
10359                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10360            userId = UserHandle.getCallingUserId();
10361        }
10362
10363        ProviderInfo cpi = null;
10364        try {
10365            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10366                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10367                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10368                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10369                    userId);
10370        } catch (RemoteException ignored) {
10371        }
10372        if (cpi == null) {
10373            // TODO: make this an outright failure in a future platform release;
10374            // until then anonymous content notifications are unprotected
10375            //return "Failed to find provider " + authority + " for user " + userId;
10376            return null;
10377        }
10378
10379        ProcessRecord r = null;
10380        synchronized (mPidsSelfLocked) {
10381            r = mPidsSelfLocked.get(Binder.getCallingPid());
10382        }
10383        if (r == null) {
10384            return "Failed to find PID " + Binder.getCallingPid();
10385        }
10386
10387        synchronized (this) {
10388            return checkContentProviderPermissionLocked(cpi, r, userId, true);
10389        }
10390    }
10391
10392    /**
10393     * Check if {@link ProcessRecord} has a possible chance at accessing the
10394     * given {@link ProviderInfo}. Final permission checking is always done
10395     * in {@link ContentProvider}.
10396     */
10397    private final String checkContentProviderPermissionLocked(
10398            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10399        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10400        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10401        boolean checkedGrants = false;
10402        if (checkUser) {
10403            // Looking for cross-user grants before enforcing the typical cross-users permissions
10404            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10405            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10406                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10407                    return null;
10408                }
10409                checkedGrants = true;
10410            }
10411            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10412                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10413            if (userId != tmpTargetUserId) {
10414                // When we actually went to determine the final targer user ID, this ended
10415                // up different than our initial check for the authority.  This is because
10416                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10417                // SELF.  So we need to re-check the grants again.
10418                checkedGrants = false;
10419            }
10420        }
10421        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10422                cpi.applicationInfo.uid, cpi.exported)
10423                == PackageManager.PERMISSION_GRANTED) {
10424            return null;
10425        }
10426        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10427                cpi.applicationInfo.uid, cpi.exported)
10428                == PackageManager.PERMISSION_GRANTED) {
10429            return null;
10430        }
10431
10432        PathPermission[] pps = cpi.pathPermissions;
10433        if (pps != null) {
10434            int i = pps.length;
10435            while (i > 0) {
10436                i--;
10437                PathPermission pp = pps[i];
10438                String pprperm = pp.getReadPermission();
10439                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10440                        cpi.applicationInfo.uid, cpi.exported)
10441                        == PackageManager.PERMISSION_GRANTED) {
10442                    return null;
10443                }
10444                String ppwperm = pp.getWritePermission();
10445                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10446                        cpi.applicationInfo.uid, cpi.exported)
10447                        == PackageManager.PERMISSION_GRANTED) {
10448                    return null;
10449                }
10450            }
10451        }
10452        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10453            return null;
10454        }
10455
10456        String msg;
10457        if (!cpi.exported) {
10458            msg = "Permission Denial: opening provider " + cpi.name
10459                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10460                    + ", uid=" + callingUid + ") that is not exported from uid "
10461                    + cpi.applicationInfo.uid;
10462        } else {
10463            msg = "Permission Denial: opening provider " + cpi.name
10464                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10465                    + ", uid=" + callingUid + ") requires "
10466                    + cpi.readPermission + " or " + cpi.writePermission;
10467        }
10468        Slog.w(TAG, msg);
10469        return msg;
10470    }
10471
10472    /**
10473     * Returns if the ContentProvider has granted a uri to callingUid
10474     */
10475    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10476        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10477        if (perms != null) {
10478            for (int i=perms.size()-1; i>=0; i--) {
10479                GrantUri grantUri = perms.keyAt(i);
10480                if (grantUri.sourceUserId == userId || !checkUser) {
10481                    if (matchesProvider(grantUri.uri, cpi)) {
10482                        return true;
10483                    }
10484                }
10485            }
10486        }
10487        return false;
10488    }
10489
10490    /**
10491     * Returns true if the uri authority is one of the authorities specified in the provider.
10492     */
10493    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10494        String uriAuth = uri.getAuthority();
10495        String cpiAuth = cpi.authority;
10496        if (cpiAuth.indexOf(';') == -1) {
10497            return cpiAuth.equals(uriAuth);
10498        }
10499        String[] cpiAuths = cpiAuth.split(";");
10500        int length = cpiAuths.length;
10501        for (int i = 0; i < length; i++) {
10502            if (cpiAuths[i].equals(uriAuth)) return true;
10503        }
10504        return false;
10505    }
10506
10507    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10508            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10509        if (r != null) {
10510            for (int i=0; i<r.conProviders.size(); i++) {
10511                ContentProviderConnection conn = r.conProviders.get(i);
10512                if (conn.provider == cpr) {
10513                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10514                            "Adding provider requested by "
10515                            + r.processName + " from process "
10516                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10517                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10518                    if (stable) {
10519                        conn.stableCount++;
10520                        conn.numStableIncs++;
10521                    } else {
10522                        conn.unstableCount++;
10523                        conn.numUnstableIncs++;
10524                    }
10525                    return conn;
10526                }
10527            }
10528            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10529            if (stable) {
10530                conn.stableCount = 1;
10531                conn.numStableIncs = 1;
10532            } else {
10533                conn.unstableCount = 1;
10534                conn.numUnstableIncs = 1;
10535            }
10536            cpr.connections.add(conn);
10537            r.conProviders.add(conn);
10538            startAssociationLocked(r.uid, r.processName, r.curProcState,
10539                    cpr.uid, cpr.name, cpr.info.processName);
10540            return conn;
10541        }
10542        cpr.addExternalProcessHandleLocked(externalProcessToken);
10543        return null;
10544    }
10545
10546    boolean decProviderCountLocked(ContentProviderConnection conn,
10547            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10548        if (conn != null) {
10549            cpr = conn.provider;
10550            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10551                    "Removing provider requested by "
10552                    + conn.client.processName + " from process "
10553                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10554                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10555            if (stable) {
10556                conn.stableCount--;
10557            } else {
10558                conn.unstableCount--;
10559            }
10560            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10561                cpr.connections.remove(conn);
10562                conn.client.conProviders.remove(conn);
10563                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10564                    // The client is more important than last activity -- note the time this
10565                    // is happening, so we keep the old provider process around a bit as last
10566                    // activity to avoid thrashing it.
10567                    if (cpr.proc != null) {
10568                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10569                    }
10570                }
10571                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10572                return true;
10573            }
10574            return false;
10575        }
10576        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10577        return false;
10578    }
10579
10580    private void checkTime(long startTime, String where) {
10581        long now = SystemClock.uptimeMillis();
10582        if ((now-startTime) > 50) {
10583            // If we are taking more than 50ms, log about it.
10584            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10585        }
10586    }
10587
10588    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10589            PROC_SPACE_TERM,
10590            PROC_SPACE_TERM|PROC_PARENS,
10591            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10592    };
10593
10594    private final long[] mProcessStateStatsLongs = new long[1];
10595
10596    boolean isProcessAliveLocked(ProcessRecord proc) {
10597        if (proc.procStatFile == null) {
10598            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10599        }
10600        mProcessStateStatsLongs[0] = 0;
10601        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10602                mProcessStateStatsLongs, null)) {
10603            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10604            return false;
10605        }
10606        final long state = mProcessStateStatsLongs[0];
10607        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10608                + (char)state);
10609        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10610    }
10611
10612    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10613            String name, IBinder token, boolean stable, int userId) {
10614        ContentProviderRecord cpr;
10615        ContentProviderConnection conn = null;
10616        ProviderInfo cpi = null;
10617
10618        synchronized(this) {
10619            long startTime = SystemClock.uptimeMillis();
10620
10621            ProcessRecord r = null;
10622            if (caller != null) {
10623                r = getRecordForAppLocked(caller);
10624                if (r == null) {
10625                    throw new SecurityException(
10626                            "Unable to find app for caller " + caller
10627                          + " (pid=" + Binder.getCallingPid()
10628                          + ") when getting content provider " + name);
10629                }
10630            }
10631
10632            boolean checkCrossUser = true;
10633
10634            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10635
10636            // First check if this content provider has been published...
10637            cpr = mProviderMap.getProviderByName(name, userId);
10638            // If that didn't work, check if it exists for user 0 and then
10639            // verify that it's a singleton provider before using it.
10640            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10641                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10642                if (cpr != null) {
10643                    cpi = cpr.info;
10644                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10645                            cpi.name, cpi.flags)
10646                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10647                        userId = UserHandle.USER_SYSTEM;
10648                        checkCrossUser = false;
10649                    } else {
10650                        cpr = null;
10651                        cpi = null;
10652                    }
10653                }
10654            }
10655
10656            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10657            if (providerRunning) {
10658                cpi = cpr.info;
10659                String msg;
10660                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10661                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10662                        != null) {
10663                    throw new SecurityException(msg);
10664                }
10665                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10666
10667                if (r != null && cpr.canRunHere(r)) {
10668                    // This provider has been published or is in the process
10669                    // of being published...  but it is also allowed to run
10670                    // in the caller's process, so don't make a connection
10671                    // and just let the caller instantiate its own instance.
10672                    ContentProviderHolder holder = cpr.newHolder(null);
10673                    // don't give caller the provider object, it needs
10674                    // to make its own.
10675                    holder.provider = null;
10676                    return holder;
10677                }
10678
10679                final long origId = Binder.clearCallingIdentity();
10680
10681                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10682
10683                // In this case the provider instance already exists, so we can
10684                // return it right away.
10685                conn = incProviderCountLocked(r, cpr, token, stable);
10686                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10687                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10688                        // If this is a perceptible app accessing the provider,
10689                        // make sure to count it as being accessed and thus
10690                        // back up on the LRU list.  This is good because
10691                        // content providers are often expensive to start.
10692                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10693                        updateLruProcessLocked(cpr.proc, false, null);
10694                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10695                    }
10696                }
10697
10698                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10699                final int verifiedAdj = cpr.proc.verifiedAdj;
10700                boolean success = updateOomAdjLocked(cpr.proc);
10701                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10702                // if the process has been successfully adjusted.  So to reduce races with
10703                // it, we will check whether the process still exists.  Note that this doesn't
10704                // completely get rid of races with LMK killing the process, but should make
10705                // them much smaller.
10706                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10707                    success = false;
10708                }
10709                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10710                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10711                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10712                // NOTE: there is still a race here where a signal could be
10713                // pending on the process even though we managed to update its
10714                // adj level.  Not sure what to do about this, but at least
10715                // the race is now smaller.
10716                if (!success) {
10717                    // Uh oh...  it looks like the provider's process
10718                    // has been killed on us.  We need to wait for a new
10719                    // process to be started, and make sure its death
10720                    // doesn't kill our process.
10721                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10722                            + " is crashing; detaching " + r);
10723                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10724                    checkTime(startTime, "getContentProviderImpl: before appDied");
10725                    appDiedLocked(cpr.proc);
10726                    checkTime(startTime, "getContentProviderImpl: after appDied");
10727                    if (!lastRef) {
10728                        // This wasn't the last ref our process had on
10729                        // the provider...  we have now been killed, bail.
10730                        return null;
10731                    }
10732                    providerRunning = false;
10733                    conn = null;
10734                } else {
10735                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10736                }
10737
10738                Binder.restoreCallingIdentity(origId);
10739            }
10740
10741            if (!providerRunning) {
10742                try {
10743                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10744                    cpi = AppGlobals.getPackageManager().
10745                        resolveContentProvider(name,
10746                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10747                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10748                } catch (RemoteException ex) {
10749                }
10750                if (cpi == null) {
10751                    return null;
10752                }
10753                // If the provider is a singleton AND
10754                // (it's a call within the same user || the provider is a
10755                // privileged app)
10756                // Then allow connecting to the singleton provider
10757                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10758                        cpi.name, cpi.flags)
10759                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10760                if (singleton) {
10761                    userId = UserHandle.USER_SYSTEM;
10762                }
10763                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10764                checkTime(startTime, "getContentProviderImpl: got app info for user");
10765
10766                String msg;
10767                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10768                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10769                        != null) {
10770                    throw new SecurityException(msg);
10771                }
10772                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10773
10774                if (!mProcessesReady
10775                        && !cpi.processName.equals("system")) {
10776                    // If this content provider does not run in the system
10777                    // process, and the system is not yet ready to run other
10778                    // processes, then fail fast instead of hanging.
10779                    throw new IllegalArgumentException(
10780                            "Attempt to launch content provider before system ready");
10781                }
10782
10783                // Make sure that the user who owns this provider is running.  If not,
10784                // we don't want to allow it to run.
10785                if (!mUserController.isUserRunningLocked(userId, 0)) {
10786                    Slog.w(TAG, "Unable to launch app "
10787                            + cpi.applicationInfo.packageName + "/"
10788                            + cpi.applicationInfo.uid + " for provider "
10789                            + name + ": user " + userId + " is stopped");
10790                    return null;
10791                }
10792
10793                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10794                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10795                cpr = mProviderMap.getProviderByClass(comp, userId);
10796                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10797                final boolean firstClass = cpr == null;
10798                if (firstClass) {
10799                    final long ident = Binder.clearCallingIdentity();
10800
10801                    // If permissions need a review before any of the app components can run,
10802                    // we return no provider and launch a review activity if the calling app
10803                    // is in the foreground.
10804                    if (mPermissionReviewRequired) {
10805                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10806                            return null;
10807                        }
10808                    }
10809
10810                    try {
10811                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10812                        ApplicationInfo ai =
10813                            AppGlobals.getPackageManager().
10814                                getApplicationInfo(
10815                                        cpi.applicationInfo.packageName,
10816                                        STOCK_PM_FLAGS, userId);
10817                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10818                        if (ai == null) {
10819                            Slog.w(TAG, "No package info for content provider "
10820                                    + cpi.name);
10821                            return null;
10822                        }
10823                        ai = getAppInfoForUser(ai, userId);
10824                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10825                    } catch (RemoteException ex) {
10826                        // pm is in same process, this will never happen.
10827                    } finally {
10828                        Binder.restoreCallingIdentity(ident);
10829                    }
10830                }
10831
10832                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10833
10834                if (r != null && cpr.canRunHere(r)) {
10835                    // If this is a multiprocess provider, then just return its
10836                    // info and allow the caller to instantiate it.  Only do
10837                    // this if the provider is the same user as the caller's
10838                    // process, or can run as root (so can be in any process).
10839                    return cpr.newHolder(null);
10840                }
10841
10842                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10843                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10844                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10845
10846                // This is single process, and our app is now connecting to it.
10847                // See if we are already in the process of launching this
10848                // provider.
10849                final int N = mLaunchingProviders.size();
10850                int i;
10851                for (i = 0; i < N; i++) {
10852                    if (mLaunchingProviders.get(i) == cpr) {
10853                        break;
10854                    }
10855                }
10856
10857                // If the provider is not already being launched, then get it
10858                // started.
10859                if (i >= N) {
10860                    final long origId = Binder.clearCallingIdentity();
10861
10862                    try {
10863                        // Content provider is now in use, its package can't be stopped.
10864                        try {
10865                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10866                            AppGlobals.getPackageManager().setPackageStoppedState(
10867                                    cpr.appInfo.packageName, false, userId);
10868                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10869                        } catch (RemoteException e) {
10870                        } catch (IllegalArgumentException e) {
10871                            Slog.w(TAG, "Failed trying to unstop package "
10872                                    + cpr.appInfo.packageName + ": " + e);
10873                        }
10874
10875                        // Use existing process if already started
10876                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10877                        ProcessRecord proc = getProcessRecordLocked(
10878                                cpi.processName, cpr.appInfo.uid, false);
10879                        if (proc != null && proc.thread != null && !proc.killed) {
10880                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10881                                    "Installing in existing process " + proc);
10882                            if (!proc.pubProviders.containsKey(cpi.name)) {
10883                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10884                                proc.pubProviders.put(cpi.name, cpr);
10885                                try {
10886                                    proc.thread.scheduleInstallProvider(cpi);
10887                                } catch (RemoteException e) {
10888                                }
10889                            }
10890                        } else {
10891                            checkTime(startTime, "getContentProviderImpl: before start process");
10892                            proc = startProcessLocked(cpi.processName,
10893                                    cpr.appInfo, false, 0, "content provider",
10894                                    new ComponentName(cpi.applicationInfo.packageName,
10895                                            cpi.name), false, false, false);
10896                            checkTime(startTime, "getContentProviderImpl: after start process");
10897                            if (proc == null) {
10898                                Slog.w(TAG, "Unable to launch app "
10899                                        + cpi.applicationInfo.packageName + "/"
10900                                        + cpi.applicationInfo.uid + " for provider "
10901                                        + name + ": process is bad");
10902                                return null;
10903                            }
10904                        }
10905                        cpr.launchingApp = proc;
10906                        mLaunchingProviders.add(cpr);
10907                    } finally {
10908                        Binder.restoreCallingIdentity(origId);
10909                    }
10910                }
10911
10912                checkTime(startTime, "getContentProviderImpl: updating data structures");
10913
10914                // Make sure the provider is published (the same provider class
10915                // may be published under multiple names).
10916                if (firstClass) {
10917                    mProviderMap.putProviderByClass(comp, cpr);
10918                }
10919
10920                mProviderMap.putProviderByName(name, cpr);
10921                conn = incProviderCountLocked(r, cpr, token, stable);
10922                if (conn != null) {
10923                    conn.waiting = true;
10924                }
10925            }
10926            checkTime(startTime, "getContentProviderImpl: done!");
10927        }
10928
10929        // Wait for the provider to be published...
10930        synchronized (cpr) {
10931            while (cpr.provider == null) {
10932                if (cpr.launchingApp == null) {
10933                    Slog.w(TAG, "Unable to launch app "
10934                            + cpi.applicationInfo.packageName + "/"
10935                            + cpi.applicationInfo.uid + " for provider "
10936                            + name + ": launching app became null");
10937                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10938                            UserHandle.getUserId(cpi.applicationInfo.uid),
10939                            cpi.applicationInfo.packageName,
10940                            cpi.applicationInfo.uid, name);
10941                    return null;
10942                }
10943                try {
10944                    if (DEBUG_MU) Slog.v(TAG_MU,
10945                            "Waiting to start provider " + cpr
10946                            + " launchingApp=" + cpr.launchingApp);
10947                    if (conn != null) {
10948                        conn.waiting = true;
10949                    }
10950                    cpr.wait();
10951                } catch (InterruptedException ex) {
10952                } finally {
10953                    if (conn != null) {
10954                        conn.waiting = false;
10955                    }
10956                }
10957            }
10958        }
10959        return cpr != null ? cpr.newHolder(conn) : null;
10960    }
10961
10962    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10963            ProcessRecord r, final int userId) {
10964        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10965                cpi.packageName, userId)) {
10966
10967            final boolean callerForeground = r == null || r.setSchedGroup
10968                    != ProcessList.SCHED_GROUP_BACKGROUND;
10969
10970            // Show a permission review UI only for starting from a foreground app
10971            if (!callerForeground) {
10972                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10973                        + cpi.packageName + " requires a permissions review");
10974                return false;
10975            }
10976
10977            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10978            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10979                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10980            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10981
10982            if (DEBUG_PERMISSIONS_REVIEW) {
10983                Slog.i(TAG, "u" + userId + " Launching permission review "
10984                        + "for package " + cpi.packageName);
10985            }
10986
10987            final UserHandle userHandle = new UserHandle(userId);
10988            mHandler.post(new Runnable() {
10989                @Override
10990                public void run() {
10991                    mContext.startActivityAsUser(intent, userHandle);
10992                }
10993            });
10994
10995            return false;
10996        }
10997
10998        return true;
10999    }
11000
11001    PackageManagerInternal getPackageManagerInternalLocked() {
11002        if (mPackageManagerInt == null) {
11003            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11004        }
11005        return mPackageManagerInt;
11006    }
11007
11008    @Override
11009    public final ContentProviderHolder getContentProvider(
11010            IApplicationThread caller, String name, int userId, boolean stable) {
11011        enforceNotIsolatedCaller("getContentProvider");
11012        if (caller == null) {
11013            String msg = "null IApplicationThread when getting content provider "
11014                    + name;
11015            Slog.w(TAG, msg);
11016            throw new SecurityException(msg);
11017        }
11018        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11019        // with cross-user grant.
11020        return getContentProviderImpl(caller, name, null, stable, userId);
11021    }
11022
11023    public ContentProviderHolder getContentProviderExternal(
11024            String name, int userId, IBinder token) {
11025        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11026            "Do not have permission in call getContentProviderExternal()");
11027        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11028                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11029        return getContentProviderExternalUnchecked(name, token, userId);
11030    }
11031
11032    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11033            IBinder token, int userId) {
11034        return getContentProviderImpl(null, name, token, true, userId);
11035    }
11036
11037    /**
11038     * Drop a content provider from a ProcessRecord's bookkeeping
11039     */
11040    public void removeContentProvider(IBinder connection, boolean stable) {
11041        enforceNotIsolatedCaller("removeContentProvider");
11042        long ident = Binder.clearCallingIdentity();
11043        try {
11044            synchronized (this) {
11045                ContentProviderConnection conn;
11046                try {
11047                    conn = (ContentProviderConnection)connection;
11048                } catch (ClassCastException e) {
11049                    String msg ="removeContentProvider: " + connection
11050                            + " not a ContentProviderConnection";
11051                    Slog.w(TAG, msg);
11052                    throw new IllegalArgumentException(msg);
11053                }
11054                if (conn == null) {
11055                    throw new NullPointerException("connection is null");
11056                }
11057                if (decProviderCountLocked(conn, null, null, stable)) {
11058                    updateOomAdjLocked();
11059                }
11060            }
11061        } finally {
11062            Binder.restoreCallingIdentity(ident);
11063        }
11064    }
11065
11066    public void removeContentProviderExternal(String name, IBinder token) {
11067        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11068            "Do not have permission in call removeContentProviderExternal()");
11069        int userId = UserHandle.getCallingUserId();
11070        long ident = Binder.clearCallingIdentity();
11071        try {
11072            removeContentProviderExternalUnchecked(name, token, userId);
11073        } finally {
11074            Binder.restoreCallingIdentity(ident);
11075        }
11076    }
11077
11078    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11079        synchronized (this) {
11080            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11081            if(cpr == null) {
11082                //remove from mProvidersByClass
11083                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11084                return;
11085            }
11086
11087            //update content provider record entry info
11088            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11089            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11090            if (localCpr.hasExternalProcessHandles()) {
11091                if (localCpr.removeExternalProcessHandleLocked(token)) {
11092                    updateOomAdjLocked();
11093                } else {
11094                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11095                            + " with no external reference for token: "
11096                            + token + ".");
11097                }
11098            } else {
11099                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11100                        + " with no external references.");
11101            }
11102        }
11103    }
11104
11105    public final void publishContentProviders(IApplicationThread caller,
11106            List<ContentProviderHolder> providers) {
11107        if (providers == null) {
11108            return;
11109        }
11110
11111        enforceNotIsolatedCaller("publishContentProviders");
11112        synchronized (this) {
11113            final ProcessRecord r = getRecordForAppLocked(caller);
11114            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11115            if (r == null) {
11116                throw new SecurityException(
11117                        "Unable to find app for caller " + caller
11118                      + " (pid=" + Binder.getCallingPid()
11119                      + ") when publishing content providers");
11120            }
11121
11122            final long origId = Binder.clearCallingIdentity();
11123
11124            final int N = providers.size();
11125            for (int i = 0; i < N; i++) {
11126                ContentProviderHolder src = providers.get(i);
11127                if (src == null || src.info == null || src.provider == null) {
11128                    continue;
11129                }
11130                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11131                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11132                if (dst != null) {
11133                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11134                    mProviderMap.putProviderByClass(comp, dst);
11135                    String names[] = dst.info.authority.split(";");
11136                    for (int j = 0; j < names.length; j++) {
11137                        mProviderMap.putProviderByName(names[j], dst);
11138                    }
11139
11140                    int launchingCount = mLaunchingProviders.size();
11141                    int j;
11142                    boolean wasInLaunchingProviders = false;
11143                    for (j = 0; j < launchingCount; j++) {
11144                        if (mLaunchingProviders.get(j) == dst) {
11145                            mLaunchingProviders.remove(j);
11146                            wasInLaunchingProviders = true;
11147                            j--;
11148                            launchingCount--;
11149                        }
11150                    }
11151                    if (wasInLaunchingProviders) {
11152                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11153                    }
11154                    synchronized (dst) {
11155                        dst.provider = src.provider;
11156                        dst.proc = r;
11157                        dst.notifyAll();
11158                    }
11159                    updateOomAdjLocked(r);
11160                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11161                            src.info.authority);
11162                }
11163            }
11164
11165            Binder.restoreCallingIdentity(origId);
11166        }
11167    }
11168
11169    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11170        ContentProviderConnection conn;
11171        try {
11172            conn = (ContentProviderConnection)connection;
11173        } catch (ClassCastException e) {
11174            String msg ="refContentProvider: " + connection
11175                    + " not a ContentProviderConnection";
11176            Slog.w(TAG, msg);
11177            throw new IllegalArgumentException(msg);
11178        }
11179        if (conn == null) {
11180            throw new NullPointerException("connection is null");
11181        }
11182
11183        synchronized (this) {
11184            if (stable > 0) {
11185                conn.numStableIncs += stable;
11186            }
11187            stable = conn.stableCount + stable;
11188            if (stable < 0) {
11189                throw new IllegalStateException("stableCount < 0: " + stable);
11190            }
11191
11192            if (unstable > 0) {
11193                conn.numUnstableIncs += unstable;
11194            }
11195            unstable = conn.unstableCount + unstable;
11196            if (unstable < 0) {
11197                throw new IllegalStateException("unstableCount < 0: " + unstable);
11198            }
11199
11200            if ((stable+unstable) <= 0) {
11201                throw new IllegalStateException("ref counts can't go to zero here: stable="
11202                        + stable + " unstable=" + unstable);
11203            }
11204            conn.stableCount = stable;
11205            conn.unstableCount = unstable;
11206            return !conn.dead;
11207        }
11208    }
11209
11210    public void unstableProviderDied(IBinder connection) {
11211        ContentProviderConnection conn;
11212        try {
11213            conn = (ContentProviderConnection)connection;
11214        } catch (ClassCastException e) {
11215            String msg ="refContentProvider: " + connection
11216                    + " not a ContentProviderConnection";
11217            Slog.w(TAG, msg);
11218            throw new IllegalArgumentException(msg);
11219        }
11220        if (conn == null) {
11221            throw new NullPointerException("connection is null");
11222        }
11223
11224        // Safely retrieve the content provider associated with the connection.
11225        IContentProvider provider;
11226        synchronized (this) {
11227            provider = conn.provider.provider;
11228        }
11229
11230        if (provider == null) {
11231            // Um, yeah, we're way ahead of you.
11232            return;
11233        }
11234
11235        // Make sure the caller is being honest with us.
11236        if (provider.asBinder().pingBinder()) {
11237            // Er, no, still looks good to us.
11238            synchronized (this) {
11239                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11240                        + " says " + conn + " died, but we don't agree");
11241                return;
11242            }
11243        }
11244
11245        // Well look at that!  It's dead!
11246        synchronized (this) {
11247            if (conn.provider.provider != provider) {
11248                // But something changed...  good enough.
11249                return;
11250            }
11251
11252            ProcessRecord proc = conn.provider.proc;
11253            if (proc == null || proc.thread == null) {
11254                // Seems like the process is already cleaned up.
11255                return;
11256            }
11257
11258            // As far as we're concerned, this is just like receiving a
11259            // death notification...  just a bit prematurely.
11260            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11261                    + ") early provider death");
11262            final long ident = Binder.clearCallingIdentity();
11263            try {
11264                appDiedLocked(proc);
11265            } finally {
11266                Binder.restoreCallingIdentity(ident);
11267            }
11268        }
11269    }
11270
11271    @Override
11272    public void appNotRespondingViaProvider(IBinder connection) {
11273        enforceCallingPermission(
11274                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11275
11276        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11277        if (conn == null) {
11278            Slog.w(TAG, "ContentProviderConnection is null");
11279            return;
11280        }
11281
11282        final ProcessRecord host = conn.provider.proc;
11283        if (host == null) {
11284            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11285            return;
11286        }
11287
11288        mHandler.post(new Runnable() {
11289            @Override
11290            public void run() {
11291                mAppErrors.appNotResponding(host, null, null, false,
11292                        "ContentProvider not responding");
11293            }
11294        });
11295    }
11296
11297    public final void installSystemProviders() {
11298        List<ProviderInfo> providers;
11299        synchronized (this) {
11300            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11301            providers = generateApplicationProvidersLocked(app);
11302            if (providers != null) {
11303                for (int i=providers.size()-1; i>=0; i--) {
11304                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11305                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11306                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11307                                + ": not system .apk");
11308                        providers.remove(i);
11309                    }
11310                }
11311            }
11312        }
11313        if (providers != null) {
11314            mSystemThread.installSystemProviders(providers);
11315        }
11316
11317        mCoreSettingsObserver = new CoreSettingsObserver(this);
11318        mFontScaleSettingObserver = new FontScaleSettingObserver();
11319
11320        //mUsageStatsService.monitorPackages();
11321    }
11322
11323    private void startPersistentApps(int matchFlags) {
11324        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11325
11326        synchronized (this) {
11327            try {
11328                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11329                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11330                for (ApplicationInfo app : apps) {
11331                    if (!"android".equals(app.packageName)) {
11332                        addAppLocked(app, false, null /* ABI override */);
11333                    }
11334                }
11335            } catch (RemoteException ex) {
11336            }
11337        }
11338    }
11339
11340    /**
11341     * When a user is unlocked, we need to install encryption-unaware providers
11342     * belonging to any running apps.
11343     */
11344    private void installEncryptionUnawareProviders(int userId) {
11345        // We're only interested in providers that are encryption unaware, and
11346        // we don't care about uninstalled apps, since there's no way they're
11347        // running at this point.
11348        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11349
11350        synchronized (this) {
11351            final int NP = mProcessNames.getMap().size();
11352            for (int ip = 0; ip < NP; ip++) {
11353                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11354                final int NA = apps.size();
11355                for (int ia = 0; ia < NA; ia++) {
11356                    final ProcessRecord app = apps.valueAt(ia);
11357                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11358
11359                    final int NG = app.pkgList.size();
11360                    for (int ig = 0; ig < NG; ig++) {
11361                        try {
11362                            final String pkgName = app.pkgList.keyAt(ig);
11363                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11364                                    .getPackageInfo(pkgName, matchFlags, userId);
11365                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11366                                for (ProviderInfo pi : pkgInfo.providers) {
11367                                    // TODO: keep in sync with generateApplicationProvidersLocked
11368                                    final boolean processMatch = Objects.equals(pi.processName,
11369                                            app.processName) || pi.multiprocess;
11370                                    final boolean userMatch = isSingleton(pi.processName,
11371                                            pi.applicationInfo, pi.name, pi.flags)
11372                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11373                                    if (processMatch && userMatch) {
11374                                        Log.v(TAG, "Installing " + pi);
11375                                        app.thread.scheduleInstallProvider(pi);
11376                                    } else {
11377                                        Log.v(TAG, "Skipping " + pi);
11378                                    }
11379                                }
11380                            }
11381                        } catch (RemoteException ignored) {
11382                        }
11383                    }
11384                }
11385            }
11386        }
11387    }
11388
11389    /**
11390     * Allows apps to retrieve the MIME type of a URI.
11391     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11392     * users, then it does not need permission to access the ContentProvider.
11393     * Either, it needs cross-user uri grants.
11394     *
11395     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11396     *
11397     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11398     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11399     */
11400    public String getProviderMimeType(Uri uri, int userId) {
11401        enforceNotIsolatedCaller("getProviderMimeType");
11402        final String name = uri.getAuthority();
11403        int callingUid = Binder.getCallingUid();
11404        int callingPid = Binder.getCallingPid();
11405        long ident = 0;
11406        boolean clearedIdentity = false;
11407        synchronized (this) {
11408            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11409        }
11410        if (canClearIdentity(callingPid, callingUid, userId)) {
11411            clearedIdentity = true;
11412            ident = Binder.clearCallingIdentity();
11413        }
11414        ContentProviderHolder holder = null;
11415        try {
11416            holder = getContentProviderExternalUnchecked(name, null, userId);
11417            if (holder != null) {
11418                return holder.provider.getType(uri);
11419            }
11420        } catch (RemoteException e) {
11421            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11422            return null;
11423        } catch (Exception e) {
11424            Log.w(TAG, "Exception while determining type of " + uri, e);
11425            return null;
11426        } finally {
11427            // We need to clear the identity to call removeContentProviderExternalUnchecked
11428            if (!clearedIdentity) {
11429                ident = Binder.clearCallingIdentity();
11430            }
11431            try {
11432                if (holder != null) {
11433                    removeContentProviderExternalUnchecked(name, null, userId);
11434                }
11435            } finally {
11436                Binder.restoreCallingIdentity(ident);
11437            }
11438        }
11439
11440        return null;
11441    }
11442
11443    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11444        if (UserHandle.getUserId(callingUid) == userId) {
11445            return true;
11446        }
11447        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11448                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11449                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11450                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11451                return true;
11452        }
11453        return false;
11454    }
11455
11456    // =========================================================
11457    // GLOBAL MANAGEMENT
11458    // =========================================================
11459
11460    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11461            boolean isolated, int isolatedUid) {
11462        String proc = customProcess != null ? customProcess : info.processName;
11463        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11464        final int userId = UserHandle.getUserId(info.uid);
11465        int uid = info.uid;
11466        if (isolated) {
11467            if (isolatedUid == 0) {
11468                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11469                while (true) {
11470                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11471                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11472                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11473                    }
11474                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11475                    mNextIsolatedProcessUid++;
11476                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11477                        // No process for this uid, use it.
11478                        break;
11479                    }
11480                    stepsLeft--;
11481                    if (stepsLeft <= 0) {
11482                        return null;
11483                    }
11484                }
11485            } else {
11486                // Special case for startIsolatedProcess (internal only), where
11487                // the uid of the isolated process is specified by the caller.
11488                uid = isolatedUid;
11489            }
11490
11491            // Register the isolated UID with this application so BatteryStats knows to
11492            // attribute resource usage to the application.
11493            //
11494            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11495            // about the process state of the isolated UID *before* it is registered with the
11496            // owning application.
11497            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11498        }
11499        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11500        if (!mBooted && !mBooting
11501                && userId == UserHandle.USER_SYSTEM
11502                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11503            r.persistent = true;
11504            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11505        }
11506        addProcessNameLocked(r);
11507        return r;
11508    }
11509
11510    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11511            String abiOverride) {
11512        ProcessRecord app;
11513        if (!isolated) {
11514            app = getProcessRecordLocked(info.processName, info.uid, true);
11515        } else {
11516            app = null;
11517        }
11518
11519        if (app == null) {
11520            app = newProcessRecordLocked(info, null, isolated, 0);
11521            updateLruProcessLocked(app, false, null);
11522            updateOomAdjLocked();
11523        }
11524
11525        // This package really, really can not be stopped.
11526        try {
11527            AppGlobals.getPackageManager().setPackageStoppedState(
11528                    info.packageName, false, UserHandle.getUserId(app.uid));
11529        } catch (RemoteException e) {
11530        } catch (IllegalArgumentException e) {
11531            Slog.w(TAG, "Failed trying to unstop package "
11532                    + info.packageName + ": " + e);
11533        }
11534
11535        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11536            app.persistent = true;
11537            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11538        }
11539        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11540            mPersistentStartingProcesses.add(app);
11541            startProcessLocked(app, "added application", app.processName, abiOverride,
11542                    null /* entryPoint */, null /* entryPointArgs */);
11543        }
11544
11545        return app;
11546    }
11547
11548    public void unhandledBack() {
11549        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11550                "unhandledBack()");
11551
11552        synchronized(this) {
11553            final long origId = Binder.clearCallingIdentity();
11554            try {
11555                getFocusedStack().unhandledBackLocked();
11556            } finally {
11557                Binder.restoreCallingIdentity(origId);
11558            }
11559        }
11560    }
11561
11562    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
11563        enforceNotIsolatedCaller("openContentUri");
11564        final int userId = UserHandle.getCallingUserId();
11565        final Uri uri = Uri.parse(uriString);
11566        String name = uri.getAuthority();
11567        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11568        ParcelFileDescriptor pfd = null;
11569        if (cph != null) {
11570            // We record the binder invoker's uid in thread-local storage before
11571            // going to the content provider to open the file.  Later, in the code
11572            // that handles all permissions checks, we look for this uid and use
11573            // that rather than the Activity Manager's own uid.  The effect is that
11574            // we do the check against the caller's permissions even though it looks
11575            // to the content provider like the Activity Manager itself is making
11576            // the request.
11577            Binder token = new Binder();
11578            sCallerIdentity.set(new Identity(
11579                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11580            try {
11581                pfd = cph.provider.openFile(null, uri, "r", null, token);
11582            } catch (FileNotFoundException e) {
11583                // do nothing; pfd will be returned null
11584            } finally {
11585                // Ensure that whatever happens, we clean up the identity state
11586                sCallerIdentity.remove();
11587                // Ensure we're done with the provider.
11588                removeContentProviderExternalUnchecked(name, null, userId);
11589            }
11590        } else {
11591            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11592        }
11593        return pfd;
11594    }
11595
11596    // Actually is sleeping or shutting down or whatever else in the future
11597    // is an inactive state.
11598    boolean isSleepingOrShuttingDownLocked() {
11599        return isSleepingLocked() || mShuttingDown;
11600    }
11601
11602    boolean isShuttingDownLocked() {
11603        return mShuttingDown;
11604    }
11605
11606    boolean isSleepingLocked() {
11607        return mSleeping;
11608    }
11609
11610    void onWakefulnessChanged(int wakefulness) {
11611        synchronized(this) {
11612            mWakefulness = wakefulness;
11613            updateSleepIfNeededLocked();
11614        }
11615    }
11616
11617    void finishRunningVoiceLocked() {
11618        if (mRunningVoice != null) {
11619            mRunningVoice = null;
11620            mVoiceWakeLock.release();
11621            updateSleepIfNeededLocked();
11622        }
11623    }
11624
11625    void startTimeTrackingFocusedActivityLocked() {
11626        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
11627        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
11628            mCurAppTimeTracker.start(resumedActivity.packageName);
11629        }
11630    }
11631
11632    void updateSleepIfNeededLocked() {
11633        if (mSleeping && !shouldSleepLocked()) {
11634            mSleeping = false;
11635            startTimeTrackingFocusedActivityLocked();
11636            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11637            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11638            updateOomAdjLocked();
11639        } else if (!mSleeping && shouldSleepLocked()) {
11640            mSleeping = true;
11641            if (mCurAppTimeTracker != null) {
11642                mCurAppTimeTracker.stop();
11643            }
11644            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11645            mStackSupervisor.goingToSleepLocked();
11646            updateOomAdjLocked();
11647
11648            // Initialize the wake times of all processes.
11649            checkExcessivePowerUsageLocked(false);
11650            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11651            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11652            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11653        }
11654    }
11655
11656    private boolean shouldSleepLocked() {
11657        // Resume applications while running a voice interactor.
11658        if (mRunningVoice != null) {
11659            return false;
11660        }
11661
11662        // TODO: Transform the lock screen state into a sleep token instead.
11663        switch (mWakefulness) {
11664            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11665            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11666            case PowerManagerInternal.WAKEFULNESS_DOZING:
11667                // Pause applications whenever the lock screen is shown or any sleep
11668                // tokens have been acquired.
11669                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
11670            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11671            default:
11672                // If we're asleep then pause applications unconditionally.
11673                return true;
11674        }
11675    }
11676
11677    /** Pokes the task persister. */
11678    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11679        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11680    }
11681
11682    /** Notifies all listeners when the pinned stack animation ends. */
11683    @Override
11684    public void notifyPinnedStackAnimationEnded() {
11685        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
11686    }
11687
11688    @Override
11689    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11690        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11691    }
11692
11693    @Override
11694    public boolean shutdown(int timeout) {
11695        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11696                != PackageManager.PERMISSION_GRANTED) {
11697            throw new SecurityException("Requires permission "
11698                    + android.Manifest.permission.SHUTDOWN);
11699        }
11700
11701        boolean timedout = false;
11702
11703        synchronized(this) {
11704            mShuttingDown = true;
11705            updateEventDispatchingLocked();
11706            timedout = mStackSupervisor.shutdownLocked(timeout);
11707        }
11708
11709        mAppOpsService.shutdown();
11710        if (mUsageStatsService != null) {
11711            mUsageStatsService.prepareShutdown();
11712        }
11713        mBatteryStatsService.shutdown();
11714        synchronized (this) {
11715            mProcessStats.shutdownLocked();
11716            notifyTaskPersisterLocked(null, true);
11717        }
11718
11719        return timedout;
11720    }
11721
11722    public final void activitySlept(IBinder token) {
11723        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11724
11725        final long origId = Binder.clearCallingIdentity();
11726
11727        synchronized (this) {
11728            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11729            if (r != null) {
11730                mStackSupervisor.activitySleptLocked(r);
11731            }
11732        }
11733
11734        Binder.restoreCallingIdentity(origId);
11735    }
11736
11737    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11738        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11739        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11740        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11741            boolean wasRunningVoice = mRunningVoice != null;
11742            mRunningVoice = session;
11743            if (!wasRunningVoice) {
11744                mVoiceWakeLock.acquire();
11745                updateSleepIfNeededLocked();
11746            }
11747        }
11748    }
11749
11750    private void updateEventDispatchingLocked() {
11751        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11752    }
11753
11754    @Override
11755    public void setLockScreenShown(boolean showing) {
11756        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11757                != PackageManager.PERMISSION_GRANTED) {
11758            throw new SecurityException("Requires permission "
11759                    + android.Manifest.permission.DEVICE_POWER);
11760        }
11761
11762        synchronized(this) {
11763            long ident = Binder.clearCallingIdentity();
11764            try {
11765                mKeyguardController.setKeyguardShown(showing);
11766            } finally {
11767                Binder.restoreCallingIdentity(ident);
11768            }
11769        }
11770    }
11771
11772    @Override
11773    public void notifyLockedProfile(@UserIdInt int userId) {
11774        try {
11775            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11776                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11777            }
11778        } catch (RemoteException ex) {
11779            throw new SecurityException("Fail to check is caller a privileged app", ex);
11780        }
11781
11782        synchronized (this) {
11783            if (mStackSupervisor.isUserLockedProfile(userId)) {
11784                final long ident = Binder.clearCallingIdentity();
11785                try {
11786                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11787                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11788                        // If there is no device lock, we will show the profile's credential page.
11789                        mActivityStarter.showConfirmDeviceCredential(userId);
11790                    } else {
11791                        // Showing launcher to avoid user entering credential twice.
11792                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11793                    }
11794                } finally {
11795                    Binder.restoreCallingIdentity(ident);
11796                }
11797            }
11798        }
11799    }
11800
11801    @Override
11802    public void startConfirmDeviceCredentialIntent(Intent intent) {
11803        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11804        synchronized (this) {
11805            final long ident = Binder.clearCallingIdentity();
11806            try {
11807                mActivityStarter.startConfirmCredentialIntent(intent);
11808            } finally {
11809                Binder.restoreCallingIdentity(ident);
11810            }
11811        }
11812    }
11813
11814    @Override
11815    public void stopAppSwitches() {
11816        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11817                != PackageManager.PERMISSION_GRANTED) {
11818            throw new SecurityException("viewquires permission "
11819                    + android.Manifest.permission.STOP_APP_SWITCHES);
11820        }
11821
11822        synchronized(this) {
11823            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11824                    + APP_SWITCH_DELAY_TIME;
11825            mDidAppSwitch = false;
11826            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11827            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11828            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11829        }
11830    }
11831
11832    public void resumeAppSwitches() {
11833        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11834                != PackageManager.PERMISSION_GRANTED) {
11835            throw new SecurityException("Requires permission "
11836                    + android.Manifest.permission.STOP_APP_SWITCHES);
11837        }
11838
11839        synchronized(this) {
11840            // Note that we don't execute any pending app switches... we will
11841            // let those wait until either the timeout, or the next start
11842            // activity request.
11843            mAppSwitchesAllowedTime = 0;
11844        }
11845    }
11846
11847    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11848            int callingPid, int callingUid, String name) {
11849        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11850            return true;
11851        }
11852
11853        int perm = checkComponentPermission(
11854                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11855                sourceUid, -1, true);
11856        if (perm == PackageManager.PERMISSION_GRANTED) {
11857            return true;
11858        }
11859
11860        // If the actual IPC caller is different from the logical source, then
11861        // also see if they are allowed to control app switches.
11862        if (callingUid != -1 && callingUid != sourceUid) {
11863            perm = checkComponentPermission(
11864                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11865                    callingUid, -1, true);
11866            if (perm == PackageManager.PERMISSION_GRANTED) {
11867                return true;
11868            }
11869        }
11870
11871        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11872        return false;
11873    }
11874
11875    public void setDebugApp(String packageName, boolean waitForDebugger,
11876            boolean persistent) {
11877        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11878                "setDebugApp()");
11879
11880        long ident = Binder.clearCallingIdentity();
11881        try {
11882            // Note that this is not really thread safe if there are multiple
11883            // callers into it at the same time, but that's not a situation we
11884            // care about.
11885            if (persistent) {
11886                final ContentResolver resolver = mContext.getContentResolver();
11887                Settings.Global.putString(
11888                    resolver, Settings.Global.DEBUG_APP,
11889                    packageName);
11890                Settings.Global.putInt(
11891                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11892                    waitForDebugger ? 1 : 0);
11893            }
11894
11895            synchronized (this) {
11896                if (!persistent) {
11897                    mOrigDebugApp = mDebugApp;
11898                    mOrigWaitForDebugger = mWaitForDebugger;
11899                }
11900                mDebugApp = packageName;
11901                mWaitForDebugger = waitForDebugger;
11902                mDebugTransient = !persistent;
11903                if (packageName != null) {
11904                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11905                            false, UserHandle.USER_ALL, "set debug app");
11906                }
11907            }
11908        } finally {
11909            Binder.restoreCallingIdentity(ident);
11910        }
11911    }
11912
11913    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11914        synchronized (this) {
11915            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11916            if (!isDebuggable) {
11917                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11918                    throw new SecurityException("Process not debuggable: " + app.packageName);
11919                }
11920            }
11921
11922            mTrackAllocationApp = processName;
11923        }
11924    }
11925
11926    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11927        synchronized (this) {
11928            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11929            if (!isDebuggable) {
11930                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11931                    throw new SecurityException("Process not debuggable: " + app.packageName);
11932                }
11933            }
11934            mProfileApp = processName;
11935            mProfileFile = profilerInfo.profileFile;
11936            if (mProfileFd != null) {
11937                try {
11938                    mProfileFd.close();
11939                } catch (IOException e) {
11940                }
11941                mProfileFd = null;
11942            }
11943            mProfileFd = profilerInfo.profileFd;
11944            mSamplingInterval = profilerInfo.samplingInterval;
11945            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11946            mProfileType = 0;
11947        }
11948    }
11949
11950    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11951        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11952        if (!isDebuggable) {
11953            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11954                throw new SecurityException("Process not debuggable: " + app.packageName);
11955            }
11956        }
11957        mNativeDebuggingApp = processName;
11958    }
11959
11960    @Override
11961    public void setAlwaysFinish(boolean enabled) {
11962        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11963                "setAlwaysFinish()");
11964
11965        long ident = Binder.clearCallingIdentity();
11966        try {
11967            Settings.Global.putInt(
11968                    mContext.getContentResolver(),
11969                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11970
11971            synchronized (this) {
11972                mAlwaysFinishActivities = enabled;
11973            }
11974        } finally {
11975            Binder.restoreCallingIdentity(ident);
11976        }
11977    }
11978
11979    @Override
11980    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11981        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11982                "setActivityController()");
11983        synchronized (this) {
11984            mController = controller;
11985            mControllerIsAMonkey = imAMonkey;
11986            Watchdog.getInstance().setActivityController(controller);
11987        }
11988    }
11989
11990    @Override
11991    public void setUserIsMonkey(boolean userIsMonkey) {
11992        synchronized (this) {
11993            synchronized (mPidsSelfLocked) {
11994                final int callingPid = Binder.getCallingPid();
11995                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11996                if (precessRecord == null) {
11997                    throw new SecurityException("Unknown process: " + callingPid);
11998                }
11999                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12000                    throw new SecurityException("Only an instrumentation process "
12001                            + "with a UiAutomation can call setUserIsMonkey");
12002                }
12003            }
12004            mUserIsMonkey = userIsMonkey;
12005        }
12006    }
12007
12008    @Override
12009    public boolean isUserAMonkey() {
12010        synchronized (this) {
12011            // If there is a controller also implies the user is a monkey.
12012            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12013        }
12014    }
12015
12016    public void requestBugReport(int bugreportType) {
12017        String extraOptions = null;
12018        switch (bugreportType) {
12019            case ActivityManager.BUGREPORT_OPTION_FULL:
12020                // Default options.
12021                break;
12022            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12023                extraOptions = "bugreportplus";
12024                break;
12025            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12026                extraOptions = "bugreportremote";
12027                break;
12028            case ActivityManager.BUGREPORT_OPTION_WEAR:
12029                extraOptions = "bugreportwear";
12030                break;
12031            default:
12032                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12033                        + bugreportType);
12034        }
12035        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12036        if (extraOptions != null) {
12037            SystemProperties.set("dumpstate.options", extraOptions);
12038        }
12039        SystemProperties.set("ctl.start", "bugreport");
12040    }
12041
12042    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12043        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12044    }
12045
12046    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12047        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12048            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12049        }
12050        return KEY_DISPATCHING_TIMEOUT;
12051    }
12052
12053    @Override
12054    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12055        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12056                != PackageManager.PERMISSION_GRANTED) {
12057            throw new SecurityException("Requires permission "
12058                    + android.Manifest.permission.FILTER_EVENTS);
12059        }
12060        ProcessRecord proc;
12061        long timeout;
12062        synchronized (this) {
12063            synchronized (mPidsSelfLocked) {
12064                proc = mPidsSelfLocked.get(pid);
12065            }
12066            timeout = getInputDispatchingTimeoutLocked(proc);
12067        }
12068
12069        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12070            return -1;
12071        }
12072
12073        return timeout;
12074    }
12075
12076    /**
12077     * Handle input dispatching timeouts.
12078     * Returns whether input dispatching should be aborted or not.
12079     */
12080    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12081            final ActivityRecord activity, final ActivityRecord parent,
12082            final boolean aboveSystem, String reason) {
12083        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12084                != PackageManager.PERMISSION_GRANTED) {
12085            throw new SecurityException("Requires permission "
12086                    + android.Manifest.permission.FILTER_EVENTS);
12087        }
12088
12089        final String annotation;
12090        if (reason == null) {
12091            annotation = "Input dispatching timed out";
12092        } else {
12093            annotation = "Input dispatching timed out (" + reason + ")";
12094        }
12095
12096        if (proc != null) {
12097            synchronized (this) {
12098                if (proc.debugging) {
12099                    return false;
12100                }
12101
12102                if (mDidDexOpt) {
12103                    // Give more time since we were dexopting.
12104                    mDidDexOpt = false;
12105                    return false;
12106                }
12107
12108                if (proc.instrumentationClass != null) {
12109                    Bundle info = new Bundle();
12110                    info.putString("shortMsg", "keyDispatchingTimedOut");
12111                    info.putString("longMsg", annotation);
12112                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12113                    return true;
12114                }
12115            }
12116            mHandler.post(new Runnable() {
12117                @Override
12118                public void run() {
12119                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12120                }
12121            });
12122        }
12123
12124        return true;
12125    }
12126
12127    @Override
12128    public Bundle getAssistContextExtras(int requestType) {
12129        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12130                null, null, true /* focused */, true /* newSessionId */,
12131                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12132        if (pae == null) {
12133            return null;
12134        }
12135        synchronized (pae) {
12136            while (!pae.haveResult) {
12137                try {
12138                    pae.wait();
12139                } catch (InterruptedException e) {
12140                }
12141            }
12142        }
12143        synchronized (this) {
12144            buildAssistBundleLocked(pae, pae.result);
12145            mPendingAssistExtras.remove(pae);
12146            mUiHandler.removeCallbacks(pae);
12147        }
12148        return pae.extras;
12149    }
12150
12151    @Override
12152    public boolean isAssistDataAllowedOnCurrentActivity() {
12153        int userId;
12154        synchronized (this) {
12155            userId = mUserController.getCurrentUserIdLocked();
12156            ActivityRecord activity = getFocusedStack().topActivity();
12157            if (activity == null) {
12158                return false;
12159            }
12160            userId = activity.userId;
12161        }
12162        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12163                Context.DEVICE_POLICY_SERVICE);
12164        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12165    }
12166
12167    @Override
12168    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12169        long ident = Binder.clearCallingIdentity();
12170        try {
12171            synchronized (this) {
12172                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12173                ActivityRecord top = getFocusedStack().topActivity();
12174                if (top != caller) {
12175                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12176                            + " is not current top " + top);
12177                    return false;
12178                }
12179                if (!top.nowVisible) {
12180                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12181                            + " is not visible");
12182                    return false;
12183                }
12184            }
12185            AssistUtils utils = new AssistUtils(mContext);
12186            return utils.showSessionForActiveService(args,
12187                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12188        } finally {
12189            Binder.restoreCallingIdentity(ident);
12190        }
12191    }
12192
12193    @Override
12194    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12195            Bundle receiverExtras,
12196            IBinder activityToken, boolean focused, boolean newSessionId) {
12197        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12198                activityToken, focused, newSessionId,
12199                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12200                != null;
12201    }
12202
12203    @Override
12204    public boolean requestAutoFillData(IResultReceiver receiver, Bundle receiverExtras,
12205            IBinder activityToken) {
12206        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null, receiver,
12207                receiverExtras, activityToken, true, true,
12208                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12209                != null;
12210    }
12211
12212    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12213            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12214            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12215        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12216                "enqueueAssistContext()");
12217        synchronized (this) {
12218            ActivityRecord activity = getFocusedStack().topActivity();
12219            if (activity == null) {
12220                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12221                return null;
12222            }
12223            if (activity.app == null || activity.app.thread == null) {
12224                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12225                return null;
12226            }
12227            if (focused) {
12228                if (activityToken != null) {
12229                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12230                    if (activity != caller) {
12231                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12232                                + " is not current top " + activity);
12233                        return null;
12234                    }
12235                }
12236            } else {
12237                activity = ActivityRecord.forTokenLocked(activityToken);
12238                if (activity == null) {
12239                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12240                            + " couldn't be found");
12241                    return null;
12242                }
12243            }
12244
12245            PendingAssistExtras pae;
12246            Bundle extras = new Bundle();
12247            if (args != null) {
12248                extras.putAll(args);
12249            }
12250            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12251            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12252            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12253                    userHandle);
12254            // Increment the sessionId if necessary
12255            if (newSessionId) {
12256                mViSessionId++;
12257            }
12258            try {
12259                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12260                        requestType, mViSessionId);
12261                mPendingAssistExtras.add(pae);
12262                mUiHandler.postDelayed(pae, timeout);
12263            } catch (RemoteException e) {
12264                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12265                return null;
12266            }
12267            return pae;
12268        }
12269    }
12270
12271    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12272        IResultReceiver receiver;
12273        synchronized (this) {
12274            mPendingAssistExtras.remove(pae);
12275            receiver = pae.receiver;
12276        }
12277        if (receiver != null) {
12278            // Caller wants result sent back to them.
12279            Bundle sendBundle = new Bundle();
12280            // At least return the receiver extras
12281            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12282                    pae.receiverExtras);
12283            try {
12284                pae.receiver.send(0, sendBundle);
12285            } catch (RemoteException e) {
12286            }
12287        }
12288    }
12289
12290    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12291        if (result != null) {
12292            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12293        }
12294        if (pae.hint != null) {
12295            pae.extras.putBoolean(pae.hint, true);
12296        }
12297    }
12298
12299    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12300            AssistContent content, Uri referrer) {
12301        PendingAssistExtras pae = (PendingAssistExtras)token;
12302        synchronized (pae) {
12303            pae.result = extras;
12304            pae.structure = structure;
12305            pae.content = content;
12306            if (referrer != null) {
12307                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12308            }
12309            pae.haveResult = true;
12310            pae.notifyAll();
12311            if (pae.intent == null && pae.receiver == null) {
12312                // Caller is just waiting for the result.
12313                return;
12314            }
12315        }
12316
12317        // We are now ready to launch the assist activity.
12318        IResultReceiver sendReceiver = null;
12319        Bundle sendBundle = null;
12320        synchronized (this) {
12321            buildAssistBundleLocked(pae, extras);
12322            boolean exists = mPendingAssistExtras.remove(pae);
12323            mUiHandler.removeCallbacks(pae);
12324            if (!exists) {
12325                // Timed out.
12326                return;
12327            }
12328            if ((sendReceiver=pae.receiver) != null) {
12329                // Caller wants result sent back to them.
12330                sendBundle = new Bundle();
12331                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12332                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12333                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12334                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12335                        pae.receiverExtras);
12336                IBinder autoFillCallback =
12337                        extras.getBinder(VoiceInteractionSession.KEY_AUTO_FILL_CALLBACK);
12338                if (autoFillCallback != null) {
12339                    sendBundle.putBinder(VoiceInteractionSession.KEY_AUTO_FILL_CALLBACK,
12340                            autoFillCallback);
12341                }
12342            }
12343        }
12344        if (sendReceiver != null) {
12345            try {
12346                sendReceiver.send(0, sendBundle);
12347            } catch (RemoteException e) {
12348            }
12349            return;
12350        }
12351
12352        long ident = Binder.clearCallingIdentity();
12353        try {
12354            pae.intent.replaceExtras(pae.extras);
12355            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12356                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12357                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12358            closeSystemDialogs("assist");
12359            try {
12360                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12361            } catch (ActivityNotFoundException e) {
12362                Slog.w(TAG, "No activity to handle assist action.", e);
12363            }
12364        } finally {
12365            Binder.restoreCallingIdentity(ident);
12366        }
12367    }
12368
12369    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12370            Bundle args) {
12371        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12372                true /* focused */, true /* newSessionId */,
12373                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12374    }
12375
12376    public void registerProcessObserver(IProcessObserver observer) {
12377        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12378                "registerProcessObserver()");
12379        synchronized (this) {
12380            mProcessObservers.register(observer);
12381        }
12382    }
12383
12384    @Override
12385    public void unregisterProcessObserver(IProcessObserver observer) {
12386        synchronized (this) {
12387            mProcessObservers.unregister(observer);
12388        }
12389    }
12390
12391    @Override
12392    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
12393            String callingPackage) {
12394        if (!hasUsageStatsPermission(callingPackage)) {
12395            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
12396                    "registerUidObserver");
12397        }
12398        synchronized (this) {
12399            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
12400                    callingPackage, which, cutpoint));
12401        }
12402    }
12403
12404    @Override
12405    public void unregisterUidObserver(IUidObserver observer) {
12406        synchronized (this) {
12407            mUidObservers.unregister(observer);
12408        }
12409    }
12410
12411    @Override
12412    public boolean convertFromTranslucent(IBinder token) {
12413        final long origId = Binder.clearCallingIdentity();
12414        try {
12415            synchronized (this) {
12416                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12417                if (r == null) {
12418                    return false;
12419                }
12420                final boolean translucentChanged = r.changeWindowTranslucency(true);
12421                if (translucentChanged) {
12422                    r.getStack().releaseBackgroundResources(r);
12423                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12424                }
12425                mWindowManager.setAppFullscreen(token, true);
12426                return translucentChanged;
12427            }
12428        } finally {
12429            Binder.restoreCallingIdentity(origId);
12430        }
12431    }
12432
12433    @Override
12434    public boolean convertToTranslucent(IBinder token, Bundle options) {
12435        final long origId = Binder.clearCallingIdentity();
12436        try {
12437            synchronized (this) {
12438                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12439                if (r == null) {
12440                    return false;
12441                }
12442                int index = r.task.mActivities.lastIndexOf(r);
12443                if (index > 0) {
12444                    ActivityRecord under = r.task.mActivities.get(index - 1);
12445                    under.returningOptions = ActivityOptions.fromBundle(options);
12446                }
12447                final boolean translucentChanged = r.changeWindowTranslucency(false);
12448                if (translucentChanged) {
12449                    r.getStack().convertActivityToTranslucent(r);
12450                }
12451                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12452                mWindowManager.setAppFullscreen(token, false);
12453                return translucentChanged;
12454            }
12455        } finally {
12456            Binder.restoreCallingIdentity(origId);
12457        }
12458    }
12459
12460    @Override
12461    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12462        final long origId = Binder.clearCallingIdentity();
12463        try {
12464            synchronized (this) {
12465                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12466                if (r != null) {
12467                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12468                }
12469            }
12470            return false;
12471        } finally {
12472            Binder.restoreCallingIdentity(origId);
12473        }
12474    }
12475
12476    @Override
12477    public boolean isBackgroundVisibleBehind(IBinder token) {
12478        final long origId = Binder.clearCallingIdentity();
12479        try {
12480            synchronized (this) {
12481                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12482                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12483                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12484                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12485                return visible;
12486            }
12487        } finally {
12488            Binder.restoreCallingIdentity(origId);
12489        }
12490    }
12491
12492    @Override
12493    public Bundle getActivityOptions(IBinder token) {
12494        final long origId = Binder.clearCallingIdentity();
12495        try {
12496            synchronized (this) {
12497                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12498                if (r != null) {
12499                    final ActivityOptions activityOptions = r.pendingOptions;
12500                    r.pendingOptions = null;
12501                    return activityOptions == null ? null : activityOptions.toBundle();
12502                }
12503                return null;
12504            }
12505        } finally {
12506            Binder.restoreCallingIdentity(origId);
12507        }
12508    }
12509
12510    @Override
12511    public void setImmersive(IBinder token, boolean immersive) {
12512        synchronized(this) {
12513            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12514            if (r == null) {
12515                throw new IllegalArgumentException();
12516            }
12517            r.immersive = immersive;
12518
12519            // update associated state if we're frontmost
12520            if (r == mStackSupervisor.getResumedActivityLocked()) {
12521                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12522                applyUpdateLockStateLocked(r);
12523            }
12524        }
12525    }
12526
12527    @Override
12528    public boolean isImmersive(IBinder token) {
12529        synchronized (this) {
12530            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12531            if (r == null) {
12532                throw new IllegalArgumentException();
12533            }
12534            return r.immersive;
12535        }
12536    }
12537
12538    public void setVrThread(int tid) {
12539        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12540            throw new UnsupportedOperationException("VR mode not supported on this device!");
12541        }
12542
12543        synchronized (this) {
12544            ProcessRecord proc;
12545            synchronized (mPidsSelfLocked) {
12546                final int pid = Binder.getCallingPid();
12547                proc = mPidsSelfLocked.get(pid);
12548
12549                if (proc != null && mInVrMode && tid >= 0) {
12550                    // ensure the tid belongs to the process
12551                    if (!Process.isThreadInProcess(pid, tid)) {
12552                        throw new IllegalArgumentException("VR thread does not belong to process");
12553                    }
12554
12555                    // reset existing VR thread to CFS if this thread still exists and belongs to
12556                    // the calling process
12557                    if (proc.vrThreadTid != 0
12558                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12559                        try {
12560                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12561                        } catch (IllegalArgumentException e) {
12562                            // Ignore this.  Only occurs in race condition where previous VR thread
12563                            // was destroyed during this method call.
12564                        }
12565                    }
12566
12567                    proc.vrThreadTid = tid;
12568
12569                    // promote to FIFO now if the tid is non-zero
12570                    try {
12571                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12572                            proc.vrThreadTid > 0) {
12573                            Process.setThreadScheduler(proc.vrThreadTid,
12574                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12575                        }
12576                    } catch (IllegalArgumentException e) {
12577                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12578                               + " not exist:\n" + e);
12579                    }
12580                }
12581            }
12582        }
12583    }
12584
12585    @Override
12586    public void setRenderThread(int tid) {
12587        synchronized (this) {
12588            ProcessRecord proc;
12589            synchronized (mPidsSelfLocked) {
12590                int pid = Binder.getCallingPid();
12591                proc = mPidsSelfLocked.get(pid);
12592                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12593                    // ensure the tid belongs to the process
12594                    if (!Process.isThreadInProcess(pid, tid)) {
12595                        throw new IllegalArgumentException(
12596                            "Render thread does not belong to process");
12597                    }
12598                    proc.renderThreadTid = tid;
12599                    if (DEBUG_OOM_ADJ) {
12600                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12601                    }
12602                    // promote to FIFO now
12603                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12604                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12605                        if (mUseFifoUiScheduling) {
12606                            Process.setThreadScheduler(proc.renderThreadTid,
12607                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12608                        } else {
12609                            Process.setThreadPriority(proc.renderThreadTid, -10);
12610                        }
12611                    }
12612                } else {
12613                    if (DEBUG_OOM_ADJ) {
12614                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12615                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12616                               mUseFifoUiScheduling);
12617                    }
12618                }
12619            }
12620        }
12621    }
12622
12623    @Override
12624    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12625        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12626            throw new UnsupportedOperationException("VR mode not supported on this device!");
12627        }
12628
12629        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12630
12631        ActivityRecord r;
12632        synchronized (this) {
12633            r = ActivityRecord.isInStackLocked(token);
12634        }
12635
12636        if (r == null) {
12637            throw new IllegalArgumentException();
12638        }
12639
12640        int err;
12641        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12642                VrManagerInternal.NO_ERROR) {
12643            return err;
12644        }
12645
12646        synchronized(this) {
12647            r.requestedVrComponent = (enabled) ? packageName : null;
12648
12649            // Update associated state if this activity is currently focused
12650            if (r == mStackSupervisor.getResumedActivityLocked()) {
12651                applyUpdateVrModeLocked(r);
12652            }
12653            return 0;
12654        }
12655    }
12656
12657    @Override
12658    public boolean isVrModePackageEnabled(ComponentName packageName) {
12659        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12660            throw new UnsupportedOperationException("VR mode not supported on this device!");
12661        }
12662
12663        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12664
12665        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12666                VrManagerInternal.NO_ERROR;
12667    }
12668
12669    public boolean isTopActivityImmersive() {
12670        enforceNotIsolatedCaller("startActivity");
12671        synchronized (this) {
12672            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12673            return (r != null) ? r.immersive : false;
12674        }
12675    }
12676
12677    @Override
12678    public boolean isTopOfTask(IBinder token) {
12679        synchronized (this) {
12680            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12681            if (r == null) {
12682                throw new IllegalArgumentException();
12683            }
12684            return r.task.getTopActivity() == r;
12685        }
12686    }
12687
12688    @Override
12689    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12690        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12691            String msg = "Permission Denial: setHasTopUi() from pid="
12692                    + Binder.getCallingPid()
12693                    + ", uid=" + Binder.getCallingUid()
12694                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12695            Slog.w(TAG, msg);
12696            throw new SecurityException(msg);
12697        }
12698        final int pid = Binder.getCallingPid();
12699        final long origId = Binder.clearCallingIdentity();
12700        try {
12701            synchronized (this) {
12702                boolean changed = false;
12703                ProcessRecord pr;
12704                synchronized (mPidsSelfLocked) {
12705                    pr = mPidsSelfLocked.get(pid);
12706                    if (pr == null) {
12707                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12708                        return;
12709                    }
12710                    if (pr.hasTopUi != hasTopUi) {
12711                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12712                        pr.hasTopUi = hasTopUi;
12713                        changed = true;
12714                    }
12715                }
12716                if (changed) {
12717                    updateOomAdjLocked(pr);
12718                }
12719            }
12720        } finally {
12721            Binder.restoreCallingIdentity(origId);
12722        }
12723    }
12724
12725    public final void enterSafeMode() {
12726        synchronized(this) {
12727            // It only makes sense to do this before the system is ready
12728            // and started launching other packages.
12729            if (!mSystemReady) {
12730                try {
12731                    AppGlobals.getPackageManager().enterSafeMode();
12732                } catch (RemoteException e) {
12733                }
12734            }
12735
12736            mSafeMode = true;
12737        }
12738    }
12739
12740    public final void showSafeModeOverlay() {
12741        View v = LayoutInflater.from(mContext).inflate(
12742                com.android.internal.R.layout.safe_mode, null);
12743        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12744        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12745        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12746        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12747        lp.gravity = Gravity.BOTTOM | Gravity.START;
12748        lp.format = v.getBackground().getOpacity();
12749        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12750                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12751        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12752        ((WindowManager)mContext.getSystemService(
12753                Context.WINDOW_SERVICE)).addView(v, lp);
12754    }
12755
12756    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12757        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12758            return;
12759        }
12760        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12761        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12762        synchronized (stats) {
12763            if (mBatteryStatsService.isOnBattery()) {
12764                mBatteryStatsService.enforceCallingPermission();
12765                int MY_UID = Binder.getCallingUid();
12766                final int uid;
12767                if (sender == null) {
12768                    uid = sourceUid;
12769                } else {
12770                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12771                }
12772                BatteryStatsImpl.Uid.Pkg pkg =
12773                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12774                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12775                pkg.noteWakeupAlarmLocked(tag);
12776            }
12777        }
12778    }
12779
12780    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12781        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12782            return;
12783        }
12784        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12785        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12786        synchronized (stats) {
12787            mBatteryStatsService.enforceCallingPermission();
12788            int MY_UID = Binder.getCallingUid();
12789            final int uid;
12790            if (sender == null) {
12791                uid = sourceUid;
12792            } else {
12793                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12794            }
12795            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12796        }
12797    }
12798
12799    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12800        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12801            return;
12802        }
12803        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12804        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12805        synchronized (stats) {
12806            mBatteryStatsService.enforceCallingPermission();
12807            int MY_UID = Binder.getCallingUid();
12808            final int uid;
12809            if (sender == null) {
12810                uid = sourceUid;
12811            } else {
12812                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12813            }
12814            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12815        }
12816    }
12817
12818    public boolean killPids(int[] pids, String pReason, boolean secure) {
12819        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12820            throw new SecurityException("killPids only available to the system");
12821        }
12822        String reason = (pReason == null) ? "Unknown" : pReason;
12823        // XXX Note: don't acquire main activity lock here, because the window
12824        // manager calls in with its locks held.
12825
12826        boolean killed = false;
12827        synchronized (mPidsSelfLocked) {
12828            int worstType = 0;
12829            for (int i=0; i<pids.length; i++) {
12830                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12831                if (proc != null) {
12832                    int type = proc.setAdj;
12833                    if (type > worstType) {
12834                        worstType = type;
12835                    }
12836                }
12837            }
12838
12839            // If the worst oom_adj is somewhere in the cached proc LRU range,
12840            // then constrain it so we will kill all cached procs.
12841            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12842                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12843                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12844            }
12845
12846            // If this is not a secure call, don't let it kill processes that
12847            // are important.
12848            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12849                worstType = ProcessList.SERVICE_ADJ;
12850            }
12851
12852            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12853            for (int i=0; i<pids.length; i++) {
12854                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12855                if (proc == null) {
12856                    continue;
12857                }
12858                int adj = proc.setAdj;
12859                if (adj >= worstType && !proc.killedByAm) {
12860                    proc.kill(reason, true);
12861                    killed = true;
12862                }
12863            }
12864        }
12865        return killed;
12866    }
12867
12868    @Override
12869    public void killUid(int appId, int userId, String reason) {
12870        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12871        synchronized (this) {
12872            final long identity = Binder.clearCallingIdentity();
12873            try {
12874                killPackageProcessesLocked(null, appId, userId,
12875                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12876                        reason != null ? reason : "kill uid");
12877            } finally {
12878                Binder.restoreCallingIdentity(identity);
12879            }
12880        }
12881    }
12882
12883    @Override
12884    public boolean killProcessesBelowForeground(String reason) {
12885        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12886            throw new SecurityException("killProcessesBelowForeground() only available to system");
12887        }
12888
12889        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12890    }
12891
12892    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12893        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12894            throw new SecurityException("killProcessesBelowAdj() only available to system");
12895        }
12896
12897        boolean killed = false;
12898        synchronized (mPidsSelfLocked) {
12899            final int size = mPidsSelfLocked.size();
12900            for (int i = 0; i < size; i++) {
12901                final int pid = mPidsSelfLocked.keyAt(i);
12902                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12903                if (proc == null) continue;
12904
12905                final int adj = proc.setAdj;
12906                if (adj > belowAdj && !proc.killedByAm) {
12907                    proc.kill(reason, true);
12908                    killed = true;
12909                }
12910            }
12911        }
12912        return killed;
12913    }
12914
12915    @Override
12916    public void hang(final IBinder who, boolean allowRestart) {
12917        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12918                != PackageManager.PERMISSION_GRANTED) {
12919            throw new SecurityException("Requires permission "
12920                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12921        }
12922
12923        final IBinder.DeathRecipient death = new DeathRecipient() {
12924            @Override
12925            public void binderDied() {
12926                synchronized (this) {
12927                    notifyAll();
12928                }
12929            }
12930        };
12931
12932        try {
12933            who.linkToDeath(death, 0);
12934        } catch (RemoteException e) {
12935            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12936            return;
12937        }
12938
12939        synchronized (this) {
12940            Watchdog.getInstance().setAllowRestart(allowRestart);
12941            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12942            synchronized (death) {
12943                while (who.isBinderAlive()) {
12944                    try {
12945                        death.wait();
12946                    } catch (InterruptedException e) {
12947                    }
12948                }
12949            }
12950            Watchdog.getInstance().setAllowRestart(true);
12951        }
12952    }
12953
12954    @Override
12955    public void restart() {
12956        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12957                != PackageManager.PERMISSION_GRANTED) {
12958            throw new SecurityException("Requires permission "
12959                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12960        }
12961
12962        Log.i(TAG, "Sending shutdown broadcast...");
12963
12964        BroadcastReceiver br = new BroadcastReceiver() {
12965            @Override public void onReceive(Context context, Intent intent) {
12966                // Now the broadcast is done, finish up the low-level shutdown.
12967                Log.i(TAG, "Shutting down activity manager...");
12968                shutdown(10000);
12969                Log.i(TAG, "Shutdown complete, restarting!");
12970                Process.killProcess(Process.myPid());
12971                System.exit(10);
12972            }
12973        };
12974
12975        // First send the high-level shut down broadcast.
12976        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12977        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12978        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12979        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12980        mContext.sendOrderedBroadcastAsUser(intent,
12981                UserHandle.ALL, null, br, mHandler, 0, null, null);
12982        */
12983        br.onReceive(mContext, intent);
12984    }
12985
12986    private long getLowRamTimeSinceIdle(long now) {
12987        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12988    }
12989
12990    @Override
12991    public void performIdleMaintenance() {
12992        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12993                != PackageManager.PERMISSION_GRANTED) {
12994            throw new SecurityException("Requires permission "
12995                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12996        }
12997
12998        synchronized (this) {
12999            final long now = SystemClock.uptimeMillis();
13000            final long timeSinceLastIdle = now - mLastIdleTime;
13001            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13002            mLastIdleTime = now;
13003            mLowRamTimeSinceLastIdle = 0;
13004            if (mLowRamStartTime != 0) {
13005                mLowRamStartTime = now;
13006            }
13007
13008            StringBuilder sb = new StringBuilder(128);
13009            sb.append("Idle maintenance over ");
13010            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13011            sb.append(" low RAM for ");
13012            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13013            Slog.i(TAG, sb.toString());
13014
13015            // If at least 1/3 of our time since the last idle period has been spent
13016            // with RAM low, then we want to kill processes.
13017            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13018
13019            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13020                ProcessRecord proc = mLruProcesses.get(i);
13021                if (proc.notCachedSinceIdle) {
13022                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13023                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13024                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13025                        if (doKilling && proc.initialIdlePss != 0
13026                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13027                            sb = new StringBuilder(128);
13028                            sb.append("Kill");
13029                            sb.append(proc.processName);
13030                            sb.append(" in idle maint: pss=");
13031                            sb.append(proc.lastPss);
13032                            sb.append(", swapPss=");
13033                            sb.append(proc.lastSwapPss);
13034                            sb.append(", initialPss=");
13035                            sb.append(proc.initialIdlePss);
13036                            sb.append(", period=");
13037                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13038                            sb.append(", lowRamPeriod=");
13039                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13040                            Slog.wtfQuiet(TAG, sb.toString());
13041                            proc.kill("idle maint (pss " + proc.lastPss
13042                                    + " from " + proc.initialIdlePss + ")", true);
13043                        }
13044                    }
13045                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13046                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13047                    proc.notCachedSinceIdle = true;
13048                    proc.initialIdlePss = 0;
13049                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13050                            mTestPssMode, isSleepingLocked(), now);
13051                }
13052            }
13053
13054            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13055            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13056        }
13057    }
13058
13059    @Override
13060    public void sendIdleJobTrigger() {
13061        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13062                != PackageManager.PERMISSION_GRANTED) {
13063            throw new SecurityException("Requires permission "
13064                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13065        }
13066
13067        final long ident = Binder.clearCallingIdentity();
13068        try {
13069            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13070                    .setPackage("android")
13071                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13072            broadcastIntent(null, intent, null, null, 0, null, null, null,
13073                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13074        } finally {
13075            Binder.restoreCallingIdentity(ident);
13076        }
13077    }
13078
13079    private void retrieveSettings() {
13080        final ContentResolver resolver = mContext.getContentResolver();
13081        final boolean freeformWindowManagement =
13082                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13083                        || Settings.Global.getInt(
13084                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13085        final boolean supportsPictureInPicture =
13086                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13087
13088        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13089        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13090        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13091        final boolean alwaysFinishActivities =
13092                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13093        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13094        final boolean forceResizable = Settings.Global.getInt(
13095                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13096        final boolean supportsLeanbackOnly =
13097                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13098
13099        // Transfer any global setting for forcing RTL layout, into a System Property
13100        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13101
13102        final Configuration configuration = new Configuration();
13103        Settings.System.getConfiguration(resolver, configuration);
13104        if (forceRtl) {
13105            // This will take care of setting the correct layout direction flags
13106            configuration.setLayoutDirection(configuration.locale);
13107        }
13108
13109        synchronized (this) {
13110            mDebugApp = mOrigDebugApp = debugApp;
13111            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13112            mAlwaysFinishActivities = alwaysFinishActivities;
13113            mSupportsLeanbackOnly = supportsLeanbackOnly;
13114            mForceResizableActivities = forceResizable;
13115            if (supportsMultiWindow || forceResizable) {
13116                mSupportsMultiWindow = true;
13117                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13118                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13119            } else {
13120                mSupportsMultiWindow = false;
13121                mSupportsFreeformWindowManagement = false;
13122                mSupportsPictureInPicture = false;
13123            }
13124            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13125            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13126            // This happens before any activities are started, so we can change global configuration
13127            // in-place.
13128            updateConfigurationLocked(configuration, null, true);
13129            final Configuration globalConfig = getGlobalConfiguration();
13130            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13131
13132            // Load resources only after the current configuration has been set.
13133            final Resources res = mContext.getResources();
13134            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13135            mThumbnailWidth = res.getDimensionPixelSize(
13136                    com.android.internal.R.dimen.thumbnail_width);
13137            mThumbnailHeight = res.getDimensionPixelSize(
13138                    com.android.internal.R.dimen.thumbnail_height);
13139            mMinPipAspectRatio = res.getFloat(
13140                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
13141            mMaxPipAspectRatio = res.getFloat(
13142                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
13143            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13144                    com.android.internal.R.string.config_appsNotReportingCrashes));
13145            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13146                    com.android.internal.R.bool.config_customUserSwitchUi);
13147            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13148                mFullscreenThumbnailScale = (float) res
13149                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13150                    (float) globalConfig.screenWidthDp;
13151            } else {
13152                mFullscreenThumbnailScale = res.getFraction(
13153                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13154            }
13155        }
13156    }
13157
13158    public void systemReady(final Runnable goingCallback) {
13159        synchronized(this) {
13160            if (mSystemReady) {
13161                // If we're done calling all the receivers, run the next "boot phase" passed in
13162                // by the SystemServer
13163                if (goingCallback != null) {
13164                    goingCallback.run();
13165                }
13166                return;
13167            }
13168
13169            mLocalDeviceIdleController
13170                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13171
13172            // Make sure we have the current profile info, since it is needed for security checks.
13173            mUserController.onSystemReady();
13174            mRecentTasks.onSystemReadyLocked();
13175            mAppOpsService.systemReady();
13176            mSystemReady = true;
13177        }
13178
13179        ArrayList<ProcessRecord> procsToKill = null;
13180        synchronized(mPidsSelfLocked) {
13181            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13182                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13183                if (!isAllowedWhileBooting(proc.info)){
13184                    if (procsToKill == null) {
13185                        procsToKill = new ArrayList<ProcessRecord>();
13186                    }
13187                    procsToKill.add(proc);
13188                }
13189            }
13190        }
13191
13192        synchronized(this) {
13193            if (procsToKill != null) {
13194                for (int i=procsToKill.size()-1; i>=0; i--) {
13195                    ProcessRecord proc = procsToKill.get(i);
13196                    Slog.i(TAG, "Removing system update proc: " + proc);
13197                    removeProcessLocked(proc, true, false, "system update done");
13198                }
13199            }
13200
13201            // Now that we have cleaned up any update processes, we
13202            // are ready to start launching real processes and know that
13203            // we won't trample on them any more.
13204            mProcessesReady = true;
13205        }
13206
13207        Slog.i(TAG, "System now ready");
13208        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13209            SystemClock.uptimeMillis());
13210
13211        synchronized(this) {
13212            // Make sure we have no pre-ready processes sitting around.
13213
13214            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13215                ResolveInfo ri = mContext.getPackageManager()
13216                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13217                                STOCK_PM_FLAGS);
13218                CharSequence errorMsg = null;
13219                if (ri != null) {
13220                    ActivityInfo ai = ri.activityInfo;
13221                    ApplicationInfo app = ai.applicationInfo;
13222                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13223                        mTopAction = Intent.ACTION_FACTORY_TEST;
13224                        mTopData = null;
13225                        mTopComponent = new ComponentName(app.packageName,
13226                                ai.name);
13227                    } else {
13228                        errorMsg = mContext.getResources().getText(
13229                                com.android.internal.R.string.factorytest_not_system);
13230                    }
13231                } else {
13232                    errorMsg = mContext.getResources().getText(
13233                            com.android.internal.R.string.factorytest_no_action);
13234                }
13235                if (errorMsg != null) {
13236                    mTopAction = null;
13237                    mTopData = null;
13238                    mTopComponent = null;
13239                    Message msg = Message.obtain();
13240                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13241                    msg.getData().putCharSequence("msg", errorMsg);
13242                    mUiHandler.sendMessage(msg);
13243                }
13244            }
13245        }
13246
13247        retrieveSettings();
13248        final int currentUserId;
13249        synchronized (this) {
13250            currentUserId = mUserController.getCurrentUserIdLocked();
13251            readGrantedUriPermissionsLocked();
13252        }
13253
13254        if (goingCallback != null) goingCallback.run();
13255
13256        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13257                Integer.toString(currentUserId), currentUserId);
13258        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13259                Integer.toString(currentUserId), currentUserId);
13260        mSystemServiceManager.startUser(currentUserId);
13261
13262        synchronized (this) {
13263            // Only start up encryption-aware persistent apps; once user is
13264            // unlocked we'll come back around and start unaware apps
13265            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13266
13267            // Start up initial activity.
13268            mBooting = true;
13269            // Enable home activity for system user, so that the system can always boot. We don't
13270            // do this when the system user is not setup since the setup wizard should be the one
13271            // to handle home activity in this case.
13272            if (UserManager.isSplitSystemUser() &&
13273                    Settings.Secure.getInt(mContext.getContentResolver(),
13274                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
13275                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13276                try {
13277                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13278                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13279                            UserHandle.USER_SYSTEM);
13280                } catch (RemoteException e) {
13281                    throw e.rethrowAsRuntimeException();
13282                }
13283            }
13284            startHomeActivityLocked(currentUserId, "systemReady");
13285
13286            try {
13287                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13288                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13289                            + " data partition or your device will be unstable.");
13290                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13291                }
13292            } catch (RemoteException e) {
13293            }
13294
13295            if (!Build.isBuildConsistent()) {
13296                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13297                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13298            }
13299
13300            long ident = Binder.clearCallingIdentity();
13301            try {
13302                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13303                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13304                        | Intent.FLAG_RECEIVER_FOREGROUND);
13305                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13306                broadcastIntentLocked(null, null, intent,
13307                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13308                        null, false, false, MY_PID, Process.SYSTEM_UID,
13309                        currentUserId);
13310                intent = new Intent(Intent.ACTION_USER_STARTING);
13311                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13312                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13313                broadcastIntentLocked(null, null, intent,
13314                        null, new IIntentReceiver.Stub() {
13315                            @Override
13316                            public void performReceive(Intent intent, int resultCode, String data,
13317                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13318                                    throws RemoteException {
13319                            }
13320                        }, 0, null, null,
13321                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13322                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13323            } catch (Throwable t) {
13324                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13325            } finally {
13326                Binder.restoreCallingIdentity(ident);
13327            }
13328            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13329            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13330        }
13331    }
13332
13333    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13334        synchronized (this) {
13335            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13336        }
13337    }
13338
13339    void skipCurrentReceiverLocked(ProcessRecord app) {
13340        for (BroadcastQueue queue : mBroadcastQueues) {
13341            queue.skipCurrentReceiverLocked(app);
13342        }
13343    }
13344
13345    /**
13346     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13347     * The application process will exit immediately after this call returns.
13348     * @param app object of the crashing app, null for the system server
13349     * @param crashInfo describing the exception
13350     */
13351    public void handleApplicationCrash(IBinder app,
13352            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13353        ProcessRecord r = findAppProcess(app, "Crash");
13354        final String processName = app == null ? "system_server"
13355                : (r == null ? "unknown" : r.processName);
13356
13357        handleApplicationCrashInner("crash", r, processName, crashInfo);
13358    }
13359
13360    /* Native crash reporting uses this inner version because it needs to be somewhat
13361     * decoupled from the AM-managed cleanup lifecycle
13362     */
13363    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13364            ApplicationErrorReport.CrashInfo crashInfo) {
13365        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13366                UserHandle.getUserId(Binder.getCallingUid()), processName,
13367                r == null ? -1 : r.info.flags,
13368                crashInfo.exceptionClassName,
13369                crashInfo.exceptionMessage,
13370                crashInfo.throwFileName,
13371                crashInfo.throwLineNumber);
13372
13373        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13374
13375        mAppErrors.crashApplication(r, crashInfo);
13376    }
13377
13378    public void handleApplicationStrictModeViolation(
13379            IBinder app,
13380            int violationMask,
13381            StrictMode.ViolationInfo info) {
13382        ProcessRecord r = findAppProcess(app, "StrictMode");
13383        if (r == null) {
13384            return;
13385        }
13386
13387        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13388            Integer stackFingerprint = info.hashCode();
13389            boolean logIt = true;
13390            synchronized (mAlreadyLoggedViolatedStacks) {
13391                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13392                    logIt = false;
13393                    // TODO: sub-sample into EventLog for these, with
13394                    // the info.durationMillis?  Then we'd get
13395                    // the relative pain numbers, without logging all
13396                    // the stack traces repeatedly.  We'd want to do
13397                    // likewise in the client code, which also does
13398                    // dup suppression, before the Binder call.
13399                } else {
13400                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13401                        mAlreadyLoggedViolatedStacks.clear();
13402                    }
13403                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13404                }
13405            }
13406            if (logIt) {
13407                logStrictModeViolationToDropBox(r, info);
13408            }
13409        }
13410
13411        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13412            AppErrorResult result = new AppErrorResult();
13413            synchronized (this) {
13414                final long origId = Binder.clearCallingIdentity();
13415
13416                Message msg = Message.obtain();
13417                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13418                HashMap<String, Object> data = new HashMap<String, Object>();
13419                data.put("result", result);
13420                data.put("app", r);
13421                data.put("violationMask", violationMask);
13422                data.put("info", info);
13423                msg.obj = data;
13424                mUiHandler.sendMessage(msg);
13425
13426                Binder.restoreCallingIdentity(origId);
13427            }
13428            int res = result.get();
13429            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13430        }
13431    }
13432
13433    // Depending on the policy in effect, there could be a bunch of
13434    // these in quick succession so we try to batch these together to
13435    // minimize disk writes, number of dropbox entries, and maximize
13436    // compression, by having more fewer, larger records.
13437    private void logStrictModeViolationToDropBox(
13438            ProcessRecord process,
13439            StrictMode.ViolationInfo info) {
13440        if (info == null) {
13441            return;
13442        }
13443        final boolean isSystemApp = process == null ||
13444                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13445                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13446        final String processName = process == null ? "unknown" : process.processName;
13447        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13448        final DropBoxManager dbox = (DropBoxManager)
13449                mContext.getSystemService(Context.DROPBOX_SERVICE);
13450
13451        // Exit early if the dropbox isn't configured to accept this report type.
13452        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13453
13454        boolean bufferWasEmpty;
13455        boolean needsFlush;
13456        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13457        synchronized (sb) {
13458            bufferWasEmpty = sb.length() == 0;
13459            appendDropBoxProcessHeaders(process, processName, sb);
13460            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13461            sb.append("System-App: ").append(isSystemApp).append("\n");
13462            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13463            if (info.violationNumThisLoop != 0) {
13464                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13465            }
13466            if (info.numAnimationsRunning != 0) {
13467                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13468            }
13469            if (info.broadcastIntentAction != null) {
13470                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13471            }
13472            if (info.durationMillis != -1) {
13473                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13474            }
13475            if (info.numInstances != -1) {
13476                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13477            }
13478            if (info.tags != null) {
13479                for (String tag : info.tags) {
13480                    sb.append("Span-Tag: ").append(tag).append("\n");
13481                }
13482            }
13483            sb.append("\n");
13484            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13485                sb.append(info.crashInfo.stackTrace);
13486                sb.append("\n");
13487            }
13488            if (info.message != null) {
13489                sb.append(info.message);
13490                sb.append("\n");
13491            }
13492
13493            // Only buffer up to ~64k.  Various logging bits truncate
13494            // things at 128k.
13495            needsFlush = (sb.length() > 64 * 1024);
13496        }
13497
13498        // Flush immediately if the buffer's grown too large, or this
13499        // is a non-system app.  Non-system apps are isolated with a
13500        // different tag & policy and not batched.
13501        //
13502        // Batching is useful during internal testing with
13503        // StrictMode settings turned up high.  Without batching,
13504        // thousands of separate files could be created on boot.
13505        if (!isSystemApp || needsFlush) {
13506            new Thread("Error dump: " + dropboxTag) {
13507                @Override
13508                public void run() {
13509                    String report;
13510                    synchronized (sb) {
13511                        report = sb.toString();
13512                        sb.delete(0, sb.length());
13513                        sb.trimToSize();
13514                    }
13515                    if (report.length() != 0) {
13516                        dbox.addText(dropboxTag, report);
13517                    }
13518                }
13519            }.start();
13520            return;
13521        }
13522
13523        // System app batching:
13524        if (!bufferWasEmpty) {
13525            // An existing dropbox-writing thread is outstanding, so
13526            // we don't need to start it up.  The existing thread will
13527            // catch the buffer appends we just did.
13528            return;
13529        }
13530
13531        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13532        // (After this point, we shouldn't access AMS internal data structures.)
13533        new Thread("Error dump: " + dropboxTag) {
13534            @Override
13535            public void run() {
13536                // 5 second sleep to let stacks arrive and be batched together
13537                try {
13538                    Thread.sleep(5000);  // 5 seconds
13539                } catch (InterruptedException e) {}
13540
13541                String errorReport;
13542                synchronized (mStrictModeBuffer) {
13543                    errorReport = mStrictModeBuffer.toString();
13544                    if (errorReport.length() == 0) {
13545                        return;
13546                    }
13547                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13548                    mStrictModeBuffer.trimToSize();
13549                }
13550                dbox.addText(dropboxTag, errorReport);
13551            }
13552        }.start();
13553    }
13554
13555    /**
13556     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13557     * @param app object of the crashing app, null for the system server
13558     * @param tag reported by the caller
13559     * @param system whether this wtf is coming from the system
13560     * @param crashInfo describing the context of the error
13561     * @return true if the process should exit immediately (WTF is fatal)
13562     */
13563    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13564            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13565        final int callingUid = Binder.getCallingUid();
13566        final int callingPid = Binder.getCallingPid();
13567
13568        if (system) {
13569            // If this is coming from the system, we could very well have low-level
13570            // system locks held, so we want to do this all asynchronously.  And we
13571            // never want this to become fatal, so there is that too.
13572            mHandler.post(new Runnable() {
13573                @Override public void run() {
13574                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13575                }
13576            });
13577            return false;
13578        }
13579
13580        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13581                crashInfo);
13582
13583        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
13584                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
13585        final boolean isSystem = (r == null) || r.persistent;
13586
13587        if (isFatal && !isSystem) {
13588            mAppErrors.crashApplication(r, crashInfo);
13589            return true;
13590        } else {
13591            return false;
13592        }
13593    }
13594
13595    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13596            final ApplicationErrorReport.CrashInfo crashInfo) {
13597        final ProcessRecord r = findAppProcess(app, "WTF");
13598        final String processName = app == null ? "system_server"
13599                : (r == null ? "unknown" : r.processName);
13600
13601        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13602                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13603
13604        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13605
13606        return r;
13607    }
13608
13609    /**
13610     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13611     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13612     */
13613    private ProcessRecord findAppProcess(IBinder app, String reason) {
13614        if (app == null) {
13615            return null;
13616        }
13617
13618        synchronized (this) {
13619            final int NP = mProcessNames.getMap().size();
13620            for (int ip=0; ip<NP; ip++) {
13621                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13622                final int NA = apps.size();
13623                for (int ia=0; ia<NA; ia++) {
13624                    ProcessRecord p = apps.valueAt(ia);
13625                    if (p.thread != null && p.thread.asBinder() == app) {
13626                        return p;
13627                    }
13628                }
13629            }
13630
13631            Slog.w(TAG, "Can't find mystery application for " + reason
13632                    + " from pid=" + Binder.getCallingPid()
13633                    + " uid=" + Binder.getCallingUid() + ": " + app);
13634            return null;
13635        }
13636    }
13637
13638    /**
13639     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13640     * to append various headers to the dropbox log text.
13641     */
13642    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13643            StringBuilder sb) {
13644        // Watchdog thread ends up invoking this function (with
13645        // a null ProcessRecord) to add the stack file to dropbox.
13646        // Do not acquire a lock on this (am) in such cases, as it
13647        // could cause a potential deadlock, if and when watchdog
13648        // is invoked due to unavailability of lock on am and it
13649        // would prevent watchdog from killing system_server.
13650        if (process == null) {
13651            sb.append("Process: ").append(processName).append("\n");
13652            return;
13653        }
13654        // Note: ProcessRecord 'process' is guarded by the service
13655        // instance.  (notably process.pkgList, which could otherwise change
13656        // concurrently during execution of this method)
13657        synchronized (this) {
13658            sb.append("Process: ").append(processName).append("\n");
13659            int flags = process.info.flags;
13660            IPackageManager pm = AppGlobals.getPackageManager();
13661            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13662            for (int ip=0; ip<process.pkgList.size(); ip++) {
13663                String pkg = process.pkgList.keyAt(ip);
13664                sb.append("Package: ").append(pkg);
13665                try {
13666                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13667                    if (pi != null) {
13668                        sb.append(" v").append(pi.versionCode);
13669                        if (pi.versionName != null) {
13670                            sb.append(" (").append(pi.versionName).append(")");
13671                        }
13672                    }
13673                } catch (RemoteException e) {
13674                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13675                }
13676                sb.append("\n");
13677            }
13678        }
13679    }
13680
13681    private static String processClass(ProcessRecord process) {
13682        if (process == null || process.pid == MY_PID) {
13683            return "system_server";
13684        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13685            return "system_app";
13686        } else {
13687            return "data_app";
13688        }
13689    }
13690
13691    private volatile long mWtfClusterStart;
13692    private volatile int mWtfClusterCount;
13693
13694    /**
13695     * Write a description of an error (crash, WTF, ANR) to the drop box.
13696     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13697     * @param process which caused the error, null means the system server
13698     * @param activity which triggered the error, null if unknown
13699     * @param parent activity related to the error, null if unknown
13700     * @param subject line related to the error, null if absent
13701     * @param report in long form describing the error, null if absent
13702     * @param dataFile text file to include in the report, null if none
13703     * @param crashInfo giving an application stack trace, null if absent
13704     */
13705    public void addErrorToDropBox(String eventType,
13706            ProcessRecord process, String processName, ActivityRecord activity,
13707            ActivityRecord parent, String subject,
13708            final String report, final File dataFile,
13709            final ApplicationErrorReport.CrashInfo crashInfo) {
13710        // NOTE -- this must never acquire the ActivityManagerService lock,
13711        // otherwise the watchdog may be prevented from resetting the system.
13712
13713        // Bail early if not published yet
13714        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
13715        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
13716
13717        // Exit early if the dropbox isn't configured to accept this report type.
13718        final String dropboxTag = processClass(process) + "_" + eventType;
13719        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13720
13721        // Rate-limit how often we're willing to do the heavy lifting below to
13722        // collect and record logs; currently 5 logs per 10 second period.
13723        final long now = SystemClock.elapsedRealtime();
13724        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13725            mWtfClusterStart = now;
13726            mWtfClusterCount = 1;
13727        } else {
13728            if (mWtfClusterCount++ >= 5) return;
13729        }
13730
13731        final StringBuilder sb = new StringBuilder(1024);
13732        appendDropBoxProcessHeaders(process, processName, sb);
13733        if (process != null) {
13734            sb.append("Foreground: ")
13735                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13736                    .append("\n");
13737        }
13738        if (activity != null) {
13739            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13740        }
13741        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13742            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13743        }
13744        if (parent != null && parent != activity) {
13745            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13746        }
13747        if (subject != null) {
13748            sb.append("Subject: ").append(subject).append("\n");
13749        }
13750        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13751        if (Debug.isDebuggerConnected()) {
13752            sb.append("Debugger: Connected\n");
13753        }
13754        sb.append("\n");
13755
13756        // Do the rest in a worker thread to avoid blocking the caller on I/O
13757        // (After this point, we shouldn't access AMS internal data structures.)
13758        Thread worker = new Thread("Error dump: " + dropboxTag) {
13759            @Override
13760            public void run() {
13761                if (report != null) {
13762                    sb.append(report);
13763                }
13764
13765                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13766                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13767                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13768                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13769
13770                if (dataFile != null && maxDataFileSize > 0) {
13771                    try {
13772                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13773                                    "\n\n[[TRUNCATED]]"));
13774                    } catch (IOException e) {
13775                        Slog.e(TAG, "Error reading " + dataFile, e);
13776                    }
13777                }
13778                if (crashInfo != null && crashInfo.stackTrace != null) {
13779                    sb.append(crashInfo.stackTrace);
13780                }
13781
13782                if (lines > 0) {
13783                    sb.append("\n");
13784
13785                    // Merge several logcat streams, and take the last N lines
13786                    InputStreamReader input = null;
13787                    try {
13788                        java.lang.Process logcat = new ProcessBuilder(
13789                                "/system/bin/timeout", "-k", "15s", "10s",
13790                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13791                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13792                                        .redirectErrorStream(true).start();
13793
13794                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13795                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13796                        input = new InputStreamReader(logcat.getInputStream());
13797
13798                        int num;
13799                        char[] buf = new char[8192];
13800                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13801                    } catch (IOException e) {
13802                        Slog.e(TAG, "Error running logcat", e);
13803                    } finally {
13804                        if (input != null) try { input.close(); } catch (IOException e) {}
13805                    }
13806                }
13807
13808                dbox.addText(dropboxTag, sb.toString());
13809            }
13810        };
13811
13812        if (process == null) {
13813            // If process is null, we are being called from some internal code
13814            // and may be about to die -- run this synchronously.
13815            worker.run();
13816        } else {
13817            worker.start();
13818        }
13819    }
13820
13821    @Override
13822    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13823        enforceNotIsolatedCaller("getProcessesInErrorState");
13824        // assume our apps are happy - lazy create the list
13825        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13826
13827        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13828                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13829        int userId = UserHandle.getUserId(Binder.getCallingUid());
13830
13831        synchronized (this) {
13832
13833            // iterate across all processes
13834            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13835                ProcessRecord app = mLruProcesses.get(i);
13836                if (!allUsers && app.userId != userId) {
13837                    continue;
13838                }
13839                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13840                    // This one's in trouble, so we'll generate a report for it
13841                    // crashes are higher priority (in case there's a crash *and* an anr)
13842                    ActivityManager.ProcessErrorStateInfo report = null;
13843                    if (app.crashing) {
13844                        report = app.crashingReport;
13845                    } else if (app.notResponding) {
13846                        report = app.notRespondingReport;
13847                    }
13848
13849                    if (report != null) {
13850                        if (errList == null) {
13851                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13852                        }
13853                        errList.add(report);
13854                    } else {
13855                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13856                                " crashing = " + app.crashing +
13857                                " notResponding = " + app.notResponding);
13858                    }
13859                }
13860            }
13861        }
13862
13863        return errList;
13864    }
13865
13866    static int procStateToImportance(int procState, int memAdj,
13867            ActivityManager.RunningAppProcessInfo currApp) {
13868        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13869        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13870            currApp.lru = memAdj;
13871        } else {
13872            currApp.lru = 0;
13873        }
13874        return imp;
13875    }
13876
13877    private void fillInProcMemInfo(ProcessRecord app,
13878            ActivityManager.RunningAppProcessInfo outInfo) {
13879        outInfo.pid = app.pid;
13880        outInfo.uid = app.info.uid;
13881        if (mHeavyWeightProcess == app) {
13882            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13883        }
13884        if (app.persistent) {
13885            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13886        }
13887        if (app.activities.size() > 0) {
13888            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13889        }
13890        outInfo.lastTrimLevel = app.trimMemoryLevel;
13891        int adj = app.curAdj;
13892        int procState = app.curProcState;
13893        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13894        outInfo.importanceReasonCode = app.adjTypeCode;
13895        outInfo.processState = app.curProcState;
13896    }
13897
13898    @Override
13899    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13900        enforceNotIsolatedCaller("getRunningAppProcesses");
13901
13902        final int callingUid = Binder.getCallingUid();
13903
13904        // Lazy instantiation of list
13905        List<ActivityManager.RunningAppProcessInfo> runList = null;
13906        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13907                callingUid) == PackageManager.PERMISSION_GRANTED;
13908        final int userId = UserHandle.getUserId(callingUid);
13909        final boolean allUids = isGetTasksAllowed(
13910                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13911
13912        synchronized (this) {
13913            // Iterate across all processes
13914            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13915                ProcessRecord app = mLruProcesses.get(i);
13916                if ((!allUsers && app.userId != userId)
13917                        || (!allUids && app.uid != callingUid)) {
13918                    continue;
13919                }
13920                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13921                    // Generate process state info for running application
13922                    ActivityManager.RunningAppProcessInfo currApp =
13923                        new ActivityManager.RunningAppProcessInfo(app.processName,
13924                                app.pid, app.getPackageList());
13925                    fillInProcMemInfo(app, currApp);
13926                    if (app.adjSource instanceof ProcessRecord) {
13927                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13928                        currApp.importanceReasonImportance =
13929                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13930                                        app.adjSourceProcState);
13931                    } else if (app.adjSource instanceof ActivityRecord) {
13932                        ActivityRecord r = (ActivityRecord)app.adjSource;
13933                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13934                    }
13935                    if (app.adjTarget instanceof ComponentName) {
13936                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13937                    }
13938                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13939                    //        + " lru=" + currApp.lru);
13940                    if (runList == null) {
13941                        runList = new ArrayList<>();
13942                    }
13943                    runList.add(currApp);
13944                }
13945            }
13946        }
13947        return runList;
13948    }
13949
13950    @Override
13951    public List<ApplicationInfo> getRunningExternalApplications() {
13952        enforceNotIsolatedCaller("getRunningExternalApplications");
13953        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13954        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13955        if (runningApps != null && runningApps.size() > 0) {
13956            Set<String> extList = new HashSet<String>();
13957            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13958                if (app.pkgList != null) {
13959                    for (String pkg : app.pkgList) {
13960                        extList.add(pkg);
13961                    }
13962                }
13963            }
13964            IPackageManager pm = AppGlobals.getPackageManager();
13965            for (String pkg : extList) {
13966                try {
13967                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13968                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13969                        retList.add(info);
13970                    }
13971                } catch (RemoteException e) {
13972                }
13973            }
13974        }
13975        return retList;
13976    }
13977
13978    @Override
13979    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13980        enforceNotIsolatedCaller("getMyMemoryState");
13981        synchronized (this) {
13982            ProcessRecord proc;
13983            synchronized (mPidsSelfLocked) {
13984                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13985            }
13986            fillInProcMemInfo(proc, outInfo);
13987        }
13988    }
13989
13990    @Override
13991    public int getMemoryTrimLevel() {
13992        enforceNotIsolatedCaller("getMyMemoryState");
13993        synchronized (this) {
13994            return mLastMemoryLevel;
13995        }
13996    }
13997
13998    @Override
13999    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14000            FileDescriptor err, String[] args, ShellCallback callback,
14001            ResultReceiver resultReceiver) {
14002        (new ActivityManagerShellCommand(this, false)).exec(
14003                this, in, out, err, args, callback, resultReceiver);
14004    }
14005
14006    @Override
14007    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14008        if (checkCallingPermission(android.Manifest.permission.DUMP)
14009                != PackageManager.PERMISSION_GRANTED) {
14010            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14011                    + Binder.getCallingPid()
14012                    + ", uid=" + Binder.getCallingUid()
14013                    + " without permission "
14014                    + android.Manifest.permission.DUMP);
14015            return;
14016        }
14017
14018        boolean dumpAll = false;
14019        boolean dumpClient = false;
14020        boolean dumpCheckin = false;
14021        boolean dumpCheckinFormat = false;
14022        boolean dumpVisibleStacks = false;
14023        String dumpPackage = null;
14024
14025        int opti = 0;
14026        while (opti < args.length) {
14027            String opt = args[opti];
14028            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14029                break;
14030            }
14031            opti++;
14032            if ("-a".equals(opt)) {
14033                dumpAll = true;
14034            } else if ("-c".equals(opt)) {
14035                dumpClient = true;
14036            } else if ("-v".equals(opt)) {
14037                dumpVisibleStacks = true;
14038            } else if ("-p".equals(opt)) {
14039                if (opti < args.length) {
14040                    dumpPackage = args[opti];
14041                    opti++;
14042                } else {
14043                    pw.println("Error: -p option requires package argument");
14044                    return;
14045                }
14046                dumpClient = true;
14047            } else if ("--checkin".equals(opt)) {
14048                dumpCheckin = dumpCheckinFormat = true;
14049            } else if ("-C".equals(opt)) {
14050                dumpCheckinFormat = true;
14051            } else if ("-h".equals(opt)) {
14052                ActivityManagerShellCommand.dumpHelp(pw, true);
14053                return;
14054            } else {
14055                pw.println("Unknown argument: " + opt + "; use -h for help");
14056            }
14057        }
14058
14059        long origId = Binder.clearCallingIdentity();
14060        boolean more = false;
14061        // Is the caller requesting to dump a particular piece of data?
14062        if (opti < args.length) {
14063            String cmd = args[opti];
14064            opti++;
14065            if ("activities".equals(cmd) || "a".equals(cmd)) {
14066                synchronized (this) {
14067                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14068                }
14069            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14070                synchronized (this) {
14071                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14072                }
14073            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14074                String[] newArgs;
14075                String name;
14076                if (opti >= args.length) {
14077                    name = null;
14078                    newArgs = EMPTY_STRING_ARRAY;
14079                } else {
14080                    dumpPackage = args[opti];
14081                    opti++;
14082                    newArgs = new String[args.length - opti];
14083                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14084                            args.length - opti);
14085                }
14086                synchronized (this) {
14087                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14088                }
14089            } else if ("broadcast-stats".equals(cmd)) {
14090                String[] newArgs;
14091                String name;
14092                if (opti >= args.length) {
14093                    name = null;
14094                    newArgs = EMPTY_STRING_ARRAY;
14095                } else {
14096                    dumpPackage = args[opti];
14097                    opti++;
14098                    newArgs = new String[args.length - opti];
14099                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14100                            args.length - opti);
14101                }
14102                synchronized (this) {
14103                    if (dumpCheckinFormat) {
14104                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14105                                dumpPackage);
14106                    } else {
14107                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14108                    }
14109                }
14110            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14111                String[] newArgs;
14112                String name;
14113                if (opti >= args.length) {
14114                    name = null;
14115                    newArgs = EMPTY_STRING_ARRAY;
14116                } else {
14117                    dumpPackage = args[opti];
14118                    opti++;
14119                    newArgs = new String[args.length - opti];
14120                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14121                            args.length - opti);
14122                }
14123                synchronized (this) {
14124                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14125                }
14126            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14127                String[] newArgs;
14128                String name;
14129                if (opti >= args.length) {
14130                    name = null;
14131                    newArgs = EMPTY_STRING_ARRAY;
14132                } else {
14133                    dumpPackage = args[opti];
14134                    opti++;
14135                    newArgs = new String[args.length - opti];
14136                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14137                            args.length - opti);
14138                }
14139                synchronized (this) {
14140                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14141                }
14142            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14143                synchronized (this) {
14144                    dumpOomLocked(fd, pw, args, opti, true);
14145                }
14146            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14147                synchronized (this) {
14148                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14149                }
14150            } else if ("provider".equals(cmd)) {
14151                String[] newArgs;
14152                String name;
14153                if (opti >= args.length) {
14154                    name = null;
14155                    newArgs = EMPTY_STRING_ARRAY;
14156                } else {
14157                    name = args[opti];
14158                    opti++;
14159                    newArgs = new String[args.length - opti];
14160                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14161                }
14162                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14163                    pw.println("No providers match: " + name);
14164                    pw.println("Use -h for help.");
14165                }
14166            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14167                synchronized (this) {
14168                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14169                }
14170            } else if ("service".equals(cmd)) {
14171                String[] newArgs;
14172                String name;
14173                if (opti >= args.length) {
14174                    name = null;
14175                    newArgs = EMPTY_STRING_ARRAY;
14176                } else {
14177                    name = args[opti];
14178                    opti++;
14179                    newArgs = new String[args.length - opti];
14180                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14181                            args.length - opti);
14182                }
14183                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14184                    pw.println("No services match: " + name);
14185                    pw.println("Use -h for help.");
14186                }
14187            } else if ("package".equals(cmd)) {
14188                String[] newArgs;
14189                if (opti >= args.length) {
14190                    pw.println("package: no package name specified");
14191                    pw.println("Use -h for help.");
14192                } else {
14193                    dumpPackage = args[opti];
14194                    opti++;
14195                    newArgs = new String[args.length - opti];
14196                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14197                            args.length - opti);
14198                    args = newArgs;
14199                    opti = 0;
14200                    more = true;
14201                }
14202            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14203                synchronized (this) {
14204                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14205                }
14206            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14207                if (dumpClient) {
14208                    ActiveServices.ServiceDumper dumper;
14209                    synchronized (this) {
14210                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14211                                dumpPackage);
14212                    }
14213                    dumper.dumpWithClient();
14214                } else {
14215                    synchronized (this) {
14216                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14217                                dumpPackage).dumpLocked();
14218                    }
14219                }
14220            } else if ("locks".equals(cmd)) {
14221                LockGuard.dump(fd, pw, args);
14222            } else {
14223                // Dumping a single activity?
14224                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacks)) {
14225                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14226                    int res = shell.exec(this, null, fd, null, args, null,
14227                            new ResultReceiver(null));
14228                    if (res < 0) {
14229                        pw.println("Bad activity command, or no activities match: " + cmd);
14230                        pw.println("Use -h for help.");
14231                    }
14232                }
14233            }
14234            if (!more) {
14235                Binder.restoreCallingIdentity(origId);
14236                return;
14237            }
14238        }
14239
14240        // No piece of data specified, dump everything.
14241        if (dumpCheckinFormat) {
14242            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14243        } else if (dumpClient) {
14244            ActiveServices.ServiceDumper sdumper;
14245            synchronized (this) {
14246                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14247                pw.println();
14248                if (dumpAll) {
14249                    pw.println("-------------------------------------------------------------------------------");
14250                }
14251                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14252                pw.println();
14253                if (dumpAll) {
14254                    pw.println("-------------------------------------------------------------------------------");
14255                }
14256                if (dumpAll || dumpPackage != null) {
14257                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14258                    pw.println();
14259                    if (dumpAll) {
14260                        pw.println("-------------------------------------------------------------------------------");
14261                    }
14262                }
14263                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14264                pw.println();
14265                if (dumpAll) {
14266                    pw.println("-------------------------------------------------------------------------------");
14267                }
14268                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14269                pw.println();
14270                if (dumpAll) {
14271                    pw.println("-------------------------------------------------------------------------------");
14272                }
14273                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14274                        dumpPackage);
14275            }
14276            sdumper.dumpWithClient();
14277            pw.println();
14278            synchronized (this) {
14279                if (dumpAll) {
14280                    pw.println("-------------------------------------------------------------------------------");
14281                }
14282                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14283                pw.println();
14284                if (dumpAll) {
14285                    pw.println("-------------------------------------------------------------------------------");
14286                }
14287                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14288                if (mAssociations.size() > 0) {
14289                    pw.println();
14290                    if (dumpAll) {
14291                        pw.println("-------------------------------------------------------------------------------");
14292                    }
14293                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14294                }
14295                pw.println();
14296                if (dumpAll) {
14297                    pw.println("-------------------------------------------------------------------------------");
14298                }
14299                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14300            }
14301
14302        } else {
14303            synchronized (this) {
14304                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14305                pw.println();
14306                if (dumpAll) {
14307                    pw.println("-------------------------------------------------------------------------------");
14308                }
14309                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14310                pw.println();
14311                if (dumpAll) {
14312                    pw.println("-------------------------------------------------------------------------------");
14313                }
14314                if (dumpAll || dumpPackage != null) {
14315                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14316                    pw.println();
14317                    if (dumpAll) {
14318                        pw.println("-------------------------------------------------------------------------------");
14319                    }
14320                }
14321                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14322                pw.println();
14323                if (dumpAll) {
14324                    pw.println("-------------------------------------------------------------------------------");
14325                }
14326                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14327                pw.println();
14328                if (dumpAll) {
14329                    pw.println("-------------------------------------------------------------------------------");
14330                }
14331                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14332                        .dumpLocked();
14333                pw.println();
14334                if (dumpAll) {
14335                    pw.println("-------------------------------------------------------------------------------");
14336                }
14337                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14338                pw.println();
14339                if (dumpAll) {
14340                    pw.println("-------------------------------------------------------------------------------");
14341                }
14342                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14343                if (mAssociations.size() > 0) {
14344                    pw.println();
14345                    if (dumpAll) {
14346                        pw.println("-------------------------------------------------------------------------------");
14347                    }
14348                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14349                }
14350                pw.println();
14351                if (dumpAll) {
14352                    pw.println("-------------------------------------------------------------------------------");
14353                }
14354                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14355            }
14356        }
14357        Binder.restoreCallingIdentity(origId);
14358    }
14359
14360    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14361            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14362        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14363
14364        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14365                dumpPackage);
14366        boolean needSep = printedAnything;
14367
14368        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
14369                mStackSupervisor.getResumedActivityLocked(),
14370                dumpPackage, needSep, "  ResumedActivity: ");
14371        if (printed) {
14372            printedAnything = true;
14373            needSep = false;
14374        }
14375
14376        if (dumpPackage == null) {
14377            if (needSep) {
14378                pw.println();
14379            }
14380            needSep = true;
14381            printedAnything = true;
14382            mStackSupervisor.dump(pw, "  ");
14383        }
14384
14385        if (!printedAnything) {
14386            pw.println("  (nothing)");
14387        }
14388    }
14389
14390    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14391            int opti, boolean dumpAll, String dumpPackage) {
14392        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14393
14394        boolean printedAnything = false;
14395
14396        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14397            boolean printedHeader = false;
14398
14399            final int N = mRecentTasks.size();
14400            for (int i=0; i<N; i++) {
14401                TaskRecord tr = mRecentTasks.get(i);
14402                if (dumpPackage != null) {
14403                    if (tr.realActivity == null ||
14404                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
14405                        continue;
14406                    }
14407                }
14408                if (!printedHeader) {
14409                    pw.println("  Recent tasks:");
14410                    printedHeader = true;
14411                    printedAnything = true;
14412                }
14413                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14414                        pw.println(tr);
14415                if (dumpAll) {
14416                    mRecentTasks.get(i).dump(pw, "    ");
14417                }
14418            }
14419        }
14420
14421        if (!printedAnything) {
14422            pw.println("  (nothing)");
14423        }
14424    }
14425
14426    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14427            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14428        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14429
14430        int dumpUid = 0;
14431        if (dumpPackage != null) {
14432            IPackageManager pm = AppGlobals.getPackageManager();
14433            try {
14434                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
14435            } catch (RemoteException e) {
14436            }
14437        }
14438
14439        boolean printedAnything = false;
14440
14441        final long now = SystemClock.uptimeMillis();
14442
14443        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14444            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14445                    = mAssociations.valueAt(i1);
14446            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14447                SparseArray<ArrayMap<String, Association>> sourceUids
14448                        = targetComponents.valueAt(i2);
14449                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14450                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14451                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14452                        Association ass = sourceProcesses.valueAt(i4);
14453                        if (dumpPackage != null) {
14454                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14455                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14456                                continue;
14457                            }
14458                        }
14459                        printedAnything = true;
14460                        pw.print("  ");
14461                        pw.print(ass.mTargetProcess);
14462                        pw.print("/");
14463                        UserHandle.formatUid(pw, ass.mTargetUid);
14464                        pw.print(" <- ");
14465                        pw.print(ass.mSourceProcess);
14466                        pw.print("/");
14467                        UserHandle.formatUid(pw, ass.mSourceUid);
14468                        pw.println();
14469                        pw.print("    via ");
14470                        pw.print(ass.mTargetComponent.flattenToShortString());
14471                        pw.println();
14472                        pw.print("    ");
14473                        long dur = ass.mTime;
14474                        if (ass.mNesting > 0) {
14475                            dur += now - ass.mStartTime;
14476                        }
14477                        TimeUtils.formatDuration(dur, pw);
14478                        pw.print(" (");
14479                        pw.print(ass.mCount);
14480                        pw.print(" times)");
14481                        pw.print("  ");
14482                        for (int i=0; i<ass.mStateTimes.length; i++) {
14483                            long amt = ass.mStateTimes[i];
14484                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
14485                                amt += now - ass.mLastStateUptime;
14486                            }
14487                            if (amt != 0) {
14488                                pw.print(" ");
14489                                pw.print(ProcessList.makeProcStateString(
14490                                            i + ActivityManager.MIN_PROCESS_STATE));
14491                                pw.print("=");
14492                                TimeUtils.formatDuration(amt, pw);
14493                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
14494                                    pw.print("*");
14495                                }
14496                            }
14497                        }
14498                        pw.println();
14499                        if (ass.mNesting > 0) {
14500                            pw.print("    Currently active: ");
14501                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14502                            pw.println();
14503                        }
14504                    }
14505                }
14506            }
14507
14508        }
14509
14510        if (!printedAnything) {
14511            pw.println("  (nothing)");
14512        }
14513    }
14514
14515    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14516            String header, boolean needSep) {
14517        boolean printed = false;
14518        int whichAppId = -1;
14519        if (dumpPackage != null) {
14520            try {
14521                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14522                        dumpPackage, 0);
14523                whichAppId = UserHandle.getAppId(info.uid);
14524            } catch (NameNotFoundException e) {
14525                e.printStackTrace();
14526            }
14527        }
14528        for (int i=0; i<uids.size(); i++) {
14529            UidRecord uidRec = uids.valueAt(i);
14530            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14531                continue;
14532            }
14533            if (!printed) {
14534                printed = true;
14535                if (needSep) {
14536                    pw.println();
14537                }
14538                pw.print("  ");
14539                pw.println(header);
14540                needSep = true;
14541            }
14542            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14543            pw.print(": "); pw.println(uidRec);
14544        }
14545        return printed;
14546    }
14547
14548    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14549            int opti, boolean dumpAll, String dumpPackage) {
14550        boolean needSep = false;
14551        boolean printedAnything = false;
14552        int numPers = 0;
14553
14554        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14555
14556        if (dumpAll) {
14557            final int NP = mProcessNames.getMap().size();
14558            for (int ip=0; ip<NP; ip++) {
14559                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14560                final int NA = procs.size();
14561                for (int ia=0; ia<NA; ia++) {
14562                    ProcessRecord r = procs.valueAt(ia);
14563                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14564                        continue;
14565                    }
14566                    if (!needSep) {
14567                        pw.println("  All known processes:");
14568                        needSep = true;
14569                        printedAnything = true;
14570                    }
14571                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14572                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14573                        pw.print(" "); pw.println(r);
14574                    r.dump(pw, "    ");
14575                    if (r.persistent) {
14576                        numPers++;
14577                    }
14578                }
14579            }
14580        }
14581
14582        if (mIsolatedProcesses.size() > 0) {
14583            boolean printed = false;
14584            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14585                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14586                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14587                    continue;
14588                }
14589                if (!printed) {
14590                    if (needSep) {
14591                        pw.println();
14592                    }
14593                    pw.println("  Isolated process list (sorted by uid):");
14594                    printedAnything = true;
14595                    printed = true;
14596                    needSep = true;
14597                }
14598                pw.println(String.format("%sIsolated #%2d: %s",
14599                        "    ", i, r.toString()));
14600            }
14601        }
14602
14603        if (mActiveUids.size() > 0) {
14604            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14605                printedAnything = needSep = true;
14606            }
14607        }
14608        if (mValidateUids.size() > 0) {
14609            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14610                printedAnything = needSep = true;
14611            }
14612        }
14613
14614        if (mLruProcesses.size() > 0) {
14615            if (needSep) {
14616                pw.println();
14617            }
14618            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14619                    pw.print(" total, non-act at ");
14620                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14621                    pw.print(", non-svc at ");
14622                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14623                    pw.println("):");
14624            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14625            needSep = true;
14626            printedAnything = true;
14627        }
14628
14629        if (dumpAll || dumpPackage != null) {
14630            synchronized (mPidsSelfLocked) {
14631                boolean printed = false;
14632                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14633                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14634                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14635                        continue;
14636                    }
14637                    if (!printed) {
14638                        if (needSep) pw.println();
14639                        needSep = true;
14640                        pw.println("  PID mappings:");
14641                        printed = true;
14642                        printedAnything = true;
14643                    }
14644                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14645                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14646                }
14647            }
14648        }
14649
14650        if (mForegroundProcesses.size() > 0) {
14651            synchronized (mPidsSelfLocked) {
14652                boolean printed = false;
14653                for (int i=0; i<mForegroundProcesses.size(); i++) {
14654                    ProcessRecord r = mPidsSelfLocked.get(
14655                            mForegroundProcesses.valueAt(i).pid);
14656                    if (dumpPackage != null && (r == null
14657                            || !r.pkgList.containsKey(dumpPackage))) {
14658                        continue;
14659                    }
14660                    if (!printed) {
14661                        if (needSep) pw.println();
14662                        needSep = true;
14663                        pw.println("  Foreground Processes:");
14664                        printed = true;
14665                        printedAnything = true;
14666                    }
14667                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14668                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14669                }
14670            }
14671        }
14672
14673        if (mPersistentStartingProcesses.size() > 0) {
14674            if (needSep) pw.println();
14675            needSep = true;
14676            printedAnything = true;
14677            pw.println("  Persisent processes that are starting:");
14678            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14679                    "Starting Norm", "Restarting PERS", dumpPackage);
14680        }
14681
14682        if (mRemovedProcesses.size() > 0) {
14683            if (needSep) pw.println();
14684            needSep = true;
14685            printedAnything = true;
14686            pw.println("  Processes that are being removed:");
14687            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14688                    "Removed Norm", "Removed PERS", dumpPackage);
14689        }
14690
14691        if (mProcessesOnHold.size() > 0) {
14692            if (needSep) pw.println();
14693            needSep = true;
14694            printedAnything = true;
14695            pw.println("  Processes that are on old until the system is ready:");
14696            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14697                    "OnHold Norm", "OnHold PERS", dumpPackage);
14698        }
14699
14700        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14701
14702        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14703        if (needSep) {
14704            printedAnything = true;
14705        }
14706
14707        if (dumpPackage == null) {
14708            pw.println();
14709            needSep = false;
14710            mUserController.dump(pw, dumpAll);
14711        }
14712        if (mHomeProcess != null && (dumpPackage == null
14713                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14714            if (needSep) {
14715                pw.println();
14716                needSep = false;
14717            }
14718            pw.println("  mHomeProcess: " + mHomeProcess);
14719        }
14720        if (mPreviousProcess != null && (dumpPackage == null
14721                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14722            if (needSep) {
14723                pw.println();
14724                needSep = false;
14725            }
14726            pw.println("  mPreviousProcess: " + mPreviousProcess);
14727        }
14728        if (dumpAll) {
14729            StringBuilder sb = new StringBuilder(128);
14730            sb.append("  mPreviousProcessVisibleTime: ");
14731            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14732            pw.println(sb);
14733        }
14734        if (mHeavyWeightProcess != null && (dumpPackage == null
14735                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14736            if (needSep) {
14737                pw.println();
14738                needSep = false;
14739            }
14740            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14741        }
14742        if (dumpPackage == null) {
14743            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
14744            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
14745        }
14746        if (dumpAll) {
14747            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14748            if (mCompatModePackages.getPackages().size() > 0) {
14749                boolean printed = false;
14750                for (Map.Entry<String, Integer> entry
14751                        : mCompatModePackages.getPackages().entrySet()) {
14752                    String pkg = entry.getKey();
14753                    int mode = entry.getValue();
14754                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14755                        continue;
14756                    }
14757                    if (!printed) {
14758                        pw.println("  mScreenCompatPackages:");
14759                        printed = true;
14760                    }
14761                    pw.print("    "); pw.print(pkg); pw.print(": ");
14762                            pw.print(mode); pw.println();
14763                }
14764            }
14765            final int NI = mUidObservers.getRegisteredCallbackCount();
14766            boolean printed = false;
14767            for (int i=0; i<NI; i++) {
14768                final UidObserverRegistration reg = (UidObserverRegistration)
14769                        mUidObservers.getRegisteredCallbackCookie(i);
14770                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
14771                    if (!printed) {
14772                        pw.println("  mUidObservers:");
14773                        printed = true;
14774                    }
14775                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
14776                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
14777                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
14778                        pw.print(" IDLE");
14779                    }
14780                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
14781                        pw.print(" ACT" );
14782                    }
14783                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
14784                        pw.print(" GONE");
14785                    }
14786                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
14787                        pw.print(" STATE");
14788                        pw.print(" (cut="); pw.print(reg.cutpoint);
14789                        pw.print(")");
14790                    }
14791                    pw.println();
14792                    if (reg.lastProcStates != null) {
14793                        final int NJ = reg.lastProcStates.size();
14794                        for (int j=0; j<NJ; j++) {
14795                            pw.print("      Last ");
14796                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
14797                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
14798                        }
14799                    }
14800                }
14801            }
14802        }
14803        if (dumpPackage == null) {
14804            pw.println("  mWakefulness="
14805                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14806            pw.println("  mSleepTokens=" + mSleepTokens);
14807            pw.println("  mSleeping=" + mSleeping);
14808            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14809            if (mRunningVoice != null) {
14810                pw.println("  mRunningVoice=" + mRunningVoice);
14811                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14812            }
14813        }
14814        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14815                || mOrigWaitForDebugger) {
14816            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14817                    || dumpPackage.equals(mOrigDebugApp)) {
14818                if (needSep) {
14819                    pw.println();
14820                    needSep = false;
14821                }
14822                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14823                        + " mDebugTransient=" + mDebugTransient
14824                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14825            }
14826        }
14827        if (mCurAppTimeTracker != null) {
14828            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14829        }
14830        if (mMemWatchProcesses.getMap().size() > 0) {
14831            pw.println("  Mem watch processes:");
14832            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14833                    = mMemWatchProcesses.getMap();
14834            for (int i=0; i<procs.size(); i++) {
14835                final String proc = procs.keyAt(i);
14836                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14837                for (int j=0; j<uids.size(); j++) {
14838                    if (needSep) {
14839                        pw.println();
14840                        needSep = false;
14841                    }
14842                    StringBuilder sb = new StringBuilder();
14843                    sb.append("    ").append(proc).append('/');
14844                    UserHandle.formatUid(sb, uids.keyAt(j));
14845                    Pair<Long, String> val = uids.valueAt(j);
14846                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14847                    if (val.second != null) {
14848                        sb.append(", report to ").append(val.second);
14849                    }
14850                    pw.println(sb.toString());
14851                }
14852            }
14853            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14854            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14855            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14856                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14857        }
14858        if (mTrackAllocationApp != null) {
14859            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14860                if (needSep) {
14861                    pw.println();
14862                    needSep = false;
14863                }
14864                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14865            }
14866        }
14867        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14868                || mProfileFd != null) {
14869            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14870                if (needSep) {
14871                    pw.println();
14872                    needSep = false;
14873                }
14874                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14875                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14876                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14877                        + mAutoStopProfiler);
14878                pw.println("  mProfileType=" + mProfileType);
14879            }
14880        }
14881        if (mNativeDebuggingApp != null) {
14882            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14883                if (needSep) {
14884                    pw.println();
14885                    needSep = false;
14886                }
14887                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14888            }
14889        }
14890        if (dumpPackage == null) {
14891            if (mAlwaysFinishActivities) {
14892                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
14893            }
14894            if (mController != null) {
14895                pw.println("  mController=" + mController
14896                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14897            }
14898            if (dumpAll) {
14899                pw.println("  Total persistent processes: " + numPers);
14900                pw.println("  mProcessesReady=" + mProcessesReady
14901                        + " mSystemReady=" + mSystemReady
14902                        + " mBooted=" + mBooted
14903                        + " mFactoryTest=" + mFactoryTest);
14904                pw.println("  mBooting=" + mBooting
14905                        + " mCallFinishBooting=" + mCallFinishBooting
14906                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14907                pw.print("  mLastPowerCheckRealtime=");
14908                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14909                        pw.println("");
14910                pw.print("  mLastPowerCheckUptime=");
14911                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14912                        pw.println("");
14913                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14914                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14915                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14916                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14917                        + " (" + mLruProcesses.size() + " total)"
14918                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14919                        + " mNumServiceProcs=" + mNumServiceProcs
14920                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14921                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14922                        + " mLastMemoryLevel=" + mLastMemoryLevel
14923                        + " mLastNumProcesses=" + mLastNumProcesses);
14924                long now = SystemClock.uptimeMillis();
14925                pw.print("  mLastIdleTime=");
14926                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14927                        pw.print(" mLowRamSinceLastIdle=");
14928                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14929                        pw.println();
14930            }
14931        }
14932
14933        if (!printedAnything) {
14934            pw.println("  (nothing)");
14935        }
14936    }
14937
14938    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14939            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14940        if (mProcessesToGc.size() > 0) {
14941            boolean printed = false;
14942            long now = SystemClock.uptimeMillis();
14943            for (int i=0; i<mProcessesToGc.size(); i++) {
14944                ProcessRecord proc = mProcessesToGc.get(i);
14945                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14946                    continue;
14947                }
14948                if (!printed) {
14949                    if (needSep) pw.println();
14950                    needSep = true;
14951                    pw.println("  Processes that are waiting to GC:");
14952                    printed = true;
14953                }
14954                pw.print("    Process "); pw.println(proc);
14955                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14956                        pw.print(", last gced=");
14957                        pw.print(now-proc.lastRequestedGc);
14958                        pw.print(" ms ago, last lowMem=");
14959                        pw.print(now-proc.lastLowMemory);
14960                        pw.println(" ms ago");
14961
14962            }
14963        }
14964        return needSep;
14965    }
14966
14967    void printOomLevel(PrintWriter pw, String name, int adj) {
14968        pw.print("    ");
14969        if (adj >= 0) {
14970            pw.print(' ');
14971            if (adj < 10) pw.print(' ');
14972        } else {
14973            if (adj > -10) pw.print(' ');
14974        }
14975        pw.print(adj);
14976        pw.print(": ");
14977        pw.print(name);
14978        pw.print(" (");
14979        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14980        pw.println(")");
14981    }
14982
14983    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14984            int opti, boolean dumpAll) {
14985        boolean needSep = false;
14986
14987        if (mLruProcesses.size() > 0) {
14988            if (needSep) pw.println();
14989            needSep = true;
14990            pw.println("  OOM levels:");
14991            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14992            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14993            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14994            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14995            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14996            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14997            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14998            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14999            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15000            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15001            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15002            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15003            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15004            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15005
15006            if (needSep) pw.println();
15007            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15008                    pw.print(" total, non-act at ");
15009                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15010                    pw.print(", non-svc at ");
15011                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15012                    pw.println("):");
15013            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15014            needSep = true;
15015        }
15016
15017        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15018
15019        pw.println();
15020        pw.println("  mHomeProcess: " + mHomeProcess);
15021        pw.println("  mPreviousProcess: " + mPreviousProcess);
15022        if (mHeavyWeightProcess != null) {
15023            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15024        }
15025
15026        return true;
15027    }
15028
15029    /**
15030     * There are three ways to call this:
15031     *  - no provider specified: dump all the providers
15032     *  - a flattened component name that matched an existing provider was specified as the
15033     *    first arg: dump that one provider
15034     *  - the first arg isn't the flattened component name of an existing provider:
15035     *    dump all providers whose component contains the first arg as a substring
15036     */
15037    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15038            int opti, boolean dumpAll) {
15039        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15040    }
15041
15042    static class ItemMatcher {
15043        ArrayList<ComponentName> components;
15044        ArrayList<String> strings;
15045        ArrayList<Integer> objects;
15046        boolean all;
15047
15048        ItemMatcher() {
15049            all = true;
15050        }
15051
15052        void build(String name) {
15053            ComponentName componentName = ComponentName.unflattenFromString(name);
15054            if (componentName != null) {
15055                if (components == null) {
15056                    components = new ArrayList<ComponentName>();
15057                }
15058                components.add(componentName);
15059                all = false;
15060            } else {
15061                int objectId = 0;
15062                // Not a '/' separated full component name; maybe an object ID?
15063                try {
15064                    objectId = Integer.parseInt(name, 16);
15065                    if (objects == null) {
15066                        objects = new ArrayList<Integer>();
15067                    }
15068                    objects.add(objectId);
15069                    all = false;
15070                } catch (RuntimeException e) {
15071                    // Not an integer; just do string match.
15072                    if (strings == null) {
15073                        strings = new ArrayList<String>();
15074                    }
15075                    strings.add(name);
15076                    all = false;
15077                }
15078            }
15079        }
15080
15081        int build(String[] args, int opti) {
15082            for (; opti<args.length; opti++) {
15083                String name = args[opti];
15084                if ("--".equals(name)) {
15085                    return opti+1;
15086                }
15087                build(name);
15088            }
15089            return opti;
15090        }
15091
15092        boolean match(Object object, ComponentName comp) {
15093            if (all) {
15094                return true;
15095            }
15096            if (components != null) {
15097                for (int i=0; i<components.size(); i++) {
15098                    if (components.get(i).equals(comp)) {
15099                        return true;
15100                    }
15101                }
15102            }
15103            if (objects != null) {
15104                for (int i=0; i<objects.size(); i++) {
15105                    if (System.identityHashCode(object) == objects.get(i)) {
15106                        return true;
15107                    }
15108                }
15109            }
15110            if (strings != null) {
15111                String flat = comp.flattenToString();
15112                for (int i=0; i<strings.size(); i++) {
15113                    if (flat.contains(strings.get(i))) {
15114                        return true;
15115                    }
15116                }
15117            }
15118            return false;
15119        }
15120    }
15121
15122    /**
15123     * There are three things that cmd can be:
15124     *  - a flattened component name that matches an existing activity
15125     *  - the cmd arg isn't the flattened component name of an existing activity:
15126     *    dump all activity whose component contains the cmd as a substring
15127     *  - A hex number of the ActivityRecord object instance.
15128     */
15129    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15130            int opti, boolean dumpAll, boolean dumpVisibleStacks) {
15131        ArrayList<ActivityRecord> activities;
15132
15133        synchronized (this) {
15134            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacks);
15135        }
15136
15137        if (activities.size() <= 0) {
15138            return false;
15139        }
15140
15141        String[] newArgs = new String[args.length - opti];
15142        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15143
15144        TaskRecord lastTask = null;
15145        boolean needSep = false;
15146        for (int i=activities.size()-1; i>=0; i--) {
15147            ActivityRecord r = activities.get(i);
15148            if (needSep) {
15149                pw.println();
15150            }
15151            needSep = true;
15152            synchronized (this) {
15153                if (lastTask != r.task) {
15154                    lastTask = r.task;
15155                    pw.print("TASK "); pw.print(lastTask.affinity);
15156                            pw.print(" id="); pw.print(lastTask.taskId);
15157                            pw.print(" userId="); pw.println(lastTask.userId);
15158                    if (dumpAll) {
15159                        lastTask.dump(pw, "  ");
15160                    }
15161                }
15162            }
15163            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15164        }
15165        return true;
15166    }
15167
15168    /**
15169     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15170     * there is a thread associated with the activity.
15171     */
15172    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15173            final ActivityRecord r, String[] args, boolean dumpAll) {
15174        String innerPrefix = prefix + "  ";
15175        synchronized (this) {
15176            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15177                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15178                    pw.print(" pid=");
15179                    if (r.app != null) pw.println(r.app.pid);
15180                    else pw.println("(not running)");
15181            if (dumpAll) {
15182                r.dump(pw, innerPrefix);
15183            }
15184        }
15185        if (r.app != null && r.app.thread != null) {
15186            // flush anything that is already in the PrintWriter since the thread is going
15187            // to write to the file descriptor directly
15188            pw.flush();
15189            try {
15190                TransferPipe tp = new TransferPipe();
15191                try {
15192                    r.app.thread.dumpActivity(tp.getWriteFd(),
15193                            r.appToken, innerPrefix, args);
15194                    tp.go(fd);
15195                } finally {
15196                    tp.kill();
15197                }
15198            } catch (IOException e) {
15199                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15200            } catch (RemoteException e) {
15201                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15202            }
15203        }
15204    }
15205
15206    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15207            int opti, boolean dumpAll, String dumpPackage) {
15208        boolean needSep = false;
15209        boolean onlyHistory = false;
15210        boolean printedAnything = false;
15211
15212        if ("history".equals(dumpPackage)) {
15213            if (opti < args.length && "-s".equals(args[opti])) {
15214                dumpAll = false;
15215            }
15216            onlyHistory = true;
15217            dumpPackage = null;
15218        }
15219
15220        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15221        if (!onlyHistory && dumpAll) {
15222            if (mRegisteredReceivers.size() > 0) {
15223                boolean printed = false;
15224                Iterator it = mRegisteredReceivers.values().iterator();
15225                while (it.hasNext()) {
15226                    ReceiverList r = (ReceiverList)it.next();
15227                    if (dumpPackage != null && (r.app == null ||
15228                            !dumpPackage.equals(r.app.info.packageName))) {
15229                        continue;
15230                    }
15231                    if (!printed) {
15232                        pw.println("  Registered Receivers:");
15233                        needSep = true;
15234                        printed = true;
15235                        printedAnything = true;
15236                    }
15237                    pw.print("  * "); pw.println(r);
15238                    r.dump(pw, "    ");
15239                }
15240            }
15241
15242            if (mReceiverResolver.dump(pw, needSep ?
15243                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15244                    "    ", dumpPackage, false, false)) {
15245                needSep = true;
15246                printedAnything = true;
15247            }
15248        }
15249
15250        for (BroadcastQueue q : mBroadcastQueues) {
15251            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15252            printedAnything |= needSep;
15253        }
15254
15255        needSep = true;
15256
15257        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15258            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15259                if (needSep) {
15260                    pw.println();
15261                }
15262                needSep = true;
15263                printedAnything = true;
15264                pw.print("  Sticky broadcasts for user ");
15265                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15266                StringBuilder sb = new StringBuilder(128);
15267                for (Map.Entry<String, ArrayList<Intent>> ent
15268                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15269                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15270                    if (dumpAll) {
15271                        pw.println(":");
15272                        ArrayList<Intent> intents = ent.getValue();
15273                        final int N = intents.size();
15274                        for (int i=0; i<N; i++) {
15275                            sb.setLength(0);
15276                            sb.append("    Intent: ");
15277                            intents.get(i).toShortString(sb, false, true, false, false);
15278                            pw.println(sb.toString());
15279                            Bundle bundle = intents.get(i).getExtras();
15280                            if (bundle != null) {
15281                                pw.print("      ");
15282                                pw.println(bundle.toString());
15283                            }
15284                        }
15285                    } else {
15286                        pw.println("");
15287                    }
15288                }
15289            }
15290        }
15291
15292        if (!onlyHistory && dumpAll) {
15293            pw.println();
15294            for (BroadcastQueue queue : mBroadcastQueues) {
15295                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15296                        + queue.mBroadcastsScheduled);
15297            }
15298            pw.println("  mHandler:");
15299            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15300            needSep = true;
15301            printedAnything = true;
15302        }
15303
15304        if (!printedAnything) {
15305            pw.println("  (nothing)");
15306        }
15307    }
15308
15309    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15310            int opti, boolean dumpAll, String dumpPackage) {
15311        if (mCurBroadcastStats == null) {
15312            return;
15313        }
15314
15315        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15316        final long now = SystemClock.elapsedRealtime();
15317        if (mLastBroadcastStats != null) {
15318            pw.print("  Last stats (from ");
15319            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15320            pw.print(" to ");
15321            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15322            pw.print(", ");
15323            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15324                    - mLastBroadcastStats.mStartUptime, pw);
15325            pw.println(" uptime):");
15326            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15327                pw.println("    (nothing)");
15328            }
15329            pw.println();
15330        }
15331        pw.print("  Current stats (from ");
15332        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15333        pw.print(" to now, ");
15334        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15335                - mCurBroadcastStats.mStartUptime, pw);
15336        pw.println(" uptime):");
15337        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15338            pw.println("    (nothing)");
15339        }
15340    }
15341
15342    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15343            int opti, boolean fullCheckin, String dumpPackage) {
15344        if (mCurBroadcastStats == null) {
15345            return;
15346        }
15347
15348        if (mLastBroadcastStats != null) {
15349            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15350            if (fullCheckin) {
15351                mLastBroadcastStats = null;
15352                return;
15353            }
15354        }
15355        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15356        if (fullCheckin) {
15357            mCurBroadcastStats = null;
15358        }
15359    }
15360
15361    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15362            int opti, boolean dumpAll, String dumpPackage) {
15363        boolean needSep;
15364        boolean printedAnything = false;
15365
15366        ItemMatcher matcher = new ItemMatcher();
15367        matcher.build(args, opti);
15368
15369        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15370
15371        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15372        printedAnything |= needSep;
15373
15374        if (mLaunchingProviders.size() > 0) {
15375            boolean printed = false;
15376            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15377                ContentProviderRecord r = mLaunchingProviders.get(i);
15378                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15379                    continue;
15380                }
15381                if (!printed) {
15382                    if (needSep) pw.println();
15383                    needSep = true;
15384                    pw.println("  Launching content providers:");
15385                    printed = true;
15386                    printedAnything = true;
15387                }
15388                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15389                        pw.println(r);
15390            }
15391        }
15392
15393        if (!printedAnything) {
15394            pw.println("  (nothing)");
15395        }
15396    }
15397
15398    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15399            int opti, boolean dumpAll, String dumpPackage) {
15400        boolean needSep = false;
15401        boolean printedAnything = false;
15402
15403        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15404
15405        if (mGrantedUriPermissions.size() > 0) {
15406            boolean printed = false;
15407            int dumpUid = -2;
15408            if (dumpPackage != null) {
15409                try {
15410                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15411                            MATCH_ANY_USER, 0);
15412                } catch (NameNotFoundException e) {
15413                    dumpUid = -1;
15414                }
15415            }
15416            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15417                int uid = mGrantedUriPermissions.keyAt(i);
15418                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15419                    continue;
15420                }
15421                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15422                if (!printed) {
15423                    if (needSep) pw.println();
15424                    needSep = true;
15425                    pw.println("  Granted Uri Permissions:");
15426                    printed = true;
15427                    printedAnything = true;
15428                }
15429                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15430                for (UriPermission perm : perms.values()) {
15431                    pw.print("    "); pw.println(perm);
15432                    if (dumpAll) {
15433                        perm.dump(pw, "      ");
15434                    }
15435                }
15436            }
15437        }
15438
15439        if (!printedAnything) {
15440            pw.println("  (nothing)");
15441        }
15442    }
15443
15444    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15445            int opti, boolean dumpAll, String dumpPackage) {
15446        boolean printed = false;
15447
15448        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15449
15450        if (mIntentSenderRecords.size() > 0) {
15451            Iterator<WeakReference<PendingIntentRecord>> it
15452                    = mIntentSenderRecords.values().iterator();
15453            while (it.hasNext()) {
15454                WeakReference<PendingIntentRecord> ref = it.next();
15455                PendingIntentRecord rec = ref != null ? ref.get(): null;
15456                if (dumpPackage != null && (rec == null
15457                        || !dumpPackage.equals(rec.key.packageName))) {
15458                    continue;
15459                }
15460                printed = true;
15461                if (rec != null) {
15462                    pw.print("  * "); pw.println(rec);
15463                    if (dumpAll) {
15464                        rec.dump(pw, "    ");
15465                    }
15466                } else {
15467                    pw.print("  * "); pw.println(ref);
15468                }
15469            }
15470        }
15471
15472        if (!printed) {
15473            pw.println("  (nothing)");
15474        }
15475    }
15476
15477    private static final int dumpProcessList(PrintWriter pw,
15478            ActivityManagerService service, List list,
15479            String prefix, String normalLabel, String persistentLabel,
15480            String dumpPackage) {
15481        int numPers = 0;
15482        final int N = list.size()-1;
15483        for (int i=N; i>=0; i--) {
15484            ProcessRecord r = (ProcessRecord)list.get(i);
15485            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15486                continue;
15487            }
15488            pw.println(String.format("%s%s #%2d: %s",
15489                    prefix, (r.persistent ? persistentLabel : normalLabel),
15490                    i, r.toString()));
15491            if (r.persistent) {
15492                numPers++;
15493            }
15494        }
15495        return numPers;
15496    }
15497
15498    private static final boolean dumpProcessOomList(PrintWriter pw,
15499            ActivityManagerService service, List<ProcessRecord> origList,
15500            String prefix, String normalLabel, String persistentLabel,
15501            boolean inclDetails, String dumpPackage) {
15502
15503        ArrayList<Pair<ProcessRecord, Integer>> list
15504                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15505        for (int i=0; i<origList.size(); i++) {
15506            ProcessRecord r = origList.get(i);
15507            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15508                continue;
15509            }
15510            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15511        }
15512
15513        if (list.size() <= 0) {
15514            return false;
15515        }
15516
15517        Comparator<Pair<ProcessRecord, Integer>> comparator
15518                = new Comparator<Pair<ProcessRecord, Integer>>() {
15519            @Override
15520            public int compare(Pair<ProcessRecord, Integer> object1,
15521                    Pair<ProcessRecord, Integer> object2) {
15522                if (object1.first.setAdj != object2.first.setAdj) {
15523                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15524                }
15525                if (object1.first.setProcState != object2.first.setProcState) {
15526                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15527                }
15528                if (object1.second.intValue() != object2.second.intValue()) {
15529                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15530                }
15531                return 0;
15532            }
15533        };
15534
15535        Collections.sort(list, comparator);
15536
15537        final long curRealtime = SystemClock.elapsedRealtime();
15538        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15539        final long curUptime = SystemClock.uptimeMillis();
15540        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15541
15542        for (int i=list.size()-1; i>=0; i--) {
15543            ProcessRecord r = list.get(i).first;
15544            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15545            char schedGroup;
15546            switch (r.setSchedGroup) {
15547                case ProcessList.SCHED_GROUP_BACKGROUND:
15548                    schedGroup = 'B';
15549                    break;
15550                case ProcessList.SCHED_GROUP_DEFAULT:
15551                    schedGroup = 'F';
15552                    break;
15553                case ProcessList.SCHED_GROUP_TOP_APP:
15554                    schedGroup = 'T';
15555                    break;
15556                default:
15557                    schedGroup = '?';
15558                    break;
15559            }
15560            char foreground;
15561            if (r.foregroundActivities) {
15562                foreground = 'A';
15563            } else if (r.foregroundServices) {
15564                foreground = 'S';
15565            } else {
15566                foreground = ' ';
15567            }
15568            String procState = ProcessList.makeProcStateString(r.curProcState);
15569            pw.print(prefix);
15570            pw.print(r.persistent ? persistentLabel : normalLabel);
15571            pw.print(" #");
15572            int num = (origList.size()-1)-list.get(i).second;
15573            if (num < 10) pw.print(' ');
15574            pw.print(num);
15575            pw.print(": ");
15576            pw.print(oomAdj);
15577            pw.print(' ');
15578            pw.print(schedGroup);
15579            pw.print('/');
15580            pw.print(foreground);
15581            pw.print('/');
15582            pw.print(procState);
15583            pw.print(" trm:");
15584            if (r.trimMemoryLevel < 10) pw.print(' ');
15585            pw.print(r.trimMemoryLevel);
15586            pw.print(' ');
15587            pw.print(r.toShortString());
15588            pw.print(" (");
15589            pw.print(r.adjType);
15590            pw.println(')');
15591            if (r.adjSource != null || r.adjTarget != null) {
15592                pw.print(prefix);
15593                pw.print("    ");
15594                if (r.adjTarget instanceof ComponentName) {
15595                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15596                } else if (r.adjTarget != null) {
15597                    pw.print(r.adjTarget.toString());
15598                } else {
15599                    pw.print("{null}");
15600                }
15601                pw.print("<=");
15602                if (r.adjSource instanceof ProcessRecord) {
15603                    pw.print("Proc{");
15604                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15605                    pw.println("}");
15606                } else if (r.adjSource != null) {
15607                    pw.println(r.adjSource.toString());
15608                } else {
15609                    pw.println("{null}");
15610                }
15611            }
15612            if (inclDetails) {
15613                pw.print(prefix);
15614                pw.print("    ");
15615                pw.print("oom: max="); pw.print(r.maxAdj);
15616                pw.print(" curRaw="); pw.print(r.curRawAdj);
15617                pw.print(" setRaw="); pw.print(r.setRawAdj);
15618                pw.print(" cur="); pw.print(r.curAdj);
15619                pw.print(" set="); pw.println(r.setAdj);
15620                pw.print(prefix);
15621                pw.print("    ");
15622                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15623                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15624                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15625                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15626                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15627                pw.println();
15628                pw.print(prefix);
15629                pw.print("    ");
15630                pw.print("cached="); pw.print(r.cached);
15631                pw.print(" empty="); pw.print(r.empty);
15632                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15633
15634                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15635                    if (r.lastWakeTime != 0) {
15636                        long wtime;
15637                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15638                        synchronized (stats) {
15639                            wtime = stats.getProcessWakeTime(r.info.uid,
15640                                    r.pid, curRealtime);
15641                        }
15642                        long timeUsed = wtime - r.lastWakeTime;
15643                        pw.print(prefix);
15644                        pw.print("    ");
15645                        pw.print("keep awake over ");
15646                        TimeUtils.formatDuration(realtimeSince, pw);
15647                        pw.print(" used ");
15648                        TimeUtils.formatDuration(timeUsed, pw);
15649                        pw.print(" (");
15650                        pw.print((timeUsed*100)/realtimeSince);
15651                        pw.println("%)");
15652                    }
15653                    if (r.lastCpuTime != 0) {
15654                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15655                        pw.print(prefix);
15656                        pw.print("    ");
15657                        pw.print("run cpu over ");
15658                        TimeUtils.formatDuration(uptimeSince, pw);
15659                        pw.print(" used ");
15660                        TimeUtils.formatDuration(timeUsed, pw);
15661                        pw.print(" (");
15662                        pw.print((timeUsed*100)/uptimeSince);
15663                        pw.println("%)");
15664                    }
15665                }
15666            }
15667        }
15668        return true;
15669    }
15670
15671    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15672            String[] args) {
15673        ArrayList<ProcessRecord> procs;
15674        synchronized (this) {
15675            if (args != null && args.length > start
15676                    && args[start].charAt(0) != '-') {
15677                procs = new ArrayList<ProcessRecord>();
15678                int pid = -1;
15679                try {
15680                    pid = Integer.parseInt(args[start]);
15681                } catch (NumberFormatException e) {
15682                }
15683                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15684                    ProcessRecord proc = mLruProcesses.get(i);
15685                    if (proc.pid == pid) {
15686                        procs.add(proc);
15687                    } else if (allPkgs && proc.pkgList != null
15688                            && proc.pkgList.containsKey(args[start])) {
15689                        procs.add(proc);
15690                    } else if (proc.processName.equals(args[start])) {
15691                        procs.add(proc);
15692                    }
15693                }
15694                if (procs.size() <= 0) {
15695                    return null;
15696                }
15697            } else {
15698                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15699            }
15700        }
15701        return procs;
15702    }
15703
15704    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15705            PrintWriter pw, String[] args) {
15706        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15707        if (procs == null) {
15708            pw.println("No process found for: " + args[0]);
15709            return;
15710        }
15711
15712        long uptime = SystemClock.uptimeMillis();
15713        long realtime = SystemClock.elapsedRealtime();
15714        pw.println("Applications Graphics Acceleration Info:");
15715        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15716
15717        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15718            ProcessRecord r = procs.get(i);
15719            if (r.thread != null) {
15720                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15721                pw.flush();
15722                try {
15723                    TransferPipe tp = new TransferPipe();
15724                    try {
15725                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
15726                        tp.go(fd);
15727                    } finally {
15728                        tp.kill();
15729                    }
15730                } catch (IOException e) {
15731                    pw.println("Failure while dumping the app: " + r);
15732                    pw.flush();
15733                } catch (RemoteException e) {
15734                    pw.println("Got a RemoteException while dumping the app " + r);
15735                    pw.flush();
15736                }
15737            }
15738        }
15739    }
15740
15741    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15742        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15743        if (procs == null) {
15744            pw.println("No process found for: " + args[0]);
15745            return;
15746        }
15747
15748        pw.println("Applications Database Info:");
15749
15750        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15751            ProcessRecord r = procs.get(i);
15752            if (r.thread != null) {
15753                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15754                pw.flush();
15755                try {
15756                    TransferPipe tp = new TransferPipe();
15757                    try {
15758                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
15759                        tp.go(fd);
15760                    } finally {
15761                        tp.kill();
15762                    }
15763                } catch (IOException e) {
15764                    pw.println("Failure while dumping the app: " + r);
15765                    pw.flush();
15766                } catch (RemoteException e) {
15767                    pw.println("Got a RemoteException while dumping the app " + r);
15768                    pw.flush();
15769                }
15770            }
15771        }
15772    }
15773
15774    final static class MemItem {
15775        final boolean isProc;
15776        final String label;
15777        final String shortLabel;
15778        final long pss;
15779        final long swapPss;
15780        final int id;
15781        final boolean hasActivities;
15782        ArrayList<MemItem> subitems;
15783
15784        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15785                boolean _hasActivities) {
15786            isProc = true;
15787            label = _label;
15788            shortLabel = _shortLabel;
15789            pss = _pss;
15790            swapPss = _swapPss;
15791            id = _id;
15792            hasActivities = _hasActivities;
15793        }
15794
15795        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15796            isProc = false;
15797            label = _label;
15798            shortLabel = _shortLabel;
15799            pss = _pss;
15800            swapPss = _swapPss;
15801            id = _id;
15802            hasActivities = false;
15803        }
15804    }
15805
15806    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15807            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15808        if (sort && !isCompact) {
15809            Collections.sort(items, new Comparator<MemItem>() {
15810                @Override
15811                public int compare(MemItem lhs, MemItem rhs) {
15812                    if (lhs.pss < rhs.pss) {
15813                        return 1;
15814                    } else if (lhs.pss > rhs.pss) {
15815                        return -1;
15816                    }
15817                    return 0;
15818                }
15819            });
15820        }
15821
15822        for (int i=0; i<items.size(); i++) {
15823            MemItem mi = items.get(i);
15824            if (!isCompact) {
15825                if (dumpSwapPss) {
15826                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15827                            mi.label, stringifyKBSize(mi.swapPss));
15828                } else {
15829                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15830                }
15831            } else if (mi.isProc) {
15832                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15833                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15834                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15835                pw.println(mi.hasActivities ? ",a" : ",e");
15836            } else {
15837                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15838                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15839            }
15840            if (mi.subitems != null) {
15841                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15842                        true, isCompact, dumpSwapPss);
15843            }
15844        }
15845    }
15846
15847    // These are in KB.
15848    static final long[] DUMP_MEM_BUCKETS = new long[] {
15849        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15850        120*1024, 160*1024, 200*1024,
15851        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15852        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15853    };
15854
15855    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15856            boolean stackLike) {
15857        int start = label.lastIndexOf('.');
15858        if (start >= 0) start++;
15859        else start = 0;
15860        int end = label.length();
15861        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15862            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15863                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15864                out.append(bucket);
15865                out.append(stackLike ? "MB." : "MB ");
15866                out.append(label, start, end);
15867                return;
15868            }
15869        }
15870        out.append(memKB/1024);
15871        out.append(stackLike ? "MB." : "MB ");
15872        out.append(label, start, end);
15873    }
15874
15875    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15876            ProcessList.NATIVE_ADJ,
15877            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15878            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15879            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15880            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15881            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15882            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15883    };
15884    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15885            "Native",
15886            "System", "Persistent", "Persistent Service", "Foreground",
15887            "Visible", "Perceptible",
15888            "Heavy Weight", "Backup",
15889            "A Services", "Home",
15890            "Previous", "B Services", "Cached"
15891    };
15892    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15893            "native",
15894            "sys", "pers", "persvc", "fore",
15895            "vis", "percept",
15896            "heavy", "backup",
15897            "servicea", "home",
15898            "prev", "serviceb", "cached"
15899    };
15900
15901    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15902            long realtime, boolean isCheckinRequest, boolean isCompact) {
15903        if (isCompact) {
15904            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15905        }
15906        if (isCheckinRequest || isCompact) {
15907            // short checkin version
15908            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15909        } else {
15910            pw.println("Applications Memory Usage (in Kilobytes):");
15911            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15912        }
15913    }
15914
15915    private static final int KSM_SHARED = 0;
15916    private static final int KSM_SHARING = 1;
15917    private static final int KSM_UNSHARED = 2;
15918    private static final int KSM_VOLATILE = 3;
15919
15920    private final long[] getKsmInfo() {
15921        long[] longOut = new long[4];
15922        final int[] SINGLE_LONG_FORMAT = new int[] {
15923            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15924        };
15925        long[] longTmp = new long[1];
15926        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15927                SINGLE_LONG_FORMAT, null, longTmp, null);
15928        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15929        longTmp[0] = 0;
15930        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15931                SINGLE_LONG_FORMAT, null, longTmp, null);
15932        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15933        longTmp[0] = 0;
15934        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15935                SINGLE_LONG_FORMAT, null, longTmp, null);
15936        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15937        longTmp[0] = 0;
15938        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15939                SINGLE_LONG_FORMAT, null, longTmp, null);
15940        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15941        return longOut;
15942    }
15943
15944    private static String stringifySize(long size, int order) {
15945        Locale locale = Locale.US;
15946        switch (order) {
15947            case 1:
15948                return String.format(locale, "%,13d", size);
15949            case 1024:
15950                return String.format(locale, "%,9dK", size / 1024);
15951            case 1024 * 1024:
15952                return String.format(locale, "%,5dM", size / 1024 / 1024);
15953            case 1024 * 1024 * 1024:
15954                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15955            default:
15956                throw new IllegalArgumentException("Invalid size order");
15957        }
15958    }
15959
15960    private static String stringifyKBSize(long size) {
15961        return stringifySize(size * 1024, 1024);
15962    }
15963
15964    // Update this version number in case you change the 'compact' format
15965    private static final int MEMINFO_COMPACT_VERSION = 1;
15966
15967    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15968            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15969        boolean dumpDetails = false;
15970        boolean dumpFullDetails = false;
15971        boolean dumpDalvik = false;
15972        boolean dumpSummaryOnly = false;
15973        boolean dumpUnreachable = false;
15974        boolean oomOnly = false;
15975        boolean isCompact = false;
15976        boolean localOnly = false;
15977        boolean packages = false;
15978        boolean isCheckinRequest = false;
15979        boolean dumpSwapPss = false;
15980
15981        int opti = 0;
15982        while (opti < args.length) {
15983            String opt = args[opti];
15984            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15985                break;
15986            }
15987            opti++;
15988            if ("-a".equals(opt)) {
15989                dumpDetails = true;
15990                dumpFullDetails = true;
15991                dumpDalvik = true;
15992                dumpSwapPss = true;
15993            } else if ("-d".equals(opt)) {
15994                dumpDalvik = true;
15995            } else if ("-c".equals(opt)) {
15996                isCompact = true;
15997            } else if ("-s".equals(opt)) {
15998                dumpDetails = true;
15999                dumpSummaryOnly = true;
16000            } else if ("-S".equals(opt)) {
16001                dumpSwapPss = true;
16002            } else if ("--unreachable".equals(opt)) {
16003                dumpUnreachable = true;
16004            } else if ("--oom".equals(opt)) {
16005                oomOnly = true;
16006            } else if ("--local".equals(opt)) {
16007                localOnly = true;
16008            } else if ("--package".equals(opt)) {
16009                packages = true;
16010            } else if ("--checkin".equals(opt)) {
16011                isCheckinRequest = true;
16012
16013            } else if ("-h".equals(opt)) {
16014                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16015                pw.println("  -a: include all available information for each process.");
16016                pw.println("  -d: include dalvik details.");
16017                pw.println("  -c: dump in a compact machine-parseable representation.");
16018                pw.println("  -s: dump only summary of application memory usage.");
16019                pw.println("  -S: dump also SwapPss.");
16020                pw.println("  --oom: only show processes organized by oom adj.");
16021                pw.println("  --local: only collect details locally, don't call process.");
16022                pw.println("  --package: interpret process arg as package, dumping all");
16023                pw.println("             processes that have loaded that package.");
16024                pw.println("  --checkin: dump data for a checkin");
16025                pw.println("If [process] is specified it can be the name or ");
16026                pw.println("pid of a specific process to dump.");
16027                return;
16028            } else {
16029                pw.println("Unknown argument: " + opt + "; use -h for help");
16030            }
16031        }
16032
16033        long uptime = SystemClock.uptimeMillis();
16034        long realtime = SystemClock.elapsedRealtime();
16035        final long[] tmpLong = new long[1];
16036
16037        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16038        if (procs == null) {
16039            // No Java processes.  Maybe they want to print a native process.
16040            if (args != null && args.length > opti
16041                    && args[opti].charAt(0) != '-') {
16042                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16043                        = new ArrayList<ProcessCpuTracker.Stats>();
16044                updateCpuStatsNow();
16045                int findPid = -1;
16046                try {
16047                    findPid = Integer.parseInt(args[opti]);
16048                } catch (NumberFormatException e) {
16049                }
16050                synchronized (mProcessCpuTracker) {
16051                    final int N = mProcessCpuTracker.countStats();
16052                    for (int i=0; i<N; i++) {
16053                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16054                        if (st.pid == findPid || (st.baseName != null
16055                                && st.baseName.equals(args[opti]))) {
16056                            nativeProcs.add(st);
16057                        }
16058                    }
16059                }
16060                if (nativeProcs.size() > 0) {
16061                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16062                            isCompact);
16063                    Debug.MemoryInfo mi = null;
16064                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16065                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16066                        final int pid = r.pid;
16067                        if (!isCheckinRequest && dumpDetails) {
16068                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16069                        }
16070                        if (mi == null) {
16071                            mi = new Debug.MemoryInfo();
16072                        }
16073                        if (dumpDetails || (!brief && !oomOnly)) {
16074                            Debug.getMemoryInfo(pid, mi);
16075                        } else {
16076                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16077                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16078                        }
16079                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16080                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16081                        if (isCheckinRequest) {
16082                            pw.println();
16083                        }
16084                    }
16085                    return;
16086                }
16087            }
16088            pw.println("No process found for: " + args[opti]);
16089            return;
16090        }
16091
16092        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16093            dumpDetails = true;
16094        }
16095
16096        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16097
16098        String[] innerArgs = new String[args.length-opti];
16099        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16100
16101        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16102        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16103        long nativePss = 0;
16104        long nativeSwapPss = 0;
16105        long dalvikPss = 0;
16106        long dalvikSwapPss = 0;
16107        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16108                EmptyArray.LONG;
16109        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16110                EmptyArray.LONG;
16111        long otherPss = 0;
16112        long otherSwapPss = 0;
16113        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16114        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16115
16116        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16117        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16118        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16119                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16120
16121        long totalPss = 0;
16122        long totalSwapPss = 0;
16123        long cachedPss = 0;
16124        long cachedSwapPss = 0;
16125        boolean hasSwapPss = false;
16126
16127        Debug.MemoryInfo mi = null;
16128        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16129            final ProcessRecord r = procs.get(i);
16130            final IApplicationThread thread;
16131            final int pid;
16132            final int oomAdj;
16133            final boolean hasActivities;
16134            synchronized (this) {
16135                thread = r.thread;
16136                pid = r.pid;
16137                oomAdj = r.getSetAdjWithServices();
16138                hasActivities = r.activities.size() > 0;
16139            }
16140            if (thread != null) {
16141                if (!isCheckinRequest && dumpDetails) {
16142                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16143                }
16144                if (mi == null) {
16145                    mi = new Debug.MemoryInfo();
16146                }
16147                if (dumpDetails || (!brief && !oomOnly)) {
16148                    Debug.getMemoryInfo(pid, mi);
16149                    hasSwapPss = mi.hasSwappedOutPss;
16150                } else {
16151                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16152                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16153                }
16154                if (dumpDetails) {
16155                    if (localOnly) {
16156                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16157                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16158                        if (isCheckinRequest) {
16159                            pw.println();
16160                        }
16161                    } else {
16162                        pw.flush();
16163                        try {
16164                            TransferPipe tp = new TransferPipe();
16165                            try {
16166                                thread.dumpMemInfo(tp.getWriteFd(),
16167                                        mi, isCheckinRequest, dumpFullDetails,
16168                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16169                                tp.go(fd);
16170                            } finally {
16171                                tp.kill();
16172                            }
16173                        } catch (IOException e) {
16174                            if (!isCheckinRequest) {
16175                                pw.println("Got IoException!");
16176                                pw.flush();
16177                            }
16178                        } catch (RemoteException e) {
16179                            if (!isCheckinRequest) {
16180                                pw.println("Got RemoteException!");
16181                                pw.flush();
16182                            }
16183                        }
16184                    }
16185                }
16186
16187                final long myTotalPss = mi.getTotalPss();
16188                final long myTotalUss = mi.getTotalUss();
16189                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16190
16191                synchronized (this) {
16192                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16193                        // Record this for posterity if the process has been stable.
16194                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16195                    }
16196                }
16197
16198                if (!isCheckinRequest && mi != null) {
16199                    totalPss += myTotalPss;
16200                    totalSwapPss += myTotalSwapPss;
16201                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16202                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16203                            myTotalSwapPss, pid, hasActivities);
16204                    procMems.add(pssItem);
16205                    procMemsMap.put(pid, pssItem);
16206
16207                    nativePss += mi.nativePss;
16208                    nativeSwapPss += mi.nativeSwappedOutPss;
16209                    dalvikPss += mi.dalvikPss;
16210                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16211                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16212                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16213                        dalvikSubitemSwapPss[j] +=
16214                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16215                    }
16216                    otherPss += mi.otherPss;
16217                    otherSwapPss += mi.otherSwappedOutPss;
16218                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16219                        long mem = mi.getOtherPss(j);
16220                        miscPss[j] += mem;
16221                        otherPss -= mem;
16222                        mem = mi.getOtherSwappedOutPss(j);
16223                        miscSwapPss[j] += mem;
16224                        otherSwapPss -= mem;
16225                    }
16226
16227                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16228                        cachedPss += myTotalPss;
16229                        cachedSwapPss += myTotalSwapPss;
16230                    }
16231
16232                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16233                        if (oomIndex == (oomPss.length - 1)
16234                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16235                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16236                            oomPss[oomIndex] += myTotalPss;
16237                            oomSwapPss[oomIndex] += myTotalSwapPss;
16238                            if (oomProcs[oomIndex] == null) {
16239                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16240                            }
16241                            oomProcs[oomIndex].add(pssItem);
16242                            break;
16243                        }
16244                    }
16245                }
16246            }
16247        }
16248
16249        long nativeProcTotalPss = 0;
16250
16251        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16252            // If we are showing aggregations, also look for native processes to
16253            // include so that our aggregations are more accurate.
16254            updateCpuStatsNow();
16255            mi = null;
16256            synchronized (mProcessCpuTracker) {
16257                final int N = mProcessCpuTracker.countStats();
16258                for (int i=0; i<N; i++) {
16259                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16260                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16261                        if (mi == null) {
16262                            mi = new Debug.MemoryInfo();
16263                        }
16264                        if (!brief && !oomOnly) {
16265                            Debug.getMemoryInfo(st.pid, mi);
16266                        } else {
16267                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16268                            mi.nativePrivateDirty = (int)tmpLong[0];
16269                        }
16270
16271                        final long myTotalPss = mi.getTotalPss();
16272                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16273                        totalPss += myTotalPss;
16274                        nativeProcTotalPss += myTotalPss;
16275
16276                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16277                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16278                        procMems.add(pssItem);
16279
16280                        nativePss += mi.nativePss;
16281                        nativeSwapPss += mi.nativeSwappedOutPss;
16282                        dalvikPss += mi.dalvikPss;
16283                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16284                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16285                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16286                            dalvikSubitemSwapPss[j] +=
16287                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16288                        }
16289                        otherPss += mi.otherPss;
16290                        otherSwapPss += mi.otherSwappedOutPss;
16291                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16292                            long mem = mi.getOtherPss(j);
16293                            miscPss[j] += mem;
16294                            otherPss -= mem;
16295                            mem = mi.getOtherSwappedOutPss(j);
16296                            miscSwapPss[j] += mem;
16297                            otherSwapPss -= mem;
16298                        }
16299                        oomPss[0] += myTotalPss;
16300                        oomSwapPss[0] += myTotalSwapPss;
16301                        if (oomProcs[0] == null) {
16302                            oomProcs[0] = new ArrayList<MemItem>();
16303                        }
16304                        oomProcs[0].add(pssItem);
16305                    }
16306                }
16307            }
16308
16309            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16310
16311            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16312            final MemItem dalvikItem =
16313                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16314            if (dalvikSubitemPss.length > 0) {
16315                dalvikItem.subitems = new ArrayList<MemItem>();
16316                for (int j=0; j<dalvikSubitemPss.length; j++) {
16317                    final String name = Debug.MemoryInfo.getOtherLabel(
16318                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16319                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16320                                    dalvikSubitemSwapPss[j], j));
16321                }
16322            }
16323            catMems.add(dalvikItem);
16324            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16325            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16326                String label = Debug.MemoryInfo.getOtherLabel(j);
16327                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16328            }
16329
16330            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16331            for (int j=0; j<oomPss.length; j++) {
16332                if (oomPss[j] != 0) {
16333                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16334                            : DUMP_MEM_OOM_LABEL[j];
16335                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16336                            DUMP_MEM_OOM_ADJ[j]);
16337                    item.subitems = oomProcs[j];
16338                    oomMems.add(item);
16339                }
16340            }
16341
16342            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16343            if (!brief && !oomOnly && !isCompact) {
16344                pw.println();
16345                pw.println("Total PSS by process:");
16346                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16347                pw.println();
16348            }
16349            if (!isCompact) {
16350                pw.println("Total PSS by OOM adjustment:");
16351            }
16352            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16353            if (!brief && !oomOnly) {
16354                PrintWriter out = categoryPw != null ? categoryPw : pw;
16355                if (!isCompact) {
16356                    out.println();
16357                    out.println("Total PSS by category:");
16358                }
16359                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16360            }
16361            if (!isCompact) {
16362                pw.println();
16363            }
16364            MemInfoReader memInfo = new MemInfoReader();
16365            memInfo.readMemInfo();
16366            if (nativeProcTotalPss > 0) {
16367                synchronized (this) {
16368                    final long cachedKb = memInfo.getCachedSizeKb();
16369                    final long freeKb = memInfo.getFreeSizeKb();
16370                    final long zramKb = memInfo.getZramTotalSizeKb();
16371                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16372                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16373                            kernelKb*1024, nativeProcTotalPss*1024);
16374                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16375                            nativeProcTotalPss);
16376                }
16377            }
16378            if (!brief) {
16379                if (!isCompact) {
16380                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16381                    pw.print(" (status ");
16382                    switch (mLastMemoryLevel) {
16383                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16384                            pw.println("normal)");
16385                            break;
16386                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16387                            pw.println("moderate)");
16388                            break;
16389                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16390                            pw.println("low)");
16391                            break;
16392                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16393                            pw.println("critical)");
16394                            break;
16395                        default:
16396                            pw.print(mLastMemoryLevel);
16397                            pw.println(")");
16398                            break;
16399                    }
16400                    pw.print(" Free RAM: ");
16401                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16402                            + memInfo.getFreeSizeKb()));
16403                    pw.print(" (");
16404                    pw.print(stringifyKBSize(cachedPss));
16405                    pw.print(" cached pss + ");
16406                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16407                    pw.print(" cached kernel + ");
16408                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16409                    pw.println(" free)");
16410                } else {
16411                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16412                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16413                            + memInfo.getFreeSizeKb()); pw.print(",");
16414                    pw.println(totalPss - cachedPss);
16415                }
16416            }
16417            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16418                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16419                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16420            if (!isCompact) {
16421                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16422                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16423                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16424                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16425                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16426            } else {
16427                pw.print("lostram,"); pw.println(lostRAM);
16428            }
16429            if (!brief) {
16430                if (memInfo.getZramTotalSizeKb() != 0) {
16431                    if (!isCompact) {
16432                        pw.print("     ZRAM: ");
16433                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16434                                pw.print(" physical used for ");
16435                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16436                                        - memInfo.getSwapFreeSizeKb()));
16437                                pw.print(" in swap (");
16438                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16439                                pw.println(" total swap)");
16440                    } else {
16441                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16442                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16443                                pw.println(memInfo.getSwapFreeSizeKb());
16444                    }
16445                }
16446                final long[] ksm = getKsmInfo();
16447                if (!isCompact) {
16448                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16449                            || ksm[KSM_VOLATILE] != 0) {
16450                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16451                                pw.print(" saved from shared ");
16452                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16453                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16454                                pw.print(" unshared; ");
16455                                pw.print(stringifyKBSize(
16456                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16457                    }
16458                    pw.print("   Tuning: ");
16459                    pw.print(ActivityManager.staticGetMemoryClass());
16460                    pw.print(" (large ");
16461                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16462                    pw.print("), oom ");
16463                    pw.print(stringifySize(
16464                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16465                    pw.print(", restore limit ");
16466                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16467                    if (ActivityManager.isLowRamDeviceStatic()) {
16468                        pw.print(" (low-ram)");
16469                    }
16470                    if (ActivityManager.isHighEndGfx()) {
16471                        pw.print(" (high-end-gfx)");
16472                    }
16473                    pw.println();
16474                } else {
16475                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16476                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16477                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16478                    pw.print("tuning,");
16479                    pw.print(ActivityManager.staticGetMemoryClass());
16480                    pw.print(',');
16481                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16482                    pw.print(',');
16483                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16484                    if (ActivityManager.isLowRamDeviceStatic()) {
16485                        pw.print(",low-ram");
16486                    }
16487                    if (ActivityManager.isHighEndGfx()) {
16488                        pw.print(",high-end-gfx");
16489                    }
16490                    pw.println();
16491                }
16492            }
16493        }
16494    }
16495
16496    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16497            long memtrack, String name) {
16498        sb.append("  ");
16499        sb.append(ProcessList.makeOomAdjString(oomAdj));
16500        sb.append(' ');
16501        sb.append(ProcessList.makeProcStateString(procState));
16502        sb.append(' ');
16503        ProcessList.appendRamKb(sb, pss);
16504        sb.append(": ");
16505        sb.append(name);
16506        if (memtrack > 0) {
16507            sb.append(" (");
16508            sb.append(stringifyKBSize(memtrack));
16509            sb.append(" memtrack)");
16510        }
16511    }
16512
16513    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16514        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16515        sb.append(" (pid ");
16516        sb.append(mi.pid);
16517        sb.append(") ");
16518        sb.append(mi.adjType);
16519        sb.append('\n');
16520        if (mi.adjReason != null) {
16521            sb.append("                      ");
16522            sb.append(mi.adjReason);
16523            sb.append('\n');
16524        }
16525    }
16526
16527    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16528        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16529        for (int i=0, N=memInfos.size(); i<N; i++) {
16530            ProcessMemInfo mi = memInfos.get(i);
16531            infoMap.put(mi.pid, mi);
16532        }
16533        updateCpuStatsNow();
16534        long[] memtrackTmp = new long[1];
16535        final List<ProcessCpuTracker.Stats> stats;
16536        // Get a list of Stats that have vsize > 0
16537        synchronized (mProcessCpuTracker) {
16538            stats = mProcessCpuTracker.getStats((st) -> {
16539                return st.vsize > 0;
16540            });
16541        }
16542        final int statsCount = stats.size();
16543        for (int i = 0; i < statsCount; i++) {
16544            ProcessCpuTracker.Stats st = stats.get(i);
16545            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16546            if (pss > 0) {
16547                if (infoMap.indexOfKey(st.pid) < 0) {
16548                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16549                            ProcessList.NATIVE_ADJ, -1, "native", null);
16550                    mi.pss = pss;
16551                    mi.memtrack = memtrackTmp[0];
16552                    memInfos.add(mi);
16553                }
16554            }
16555        }
16556
16557        long totalPss = 0;
16558        long totalMemtrack = 0;
16559        for (int i=0, N=memInfos.size(); i<N; i++) {
16560            ProcessMemInfo mi = memInfos.get(i);
16561            if (mi.pss == 0) {
16562                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16563                mi.memtrack = memtrackTmp[0];
16564            }
16565            totalPss += mi.pss;
16566            totalMemtrack += mi.memtrack;
16567        }
16568        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16569            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16570                if (lhs.oomAdj != rhs.oomAdj) {
16571                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16572                }
16573                if (lhs.pss != rhs.pss) {
16574                    return lhs.pss < rhs.pss ? 1 : -1;
16575                }
16576                return 0;
16577            }
16578        });
16579
16580        StringBuilder tag = new StringBuilder(128);
16581        StringBuilder stack = new StringBuilder(128);
16582        tag.append("Low on memory -- ");
16583        appendMemBucket(tag, totalPss, "total", false);
16584        appendMemBucket(stack, totalPss, "total", true);
16585
16586        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16587        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16588        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16589
16590        boolean firstLine = true;
16591        int lastOomAdj = Integer.MIN_VALUE;
16592        long extraNativeRam = 0;
16593        long extraNativeMemtrack = 0;
16594        long cachedPss = 0;
16595        for (int i=0, N=memInfos.size(); i<N; i++) {
16596            ProcessMemInfo mi = memInfos.get(i);
16597
16598            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16599                cachedPss += mi.pss;
16600            }
16601
16602            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16603                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16604                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16605                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16606                if (lastOomAdj != mi.oomAdj) {
16607                    lastOomAdj = mi.oomAdj;
16608                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16609                        tag.append(" / ");
16610                    }
16611                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16612                        if (firstLine) {
16613                            stack.append(":");
16614                            firstLine = false;
16615                        }
16616                        stack.append("\n\t at ");
16617                    } else {
16618                        stack.append("$");
16619                    }
16620                } else {
16621                    tag.append(" ");
16622                    stack.append("$");
16623                }
16624                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16625                    appendMemBucket(tag, mi.pss, mi.name, false);
16626                }
16627                appendMemBucket(stack, mi.pss, mi.name, true);
16628                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16629                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16630                    stack.append("(");
16631                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16632                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16633                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16634                            stack.append(":");
16635                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16636                        }
16637                    }
16638                    stack.append(")");
16639                }
16640            }
16641
16642            appendMemInfo(fullNativeBuilder, mi);
16643            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16644                // The short form only has native processes that are >= 512K.
16645                if (mi.pss >= 512) {
16646                    appendMemInfo(shortNativeBuilder, mi);
16647                } else {
16648                    extraNativeRam += mi.pss;
16649                    extraNativeMemtrack += mi.memtrack;
16650                }
16651            } else {
16652                // Short form has all other details, but if we have collected RAM
16653                // from smaller native processes let's dump a summary of that.
16654                if (extraNativeRam > 0) {
16655                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16656                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16657                    shortNativeBuilder.append('\n');
16658                    extraNativeRam = 0;
16659                }
16660                appendMemInfo(fullJavaBuilder, mi);
16661            }
16662        }
16663
16664        fullJavaBuilder.append("           ");
16665        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16666        fullJavaBuilder.append(": TOTAL");
16667        if (totalMemtrack > 0) {
16668            fullJavaBuilder.append(" (");
16669            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16670            fullJavaBuilder.append(" memtrack)");
16671        } else {
16672        }
16673        fullJavaBuilder.append("\n");
16674
16675        MemInfoReader memInfo = new MemInfoReader();
16676        memInfo.readMemInfo();
16677        final long[] infos = memInfo.getRawInfo();
16678
16679        StringBuilder memInfoBuilder = new StringBuilder(1024);
16680        Debug.getMemInfo(infos);
16681        memInfoBuilder.append("  MemInfo: ");
16682        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16683        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16684        memInfoBuilder.append(stringifyKBSize(
16685                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16686        memInfoBuilder.append(stringifyKBSize(
16687                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16688        memInfoBuilder.append(stringifyKBSize(
16689                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16690        memInfoBuilder.append("           ");
16691        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16692        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16693        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16694        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16695        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16696            memInfoBuilder.append("  ZRAM: ");
16697            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16698            memInfoBuilder.append(" RAM, ");
16699            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16700            memInfoBuilder.append(" swap total, ");
16701            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16702            memInfoBuilder.append(" swap free\n");
16703        }
16704        final long[] ksm = getKsmInfo();
16705        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16706                || ksm[KSM_VOLATILE] != 0) {
16707            memInfoBuilder.append("  KSM: ");
16708            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16709            memInfoBuilder.append(" saved from shared ");
16710            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16711            memInfoBuilder.append("\n       ");
16712            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16713            memInfoBuilder.append(" unshared; ");
16714            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16715            memInfoBuilder.append(" volatile\n");
16716        }
16717        memInfoBuilder.append("  Free RAM: ");
16718        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16719                + memInfo.getFreeSizeKb()));
16720        memInfoBuilder.append("\n");
16721        memInfoBuilder.append("  Used RAM: ");
16722        memInfoBuilder.append(stringifyKBSize(
16723                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16724        memInfoBuilder.append("\n");
16725        memInfoBuilder.append("  Lost RAM: ");
16726        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16727                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16728                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16729        memInfoBuilder.append("\n");
16730        Slog.i(TAG, "Low on memory:");
16731        Slog.i(TAG, shortNativeBuilder.toString());
16732        Slog.i(TAG, fullJavaBuilder.toString());
16733        Slog.i(TAG, memInfoBuilder.toString());
16734
16735        StringBuilder dropBuilder = new StringBuilder(1024);
16736        /*
16737        StringWriter oomSw = new StringWriter();
16738        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16739        StringWriter catSw = new StringWriter();
16740        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16741        String[] emptyArgs = new String[] { };
16742        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16743        oomPw.flush();
16744        String oomString = oomSw.toString();
16745        */
16746        dropBuilder.append("Low on memory:");
16747        dropBuilder.append(stack);
16748        dropBuilder.append('\n');
16749        dropBuilder.append(fullNativeBuilder);
16750        dropBuilder.append(fullJavaBuilder);
16751        dropBuilder.append('\n');
16752        dropBuilder.append(memInfoBuilder);
16753        dropBuilder.append('\n');
16754        /*
16755        dropBuilder.append(oomString);
16756        dropBuilder.append('\n');
16757        */
16758        StringWriter catSw = new StringWriter();
16759        synchronized (ActivityManagerService.this) {
16760            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16761            String[] emptyArgs = new String[] { };
16762            catPw.println();
16763            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16764            catPw.println();
16765            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16766                    false, null).dumpLocked();
16767            catPw.println();
16768            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16769            catPw.flush();
16770        }
16771        dropBuilder.append(catSw.toString());
16772        addErrorToDropBox("lowmem", null, "system_server", null,
16773                null, tag.toString(), dropBuilder.toString(), null, null);
16774        //Slog.i(TAG, "Sent to dropbox:");
16775        //Slog.i(TAG, dropBuilder.toString());
16776        synchronized (ActivityManagerService.this) {
16777            long now = SystemClock.uptimeMillis();
16778            if (mLastMemUsageReportTime < now) {
16779                mLastMemUsageReportTime = now;
16780            }
16781        }
16782    }
16783
16784    /**
16785     * Searches array of arguments for the specified string
16786     * @param args array of argument strings
16787     * @param value value to search for
16788     * @return true if the value is contained in the array
16789     */
16790    private static boolean scanArgs(String[] args, String value) {
16791        if (args != null) {
16792            for (String arg : args) {
16793                if (value.equals(arg)) {
16794                    return true;
16795                }
16796            }
16797        }
16798        return false;
16799    }
16800
16801    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16802            ContentProviderRecord cpr, boolean always) {
16803        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16804
16805        if (!inLaunching || always) {
16806            synchronized (cpr) {
16807                cpr.launchingApp = null;
16808                cpr.notifyAll();
16809            }
16810            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16811            String names[] = cpr.info.authority.split(";");
16812            for (int j = 0; j < names.length; j++) {
16813                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16814            }
16815        }
16816
16817        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16818            ContentProviderConnection conn = cpr.connections.get(i);
16819            if (conn.waiting) {
16820                // If this connection is waiting for the provider, then we don't
16821                // need to mess with its process unless we are always removing
16822                // or for some reason the provider is not currently launching.
16823                if (inLaunching && !always) {
16824                    continue;
16825                }
16826            }
16827            ProcessRecord capp = conn.client;
16828            conn.dead = true;
16829            if (conn.stableCount > 0) {
16830                if (!capp.persistent && capp.thread != null
16831                        && capp.pid != 0
16832                        && capp.pid != MY_PID) {
16833                    capp.kill("depends on provider "
16834                            + cpr.name.flattenToShortString()
16835                            + " in dying proc " + (proc != null ? proc.processName : "??")
16836                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16837                }
16838            } else if (capp.thread != null && conn.provider.provider != null) {
16839                try {
16840                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16841                } catch (RemoteException e) {
16842                }
16843                // In the protocol here, we don't expect the client to correctly
16844                // clean up this connection, we'll just remove it.
16845                cpr.connections.remove(i);
16846                if (conn.client.conProviders.remove(conn)) {
16847                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16848                }
16849            }
16850        }
16851
16852        if (inLaunching && always) {
16853            mLaunchingProviders.remove(cpr);
16854        }
16855        return inLaunching;
16856    }
16857
16858    /**
16859     * Main code for cleaning up a process when it has gone away.  This is
16860     * called both as a result of the process dying, or directly when stopping
16861     * a process when running in single process mode.
16862     *
16863     * @return Returns true if the given process has been restarted, so the
16864     * app that was passed in must remain on the process lists.
16865     */
16866    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16867            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16868        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16869        if (index >= 0) {
16870            removeLruProcessLocked(app);
16871            ProcessList.remove(app.pid);
16872        }
16873
16874        mProcessesToGc.remove(app);
16875        mPendingPssProcesses.remove(app);
16876
16877        // Dismiss any open dialogs.
16878        if (app.crashDialog != null && !app.forceCrashReport) {
16879            app.crashDialog.dismiss();
16880            app.crashDialog = null;
16881        }
16882        if (app.anrDialog != null) {
16883            app.anrDialog.dismiss();
16884            app.anrDialog = null;
16885        }
16886        if (app.waitDialog != null) {
16887            app.waitDialog.dismiss();
16888            app.waitDialog = null;
16889        }
16890
16891        app.crashing = false;
16892        app.notResponding = false;
16893
16894        app.resetPackageList(mProcessStats);
16895        app.unlinkDeathRecipient();
16896        app.makeInactive(mProcessStats);
16897        app.waitingToKill = null;
16898        app.forcingToForeground = null;
16899        updateProcessForegroundLocked(app, false, false);
16900        app.foregroundActivities = false;
16901        app.hasShownUi = false;
16902        app.treatLikeActivity = false;
16903        app.hasAboveClient = false;
16904        app.hasClientActivities = false;
16905
16906        mServices.killServicesLocked(app, allowRestart);
16907
16908        boolean restart = false;
16909
16910        // Remove published content providers.
16911        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16912            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16913            final boolean always = app.bad || !allowRestart;
16914            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16915            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16916                // We left the provider in the launching list, need to
16917                // restart it.
16918                restart = true;
16919            }
16920
16921            cpr.provider = null;
16922            cpr.proc = null;
16923        }
16924        app.pubProviders.clear();
16925
16926        // Take care of any launching providers waiting for this process.
16927        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16928            restart = true;
16929        }
16930
16931        // Unregister from connected content providers.
16932        if (!app.conProviders.isEmpty()) {
16933            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16934                ContentProviderConnection conn = app.conProviders.get(i);
16935                conn.provider.connections.remove(conn);
16936                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16937                        conn.provider.name);
16938            }
16939            app.conProviders.clear();
16940        }
16941
16942        // At this point there may be remaining entries in mLaunchingProviders
16943        // where we were the only one waiting, so they are no longer of use.
16944        // Look for these and clean up if found.
16945        // XXX Commented out for now.  Trying to figure out a way to reproduce
16946        // the actual situation to identify what is actually going on.
16947        if (false) {
16948            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16949                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16950                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16951                    synchronized (cpr) {
16952                        cpr.launchingApp = null;
16953                        cpr.notifyAll();
16954                    }
16955                }
16956            }
16957        }
16958
16959        skipCurrentReceiverLocked(app);
16960
16961        // Unregister any receivers.
16962        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16963            removeReceiverLocked(app.receivers.valueAt(i));
16964        }
16965        app.receivers.clear();
16966
16967        // If the app is undergoing backup, tell the backup manager about it
16968        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16969            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16970                    + mBackupTarget.appInfo + " died during backup");
16971            mHandler.post(new Runnable() {
16972                @Override
16973                public void run(){
16974                    try {
16975                        IBackupManager bm = IBackupManager.Stub.asInterface(
16976                                ServiceManager.getService(Context.BACKUP_SERVICE));
16977                        bm.agentDisconnected(app.info.packageName);
16978                    } catch (RemoteException e) {
16979                        // can't happen; backup manager is local
16980                    }
16981                }
16982            });
16983        }
16984
16985        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16986            ProcessChangeItem item = mPendingProcessChanges.get(i);
16987            if (item.pid == app.pid) {
16988                mPendingProcessChanges.remove(i);
16989                mAvailProcessChanges.add(item);
16990            }
16991        }
16992        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16993                null).sendToTarget();
16994
16995        // If the caller is restarting this app, then leave it in its
16996        // current lists and let the caller take care of it.
16997        if (restarting) {
16998            return false;
16999        }
17000
17001        if (!app.persistent || app.isolated) {
17002            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17003                    "Removing non-persistent process during cleanup: " + app);
17004            if (!replacingPid) {
17005                removeProcessNameLocked(app.processName, app.uid);
17006            }
17007            if (mHeavyWeightProcess == app) {
17008                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17009                        mHeavyWeightProcess.userId, 0));
17010                mHeavyWeightProcess = null;
17011            }
17012        } else if (!app.removed) {
17013            // This app is persistent, so we need to keep its record around.
17014            // If it is not already on the pending app list, add it there
17015            // and start a new process for it.
17016            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17017                mPersistentStartingProcesses.add(app);
17018                restart = true;
17019            }
17020        }
17021        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17022                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17023        mProcessesOnHold.remove(app);
17024
17025        if (app == mHomeProcess) {
17026            mHomeProcess = null;
17027        }
17028        if (app == mPreviousProcess) {
17029            mPreviousProcess = null;
17030        }
17031
17032        if (restart && !app.isolated) {
17033            // We have components that still need to be running in the
17034            // process, so re-launch it.
17035            if (index < 0) {
17036                ProcessList.remove(app.pid);
17037            }
17038            addProcessNameLocked(app);
17039            startProcessLocked(app, "restart", app.processName);
17040            return true;
17041        } else if (app.pid > 0 && app.pid != MY_PID) {
17042            // Goodbye!
17043            boolean removed;
17044            synchronized (mPidsSelfLocked) {
17045                mPidsSelfLocked.remove(app.pid);
17046                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17047            }
17048            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17049            if (app.isolated) {
17050                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17051            }
17052            app.setPid(0);
17053        }
17054        return false;
17055    }
17056
17057    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17058        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17059            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17060            if (cpr.launchingApp == app) {
17061                return true;
17062            }
17063        }
17064        return false;
17065    }
17066
17067    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17068        // Look through the content providers we are waiting to have launched,
17069        // and if any run in this process then either schedule a restart of
17070        // the process or kill the client waiting for it if this process has
17071        // gone bad.
17072        boolean restart = false;
17073        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17074            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17075            if (cpr.launchingApp == app) {
17076                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17077                    restart = true;
17078                } else {
17079                    removeDyingProviderLocked(app, cpr, true);
17080                }
17081            }
17082        }
17083        return restart;
17084    }
17085
17086    // =========================================================
17087    // SERVICES
17088    // =========================================================
17089
17090    @Override
17091    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17092            int flags) {
17093        enforceNotIsolatedCaller("getServices");
17094        synchronized (this) {
17095            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17096        }
17097    }
17098
17099    @Override
17100    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17101        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17102        synchronized (this) {
17103            return mServices.getRunningServiceControlPanelLocked(name);
17104        }
17105    }
17106
17107    @Override
17108    public ComponentName startService(IApplicationThread caller, Intent service,
17109            String resolvedType, String callingPackage, int userId)
17110            throws TransactionTooLargeException {
17111        enforceNotIsolatedCaller("startService");
17112        // Refuse possible leaked file descriptors
17113        if (service != null && service.hasFileDescriptors() == true) {
17114            throw new IllegalArgumentException("File descriptors passed in Intent");
17115        }
17116
17117        if (callingPackage == null) {
17118            throw new IllegalArgumentException("callingPackage cannot be null");
17119        }
17120
17121        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17122                "startService: " + service + " type=" + resolvedType);
17123        synchronized(this) {
17124            final int callingPid = Binder.getCallingPid();
17125            final int callingUid = Binder.getCallingUid();
17126            final long origId = Binder.clearCallingIdentity();
17127            ComponentName res = mServices.startServiceLocked(caller, service,
17128                    resolvedType, callingPid, callingUid, callingPackage, userId);
17129            Binder.restoreCallingIdentity(origId);
17130            return res;
17131        }
17132    }
17133
17134    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17135            String callingPackage, int userId)
17136            throws TransactionTooLargeException {
17137        synchronized(this) {
17138            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17139                    "startServiceInPackage: " + service + " type=" + resolvedType);
17140            final long origId = Binder.clearCallingIdentity();
17141            ComponentName res = mServices.startServiceLocked(null, service,
17142                    resolvedType, -1, uid, callingPackage, userId);
17143            Binder.restoreCallingIdentity(origId);
17144            return res;
17145        }
17146    }
17147
17148    @Override
17149    public int stopService(IApplicationThread caller, Intent service,
17150            String resolvedType, int userId) {
17151        enforceNotIsolatedCaller("stopService");
17152        // Refuse possible leaked file descriptors
17153        if (service != null && service.hasFileDescriptors() == true) {
17154            throw new IllegalArgumentException("File descriptors passed in Intent");
17155        }
17156
17157        synchronized(this) {
17158            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17159        }
17160    }
17161
17162    @Override
17163    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17164        enforceNotIsolatedCaller("peekService");
17165        // Refuse possible leaked file descriptors
17166        if (service != null && service.hasFileDescriptors() == true) {
17167            throw new IllegalArgumentException("File descriptors passed in Intent");
17168        }
17169
17170        if (callingPackage == null) {
17171            throw new IllegalArgumentException("callingPackage cannot be null");
17172        }
17173
17174        synchronized(this) {
17175            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17176        }
17177    }
17178
17179    @Override
17180    public boolean stopServiceToken(ComponentName className, IBinder token,
17181            int startId) {
17182        synchronized(this) {
17183            return mServices.stopServiceTokenLocked(className, token, startId);
17184        }
17185    }
17186
17187    @Override
17188    public void setServiceForeground(ComponentName className, IBinder token,
17189            int id, Notification notification, int flags) {
17190        synchronized(this) {
17191            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17192        }
17193    }
17194
17195    @Override
17196    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17197            boolean requireFull, String name, String callerPackage) {
17198        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17199                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17200    }
17201
17202    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17203            String className, int flags) {
17204        boolean result = false;
17205        // For apps that don't have pre-defined UIDs, check for permission
17206        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17207            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17208                if (ActivityManager.checkUidPermission(
17209                        INTERACT_ACROSS_USERS,
17210                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17211                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17212                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17213                            + " requests FLAG_SINGLE_USER, but app does not hold "
17214                            + INTERACT_ACROSS_USERS;
17215                    Slog.w(TAG, msg);
17216                    throw new SecurityException(msg);
17217                }
17218                // Permission passed
17219                result = true;
17220            }
17221        } else if ("system".equals(componentProcessName)) {
17222            result = true;
17223        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17224            // Phone app and persistent apps are allowed to export singleuser providers.
17225            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17226                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17227        }
17228        if (DEBUG_MU) Slog.v(TAG_MU,
17229                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17230                + Integer.toHexString(flags) + ") = " + result);
17231        return result;
17232    }
17233
17234    /**
17235     * Checks to see if the caller is in the same app as the singleton
17236     * component, or the component is in a special app. It allows special apps
17237     * to export singleton components but prevents exporting singleton
17238     * components for regular apps.
17239     */
17240    boolean isValidSingletonCall(int callingUid, int componentUid) {
17241        int componentAppId = UserHandle.getAppId(componentUid);
17242        return UserHandle.isSameApp(callingUid, componentUid)
17243                || componentAppId == Process.SYSTEM_UID
17244                || componentAppId == Process.PHONE_UID
17245                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17246                        == PackageManager.PERMISSION_GRANTED;
17247    }
17248
17249    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17250            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17251            int userId) throws TransactionTooLargeException {
17252        enforceNotIsolatedCaller("bindService");
17253
17254        // Refuse possible leaked file descriptors
17255        if (service != null && service.hasFileDescriptors() == true) {
17256            throw new IllegalArgumentException("File descriptors passed in Intent");
17257        }
17258
17259        if (callingPackage == null) {
17260            throw new IllegalArgumentException("callingPackage cannot be null");
17261        }
17262
17263        synchronized(this) {
17264            return mServices.bindServiceLocked(caller, token, service,
17265                    resolvedType, connection, flags, callingPackage, userId);
17266        }
17267    }
17268
17269    public boolean unbindService(IServiceConnection connection) {
17270        synchronized (this) {
17271            return mServices.unbindServiceLocked(connection);
17272        }
17273    }
17274
17275    public void publishService(IBinder token, Intent intent, IBinder service) {
17276        // Refuse possible leaked file descriptors
17277        if (intent != null && intent.hasFileDescriptors() == true) {
17278            throw new IllegalArgumentException("File descriptors passed in Intent");
17279        }
17280
17281        synchronized(this) {
17282            if (!(token instanceof ServiceRecord)) {
17283                throw new IllegalArgumentException("Invalid service token");
17284            }
17285            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17286        }
17287    }
17288
17289    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17290        // Refuse possible leaked file descriptors
17291        if (intent != null && intent.hasFileDescriptors() == true) {
17292            throw new IllegalArgumentException("File descriptors passed in Intent");
17293        }
17294
17295        synchronized(this) {
17296            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17297        }
17298    }
17299
17300    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17301        synchronized(this) {
17302            if (!(token instanceof ServiceRecord)) {
17303                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17304                throw new IllegalArgumentException("Invalid service token");
17305            }
17306            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17307        }
17308    }
17309
17310    // =========================================================
17311    // BACKUP AND RESTORE
17312    // =========================================================
17313
17314    // Cause the target app to be launched if necessary and its backup agent
17315    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17316    // activity manager to announce its creation.
17317    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17318        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17319        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17320
17321        IPackageManager pm = AppGlobals.getPackageManager();
17322        ApplicationInfo app = null;
17323        try {
17324            app = pm.getApplicationInfo(packageName, 0, userId);
17325        } catch (RemoteException e) {
17326            // can't happen; package manager is process-local
17327        }
17328        if (app == null) {
17329            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17330            return false;
17331        }
17332
17333        synchronized(this) {
17334            // !!! TODO: currently no check here that we're already bound
17335            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17336            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17337            synchronized (stats) {
17338                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17339            }
17340
17341            // Backup agent is now in use, its package can't be stopped.
17342            try {
17343                AppGlobals.getPackageManager().setPackageStoppedState(
17344                        app.packageName, false, UserHandle.getUserId(app.uid));
17345            } catch (RemoteException e) {
17346            } catch (IllegalArgumentException e) {
17347                Slog.w(TAG, "Failed trying to unstop package "
17348                        + app.packageName + ": " + e);
17349            }
17350
17351            BackupRecord r = new BackupRecord(ss, app, backupMode);
17352            ComponentName hostingName =
17353                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
17354                            ? new ComponentName(app.packageName, app.backupAgentName)
17355                            : new ComponentName("android", "FullBackupAgent");
17356            // startProcessLocked() returns existing proc's record if it's already running
17357            ProcessRecord proc = startProcessLocked(app.processName, app,
17358                    false, 0, "backup", hostingName, false, false, false);
17359            if (proc == null) {
17360                Slog.e(TAG, "Unable to start backup agent process " + r);
17361                return false;
17362            }
17363
17364            // If the app is a regular app (uid >= 10000) and not the system server or phone
17365            // process, etc, then mark it as being in full backup so that certain calls to the
17366            // process can be blocked. This is not reset to false anywhere because we kill the
17367            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17368            if (UserHandle.isApp(app.uid) &&
17369                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
17370                proc.inFullBackup = true;
17371            }
17372            r.app = proc;
17373            mBackupTarget = r;
17374            mBackupAppName = app.packageName;
17375
17376            // Try not to kill the process during backup
17377            updateOomAdjLocked(proc);
17378
17379            // If the process is already attached, schedule the creation of the backup agent now.
17380            // If it is not yet live, this will be done when it attaches to the framework.
17381            if (proc.thread != null) {
17382                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17383                try {
17384                    proc.thread.scheduleCreateBackupAgent(app,
17385                            compatibilityInfoForPackageLocked(app), backupMode);
17386                } catch (RemoteException e) {
17387                    // Will time out on the backup manager side
17388                }
17389            } else {
17390                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17391            }
17392            // Invariants: at this point, the target app process exists and the application
17393            // is either already running or in the process of coming up.  mBackupTarget and
17394            // mBackupAppName describe the app, so that when it binds back to the AM we
17395            // know that it's scheduled for a backup-agent operation.
17396        }
17397
17398        return true;
17399    }
17400
17401    @Override
17402    public void clearPendingBackup() {
17403        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17404        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17405
17406        synchronized (this) {
17407            mBackupTarget = null;
17408            mBackupAppName = null;
17409        }
17410    }
17411
17412    // A backup agent has just come up
17413    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17414        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17415                + " = " + agent);
17416
17417        synchronized(this) {
17418            if (!agentPackageName.equals(mBackupAppName)) {
17419                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17420                return;
17421            }
17422        }
17423
17424        long oldIdent = Binder.clearCallingIdentity();
17425        try {
17426            IBackupManager bm = IBackupManager.Stub.asInterface(
17427                    ServiceManager.getService(Context.BACKUP_SERVICE));
17428            bm.agentConnected(agentPackageName, agent);
17429        } catch (RemoteException e) {
17430            // can't happen; the backup manager service is local
17431        } catch (Exception e) {
17432            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17433            e.printStackTrace();
17434        } finally {
17435            Binder.restoreCallingIdentity(oldIdent);
17436        }
17437    }
17438
17439    // done with this agent
17440    public void unbindBackupAgent(ApplicationInfo appInfo) {
17441        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17442        if (appInfo == null) {
17443            Slog.w(TAG, "unbind backup agent for null app");
17444            return;
17445        }
17446
17447        synchronized(this) {
17448            try {
17449                if (mBackupAppName == null) {
17450                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17451                    return;
17452                }
17453
17454                if (!mBackupAppName.equals(appInfo.packageName)) {
17455                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17456                    return;
17457                }
17458
17459                // Not backing this app up any more; reset its OOM adjustment
17460                final ProcessRecord proc = mBackupTarget.app;
17461                updateOomAdjLocked(proc);
17462
17463                // If the app crashed during backup, 'thread' will be null here
17464                if (proc.thread != null) {
17465                    try {
17466                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17467                                compatibilityInfoForPackageLocked(appInfo));
17468                    } catch (Exception e) {
17469                        Slog.e(TAG, "Exception when unbinding backup agent:");
17470                        e.printStackTrace();
17471                    }
17472                }
17473            } finally {
17474                mBackupTarget = null;
17475                mBackupAppName = null;
17476            }
17477        }
17478    }
17479    // =========================================================
17480    // BROADCASTS
17481    // =========================================================
17482
17483    boolean isPendingBroadcastProcessLocked(int pid) {
17484        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17485                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17486    }
17487
17488    void skipPendingBroadcastLocked(int pid) {
17489            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17490            for (BroadcastQueue queue : mBroadcastQueues) {
17491                queue.skipPendingBroadcastLocked(pid);
17492            }
17493    }
17494
17495    // The app just attached; send any pending broadcasts that it should receive
17496    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17497        boolean didSomething = false;
17498        for (BroadcastQueue queue : mBroadcastQueues) {
17499            didSomething |= queue.sendPendingBroadcastsLocked(app);
17500        }
17501        return didSomething;
17502    }
17503
17504    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17505            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17506        enforceNotIsolatedCaller("registerReceiver");
17507        ArrayList<Intent> stickyIntents = null;
17508        ProcessRecord callerApp = null;
17509        int callingUid;
17510        int callingPid;
17511        synchronized(this) {
17512            if (caller != null) {
17513                callerApp = getRecordForAppLocked(caller);
17514                if (callerApp == null) {
17515                    throw new SecurityException(
17516                            "Unable to find app for caller " + caller
17517                            + " (pid=" + Binder.getCallingPid()
17518                            + ") when registering receiver " + receiver);
17519                }
17520                if (callerApp.info.uid != Process.SYSTEM_UID &&
17521                        !callerApp.pkgList.containsKey(callerPackage) &&
17522                        !"android".equals(callerPackage)) {
17523                    throw new SecurityException("Given caller package " + callerPackage
17524                            + " is not running in process " + callerApp);
17525                }
17526                callingUid = callerApp.info.uid;
17527                callingPid = callerApp.pid;
17528            } else {
17529                callerPackage = null;
17530                callingUid = Binder.getCallingUid();
17531                callingPid = Binder.getCallingPid();
17532            }
17533
17534            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17535                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17536
17537            Iterator<String> actions = filter.actionsIterator();
17538            if (actions == null) {
17539                ArrayList<String> noAction = new ArrayList<String>(1);
17540                noAction.add(null);
17541                actions = noAction.iterator();
17542            }
17543
17544            // Collect stickies of users
17545            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17546            while (actions.hasNext()) {
17547                String action = actions.next();
17548                for (int id : userIds) {
17549                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17550                    if (stickies != null) {
17551                        ArrayList<Intent> intents = stickies.get(action);
17552                        if (intents != null) {
17553                            if (stickyIntents == null) {
17554                                stickyIntents = new ArrayList<Intent>();
17555                            }
17556                            stickyIntents.addAll(intents);
17557                        }
17558                    }
17559                }
17560            }
17561        }
17562
17563        ArrayList<Intent> allSticky = null;
17564        if (stickyIntents != null) {
17565            final ContentResolver resolver = mContext.getContentResolver();
17566            // Look for any matching sticky broadcasts...
17567            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17568                Intent intent = stickyIntents.get(i);
17569                // If intent has scheme "content", it will need to acccess
17570                // provider that needs to lock mProviderMap in ActivityThread
17571                // and also it may need to wait application response, so we
17572                // cannot lock ActivityManagerService here.
17573                if (filter.match(resolver, intent, true, TAG) >= 0) {
17574                    if (allSticky == null) {
17575                        allSticky = new ArrayList<Intent>();
17576                    }
17577                    allSticky.add(intent);
17578                }
17579            }
17580        }
17581
17582        // The first sticky in the list is returned directly back to the client.
17583        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17584        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17585        if (receiver == null) {
17586            return sticky;
17587        }
17588
17589        synchronized (this) {
17590            if (callerApp != null && (callerApp.thread == null
17591                    || callerApp.thread.asBinder() != caller.asBinder())) {
17592                // Original caller already died
17593                return null;
17594            }
17595            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17596            if (rl == null) {
17597                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17598                        userId, receiver);
17599                if (rl.app != null) {
17600                    rl.app.receivers.add(rl);
17601                } else {
17602                    try {
17603                        receiver.asBinder().linkToDeath(rl, 0);
17604                    } catch (RemoteException e) {
17605                        return sticky;
17606                    }
17607                    rl.linkedToDeath = true;
17608                }
17609                mRegisteredReceivers.put(receiver.asBinder(), rl);
17610            } else if (rl.uid != callingUid) {
17611                throw new IllegalArgumentException(
17612                        "Receiver requested to register for uid " + callingUid
17613                        + " was previously registered for uid " + rl.uid);
17614            } else if (rl.pid != callingPid) {
17615                throw new IllegalArgumentException(
17616                        "Receiver requested to register for pid " + callingPid
17617                        + " was previously registered for pid " + rl.pid);
17618            } else if (rl.userId != userId) {
17619                throw new IllegalArgumentException(
17620                        "Receiver requested to register for user " + userId
17621                        + " was previously registered for user " + rl.userId);
17622            }
17623            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17624                    permission, callingUid, userId);
17625            rl.add(bf);
17626            if (!bf.debugCheck()) {
17627                Slog.w(TAG, "==> For Dynamic broadcast");
17628            }
17629            mReceiverResolver.addFilter(bf);
17630
17631            // Enqueue broadcasts for all existing stickies that match
17632            // this filter.
17633            if (allSticky != null) {
17634                ArrayList receivers = new ArrayList();
17635                receivers.add(bf);
17636
17637                final int stickyCount = allSticky.size();
17638                for (int i = 0; i < stickyCount; i++) {
17639                    Intent intent = allSticky.get(i);
17640                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17641                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17642                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17643                            null, 0, null, null, false, true, true, -1);
17644                    queue.enqueueParallelBroadcastLocked(r);
17645                    queue.scheduleBroadcastsLocked();
17646                }
17647            }
17648
17649            return sticky;
17650        }
17651    }
17652
17653    public void unregisterReceiver(IIntentReceiver receiver) {
17654        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17655
17656        final long origId = Binder.clearCallingIdentity();
17657        try {
17658            boolean doTrim = false;
17659
17660            synchronized(this) {
17661                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17662                if (rl != null) {
17663                    final BroadcastRecord r = rl.curBroadcast;
17664                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17665                        final boolean doNext = r.queue.finishReceiverLocked(
17666                                r, r.resultCode, r.resultData, r.resultExtras,
17667                                r.resultAbort, false);
17668                        if (doNext) {
17669                            doTrim = true;
17670                            r.queue.processNextBroadcast(false);
17671                        }
17672                    }
17673
17674                    if (rl.app != null) {
17675                        rl.app.receivers.remove(rl);
17676                    }
17677                    removeReceiverLocked(rl);
17678                    if (rl.linkedToDeath) {
17679                        rl.linkedToDeath = false;
17680                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17681                    }
17682                }
17683            }
17684
17685            // If we actually concluded any broadcasts, we might now be able
17686            // to trim the recipients' apps from our working set
17687            if (doTrim) {
17688                trimApplications();
17689                return;
17690            }
17691
17692        } finally {
17693            Binder.restoreCallingIdentity(origId);
17694        }
17695    }
17696
17697    void removeReceiverLocked(ReceiverList rl) {
17698        mRegisteredReceivers.remove(rl.receiver.asBinder());
17699        for (int i = rl.size() - 1; i >= 0; i--) {
17700            mReceiverResolver.removeFilter(rl.get(i));
17701        }
17702    }
17703
17704    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17705        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17706            ProcessRecord r = mLruProcesses.get(i);
17707            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17708                try {
17709                    r.thread.dispatchPackageBroadcast(cmd, packages);
17710                } catch (RemoteException ex) {
17711                }
17712            }
17713        }
17714    }
17715
17716    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17717            int callingUid, int[] users) {
17718        // TODO: come back and remove this assumption to triage all broadcasts
17719        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17720
17721        List<ResolveInfo> receivers = null;
17722        try {
17723            HashSet<ComponentName> singleUserReceivers = null;
17724            boolean scannedFirstReceivers = false;
17725            for (int user : users) {
17726                // Skip users that have Shell restrictions, with exception of always permitted
17727                // Shell broadcasts
17728                if (callingUid == Process.SHELL_UID
17729                        && mUserController.hasUserRestriction(
17730                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17731                        && !isPermittedShellBroadcast(intent)) {
17732                    continue;
17733                }
17734                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17735                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17736                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17737                    // If this is not the system user, we need to check for
17738                    // any receivers that should be filtered out.
17739                    for (int i=0; i<newReceivers.size(); i++) {
17740                        ResolveInfo ri = newReceivers.get(i);
17741                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17742                            newReceivers.remove(i);
17743                            i--;
17744                        }
17745                    }
17746                }
17747                if (newReceivers != null && newReceivers.size() == 0) {
17748                    newReceivers = null;
17749                }
17750                if (receivers == null) {
17751                    receivers = newReceivers;
17752                } else if (newReceivers != null) {
17753                    // We need to concatenate the additional receivers
17754                    // found with what we have do far.  This would be easy,
17755                    // but we also need to de-dup any receivers that are
17756                    // singleUser.
17757                    if (!scannedFirstReceivers) {
17758                        // Collect any single user receivers we had already retrieved.
17759                        scannedFirstReceivers = true;
17760                        for (int i=0; i<receivers.size(); i++) {
17761                            ResolveInfo ri = receivers.get(i);
17762                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17763                                ComponentName cn = new ComponentName(
17764                                        ri.activityInfo.packageName, ri.activityInfo.name);
17765                                if (singleUserReceivers == null) {
17766                                    singleUserReceivers = new HashSet<ComponentName>();
17767                                }
17768                                singleUserReceivers.add(cn);
17769                            }
17770                        }
17771                    }
17772                    // Add the new results to the existing results, tracking
17773                    // and de-dupping single user receivers.
17774                    for (int i=0; i<newReceivers.size(); i++) {
17775                        ResolveInfo ri = newReceivers.get(i);
17776                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17777                            ComponentName cn = new ComponentName(
17778                                    ri.activityInfo.packageName, ri.activityInfo.name);
17779                            if (singleUserReceivers == null) {
17780                                singleUserReceivers = new HashSet<ComponentName>();
17781                            }
17782                            if (!singleUserReceivers.contains(cn)) {
17783                                singleUserReceivers.add(cn);
17784                                receivers.add(ri);
17785                            }
17786                        } else {
17787                            receivers.add(ri);
17788                        }
17789                    }
17790                }
17791            }
17792        } catch (RemoteException ex) {
17793            // pm is in same process, this will never happen.
17794        }
17795        return receivers;
17796    }
17797
17798    private boolean isPermittedShellBroadcast(Intent intent) {
17799        // remote bugreport should always be allowed to be taken
17800        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17801    }
17802
17803    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17804            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17805        final String action = intent.getAction();
17806        if (isProtectedBroadcast
17807                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17808                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17809                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17810                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17811                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17812                || Intent.ACTION_MASTER_CLEAR.equals(action)
17813                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17814                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17815                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17816                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17817                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17818            // Broadcast is either protected, or it's a public action that
17819            // we've relaxed, so it's fine for system internals to send.
17820            return;
17821        }
17822
17823        // This broadcast may be a problem...  but there are often system components that
17824        // want to send an internal broadcast to themselves, which is annoying to have to
17825        // explicitly list each action as a protected broadcast, so we will check for that
17826        // one safe case and allow it: an explicit broadcast, only being received by something
17827        // that has protected itself.
17828        if (receivers != null && receivers.size() > 0
17829                && (intent.getPackage() != null || intent.getComponent() != null)) {
17830            boolean allProtected = true;
17831            for (int i = receivers.size()-1; i >= 0; i--) {
17832                Object target = receivers.get(i);
17833                if (target instanceof ResolveInfo) {
17834                    ResolveInfo ri = (ResolveInfo)target;
17835                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17836                        allProtected = false;
17837                        break;
17838                    }
17839                } else {
17840                    BroadcastFilter bf = (BroadcastFilter)target;
17841                    if (bf.requiredPermission == null) {
17842                        allProtected = false;
17843                        break;
17844                    }
17845                }
17846            }
17847            if (allProtected) {
17848                // All safe!
17849                return;
17850            }
17851        }
17852
17853        // The vast majority of broadcasts sent from system internals
17854        // should be protected to avoid security holes, so yell loudly
17855        // to ensure we examine these cases.
17856        if (callerApp != null) {
17857            Log.wtf(TAG, "Sending non-protected broadcast " + action
17858                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17859                    new Throwable());
17860        } else {
17861            Log.wtf(TAG, "Sending non-protected broadcast " + action
17862                            + " from system uid " + UserHandle.formatUid(callingUid)
17863                            + " pkg " + callerPackage,
17864                    new Throwable());
17865        }
17866    }
17867
17868    final int broadcastIntentLocked(ProcessRecord callerApp,
17869            String callerPackage, Intent intent, String resolvedType,
17870            IIntentReceiver resultTo, int resultCode, String resultData,
17871            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17872            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17873        intent = new Intent(intent);
17874
17875        // By default broadcasts do not go to stopped apps.
17876        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17877
17878        // If we have not finished booting, don't allow this to launch new processes.
17879        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17880            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17881        }
17882
17883        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17884                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17885                + " ordered=" + ordered + " userid=" + userId);
17886        if ((resultTo != null) && !ordered) {
17887            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17888        }
17889
17890        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17891                ALLOW_NON_FULL, "broadcast", callerPackage);
17892
17893        // Make sure that the user who is receiving this broadcast is running.
17894        // If not, we will just skip it. Make an exception for shutdown broadcasts
17895        // and upgrade steps.
17896
17897        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17898            if ((callingUid != Process.SYSTEM_UID
17899                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17900                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17901                Slog.w(TAG, "Skipping broadcast of " + intent
17902                        + ": user " + userId + " is stopped");
17903                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17904            }
17905        }
17906
17907        BroadcastOptions brOptions = null;
17908        if (bOptions != null) {
17909            brOptions = new BroadcastOptions(bOptions);
17910            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17911                // See if the caller is allowed to do this.  Note we are checking against
17912                // the actual real caller (not whoever provided the operation as say a
17913                // PendingIntent), because that who is actually supplied the arguments.
17914                if (checkComponentPermission(
17915                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17916                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17917                        != PackageManager.PERMISSION_GRANTED) {
17918                    String msg = "Permission Denial: " + intent.getAction()
17919                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17920                            + ", uid=" + callingUid + ")"
17921                            + " requires "
17922                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17923                    Slog.w(TAG, msg);
17924                    throw new SecurityException(msg);
17925                }
17926            }
17927        }
17928
17929        // Verify that protected broadcasts are only being sent by system code,
17930        // and that system code is only sending protected broadcasts.
17931        final String action = intent.getAction();
17932        final boolean isProtectedBroadcast;
17933        try {
17934            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17935        } catch (RemoteException e) {
17936            Slog.w(TAG, "Remote exception", e);
17937            return ActivityManager.BROADCAST_SUCCESS;
17938        }
17939
17940        final boolean isCallerSystem;
17941        switch (UserHandle.getAppId(callingUid)) {
17942            case Process.ROOT_UID:
17943            case Process.SYSTEM_UID:
17944            case Process.PHONE_UID:
17945            case Process.BLUETOOTH_UID:
17946            case Process.NFC_UID:
17947                isCallerSystem = true;
17948                break;
17949            default:
17950                isCallerSystem = (callerApp != null) && callerApp.persistent;
17951                break;
17952        }
17953
17954        // First line security check before anything else: stop non-system apps from
17955        // sending protected broadcasts.
17956        if (!isCallerSystem) {
17957            if (isProtectedBroadcast) {
17958                String msg = "Permission Denial: not allowed to send broadcast "
17959                        + action + " from pid="
17960                        + callingPid + ", uid=" + callingUid;
17961                Slog.w(TAG, msg);
17962                throw new SecurityException(msg);
17963
17964            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17965                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17966                // Special case for compatibility: we don't want apps to send this,
17967                // but historically it has not been protected and apps may be using it
17968                // to poke their own app widget.  So, instead of making it protected,
17969                // just limit it to the caller.
17970                if (callerPackage == null) {
17971                    String msg = "Permission Denial: not allowed to send broadcast "
17972                            + action + " from unknown caller.";
17973                    Slog.w(TAG, msg);
17974                    throw new SecurityException(msg);
17975                } else if (intent.getComponent() != null) {
17976                    // They are good enough to send to an explicit component...  verify
17977                    // it is being sent to the calling app.
17978                    if (!intent.getComponent().getPackageName().equals(
17979                            callerPackage)) {
17980                        String msg = "Permission Denial: not allowed to send broadcast "
17981                                + action + " to "
17982                                + intent.getComponent().getPackageName() + " from "
17983                                + callerPackage;
17984                        Slog.w(TAG, msg);
17985                        throw new SecurityException(msg);
17986                    }
17987                } else {
17988                    // Limit broadcast to their own package.
17989                    intent.setPackage(callerPackage);
17990                }
17991            }
17992        }
17993
17994        if (action != null) {
17995            switch (action) {
17996                case Intent.ACTION_UID_REMOVED:
17997                case Intent.ACTION_PACKAGE_REMOVED:
17998                case Intent.ACTION_PACKAGE_CHANGED:
17999                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18000                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18001                case Intent.ACTION_PACKAGES_SUSPENDED:
18002                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18003                    // Handle special intents: if this broadcast is from the package
18004                    // manager about a package being removed, we need to remove all of
18005                    // its activities from the history stack.
18006                    if (checkComponentPermission(
18007                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18008                            callingPid, callingUid, -1, true)
18009                            != PackageManager.PERMISSION_GRANTED) {
18010                        String msg = "Permission Denial: " + intent.getAction()
18011                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18012                                + ", uid=" + callingUid + ")"
18013                                + " requires "
18014                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18015                        Slog.w(TAG, msg);
18016                        throw new SecurityException(msg);
18017                    }
18018                    switch (action) {
18019                        case Intent.ACTION_UID_REMOVED:
18020                            final Bundle intentExtras = intent.getExtras();
18021                            final int uid = intentExtras != null
18022                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18023                            if (uid >= 0) {
18024                                mBatteryStatsService.removeUid(uid);
18025                                mAppOpsService.uidRemoved(uid);
18026                            }
18027                            break;
18028                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18029                            // If resources are unavailable just force stop all those packages
18030                            // and flush the attribute cache as well.
18031                            String list[] =
18032                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18033                            if (list != null && list.length > 0) {
18034                                for (int i = 0; i < list.length; i++) {
18035                                    forceStopPackageLocked(list[i], -1, false, true, true,
18036                                            false, false, userId, "storage unmount");
18037                                }
18038                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18039                                sendPackageBroadcastLocked(
18040                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
18041                                        list, userId);
18042                            }
18043                            break;
18044                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18045                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18046                            break;
18047                        case Intent.ACTION_PACKAGE_REMOVED:
18048                        case Intent.ACTION_PACKAGE_CHANGED:
18049                            Uri data = intent.getData();
18050                            String ssp;
18051                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18052                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18053                                final boolean replacing =
18054                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18055                                final boolean killProcess =
18056                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18057                                final boolean fullUninstall = removed && !replacing;
18058                                if (removed) {
18059                                    if (killProcess) {
18060                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18061                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18062                                                false, true, true, false, fullUninstall, userId,
18063                                                removed ? "pkg removed" : "pkg changed");
18064                                    }
18065                                    final int cmd = killProcess
18066                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
18067                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
18068                                    sendPackageBroadcastLocked(cmd,
18069                                            new String[] {ssp}, userId);
18070                                    if (fullUninstall) {
18071                                        mAppOpsService.packageRemoved(
18072                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18073
18074                                        // Remove all permissions granted from/to this package
18075                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18076
18077                                        removeTasksByPackageNameLocked(ssp, userId);
18078
18079                                        // Hide the "unsupported display" dialog if necessary.
18080                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18081                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18082                                            mUnsupportedDisplaySizeDialog.dismiss();
18083                                            mUnsupportedDisplaySizeDialog = null;
18084                                        }
18085                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18086                                        mBatteryStatsService.notePackageUninstalled(ssp);
18087                                    }
18088                                } else {
18089                                    if (killProcess) {
18090                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18091                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18092                                                userId, ProcessList.INVALID_ADJ,
18093                                                false, true, true, false, "change " + ssp);
18094                                    }
18095                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18096                                            intent.getStringArrayExtra(
18097                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18098                                }
18099                            }
18100                            break;
18101                        case Intent.ACTION_PACKAGES_SUSPENDED:
18102                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18103                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18104                                    intent.getAction());
18105                            final String[] packageNames = intent.getStringArrayExtra(
18106                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18107                            final int userHandle = intent.getIntExtra(
18108                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18109
18110                            synchronized(ActivityManagerService.this) {
18111                                mRecentTasks.onPackagesSuspendedChanged(
18112                                        packageNames, suspended, userHandle);
18113                            }
18114                            break;
18115                    }
18116                    break;
18117                case Intent.ACTION_PACKAGE_REPLACED:
18118                {
18119                    final Uri data = intent.getData();
18120                    final String ssp;
18121                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18122                        final ApplicationInfo aInfo =
18123                                getPackageManagerInternalLocked().getApplicationInfo(
18124                                        ssp,
18125                                        userId);
18126                        if (aInfo == null) {
18127                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18128                                    + " ssp=" + ssp + " data=" + data);
18129                            return ActivityManager.BROADCAST_SUCCESS;
18130                        }
18131                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18132                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
18133                                new String[] {ssp}, userId);
18134                    }
18135                    break;
18136                }
18137                case Intent.ACTION_PACKAGE_ADDED:
18138                {
18139                    // Special case for adding a package: by default turn on compatibility mode.
18140                    Uri data = intent.getData();
18141                    String ssp;
18142                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18143                        final boolean replacing =
18144                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18145                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18146
18147                        try {
18148                            ApplicationInfo ai = AppGlobals.getPackageManager().
18149                                    getApplicationInfo(ssp, 0, 0);
18150                            mBatteryStatsService.notePackageInstalled(ssp,
18151                                    ai != null ? ai.versionCode : 0);
18152                        } catch (RemoteException e) {
18153                        }
18154                    }
18155                    break;
18156                }
18157                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18158                {
18159                    Uri data = intent.getData();
18160                    String ssp;
18161                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18162                        // Hide the "unsupported display" dialog if necessary.
18163                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18164                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18165                            mUnsupportedDisplaySizeDialog.dismiss();
18166                            mUnsupportedDisplaySizeDialog = null;
18167                        }
18168                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18169                    }
18170                    break;
18171                }
18172                case Intent.ACTION_TIMEZONE_CHANGED:
18173                    // If this is the time zone changed action, queue up a message that will reset
18174                    // the timezone of all currently running processes. This message will get
18175                    // queued up before the broadcast happens.
18176                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18177                    break;
18178                case Intent.ACTION_TIME_CHANGED:
18179                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
18180                    // the tri-state value it may contain and "unknown".
18181                    // For convenience we re-use the Intent extra values.
18182                    final int NO_EXTRA_VALUE_FOUND = -1;
18183                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
18184                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
18185                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
18186                    // Only send a message if the time preference is available.
18187                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
18188                        Message updateTimePreferenceMsg =
18189                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
18190                                        timeFormatPreferenceMsgValue, 0);
18191                        mHandler.sendMessage(updateTimePreferenceMsg);
18192                    }
18193                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18194                    synchronized (stats) {
18195                        stats.noteCurrentTimeChangedLocked();
18196                    }
18197                    break;
18198                case Intent.ACTION_CLEAR_DNS_CACHE:
18199                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18200                    break;
18201                case Proxy.PROXY_CHANGE_ACTION:
18202                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18203                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18204                    break;
18205                case android.hardware.Camera.ACTION_NEW_PICTURE:
18206                case android.hardware.Camera.ACTION_NEW_VIDEO:
18207                    // These broadcasts are no longer allowed by the system, since they can
18208                    // cause significant thrashing at a crictical point (using the camera).
18209                    // Apps should use JobScehduler to monitor for media provider changes.
18210                    Slog.w(TAG, action + " no longer allowed; dropping from "
18211                            + UserHandle.formatUid(callingUid));
18212                    if (resultTo != null) {
18213                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18214                        try {
18215                            queue.performReceiveLocked(callerApp, resultTo, intent,
18216                                    Activity.RESULT_CANCELED, null, null,
18217                                    false, false, userId);
18218                        } catch (RemoteException e) {
18219                            Slog.w(TAG, "Failure ["
18220                                    + queue.mQueueName + "] sending broadcast result of "
18221                                    + intent, e);
18222
18223                        }
18224                    }
18225                    // Lie; we don't want to crash the app.
18226                    return ActivityManager.BROADCAST_SUCCESS;
18227                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
18228                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
18229                    break;
18230            }
18231        }
18232
18233        // Add to the sticky list if requested.
18234        if (sticky) {
18235            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18236                    callingPid, callingUid)
18237                    != PackageManager.PERMISSION_GRANTED) {
18238                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18239                        + callingPid + ", uid=" + callingUid
18240                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18241                Slog.w(TAG, msg);
18242                throw new SecurityException(msg);
18243            }
18244            if (requiredPermissions != null && requiredPermissions.length > 0) {
18245                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18246                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18247                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18248            }
18249            if (intent.getComponent() != null) {
18250                throw new SecurityException(
18251                        "Sticky broadcasts can't target a specific component");
18252            }
18253            // We use userId directly here, since the "all" target is maintained
18254            // as a separate set of sticky broadcasts.
18255            if (userId != UserHandle.USER_ALL) {
18256                // But first, if this is not a broadcast to all users, then
18257                // make sure it doesn't conflict with an existing broadcast to
18258                // all users.
18259                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18260                        UserHandle.USER_ALL);
18261                if (stickies != null) {
18262                    ArrayList<Intent> list = stickies.get(intent.getAction());
18263                    if (list != null) {
18264                        int N = list.size();
18265                        int i;
18266                        for (i=0; i<N; i++) {
18267                            if (intent.filterEquals(list.get(i))) {
18268                                throw new IllegalArgumentException(
18269                                        "Sticky broadcast " + intent + " for user "
18270                                        + userId + " conflicts with existing global broadcast");
18271                            }
18272                        }
18273                    }
18274                }
18275            }
18276            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18277            if (stickies == null) {
18278                stickies = new ArrayMap<>();
18279                mStickyBroadcasts.put(userId, stickies);
18280            }
18281            ArrayList<Intent> list = stickies.get(intent.getAction());
18282            if (list == null) {
18283                list = new ArrayList<>();
18284                stickies.put(intent.getAction(), list);
18285            }
18286            final int stickiesCount = list.size();
18287            int i;
18288            for (i = 0; i < stickiesCount; i++) {
18289                if (intent.filterEquals(list.get(i))) {
18290                    // This sticky already exists, replace it.
18291                    list.set(i, new Intent(intent));
18292                    break;
18293                }
18294            }
18295            if (i >= stickiesCount) {
18296                list.add(new Intent(intent));
18297            }
18298        }
18299
18300        int[] users;
18301        if (userId == UserHandle.USER_ALL) {
18302            // Caller wants broadcast to go to all started users.
18303            users = mUserController.getStartedUserArrayLocked();
18304        } else {
18305            // Caller wants broadcast to go to one specific user.
18306            users = new int[] {userId};
18307        }
18308
18309        // Figure out who all will receive this broadcast.
18310        List receivers = null;
18311        List<BroadcastFilter> registeredReceivers = null;
18312        // Need to resolve the intent to interested receivers...
18313        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18314                 == 0) {
18315            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18316        }
18317        if (intent.getComponent() == null) {
18318            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18319                // Query one target user at a time, excluding shell-restricted users
18320                for (int i = 0; i < users.length; i++) {
18321                    if (mUserController.hasUserRestriction(
18322                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18323                        continue;
18324                    }
18325                    List<BroadcastFilter> registeredReceiversForUser =
18326                            mReceiverResolver.queryIntent(intent,
18327                                    resolvedType, false, users[i]);
18328                    if (registeredReceivers == null) {
18329                        registeredReceivers = registeredReceiversForUser;
18330                    } else if (registeredReceiversForUser != null) {
18331                        registeredReceivers.addAll(registeredReceiversForUser);
18332                    }
18333                }
18334            } else {
18335                registeredReceivers = mReceiverResolver.queryIntent(intent,
18336                        resolvedType, false, userId);
18337            }
18338        }
18339
18340        final boolean replacePending =
18341                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18342
18343        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18344                + " replacePending=" + replacePending);
18345
18346        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18347        if (!ordered && NR > 0) {
18348            // If we are not serializing this broadcast, then send the
18349            // registered receivers separately so they don't wait for the
18350            // components to be launched.
18351            if (isCallerSystem) {
18352                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18353                        isProtectedBroadcast, registeredReceivers);
18354            }
18355            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18356            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18357                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18358                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18359                    resultExtras, ordered, sticky, false, userId);
18360            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18361            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18362            if (!replaced) {
18363                queue.enqueueParallelBroadcastLocked(r);
18364                queue.scheduleBroadcastsLocked();
18365            }
18366            registeredReceivers = null;
18367            NR = 0;
18368        }
18369
18370        // Merge into one list.
18371        int ir = 0;
18372        if (receivers != null) {
18373            // A special case for PACKAGE_ADDED: do not allow the package
18374            // being added to see this broadcast.  This prevents them from
18375            // using this as a back door to get run as soon as they are
18376            // installed.  Maybe in the future we want to have a special install
18377            // broadcast or such for apps, but we'd like to deliberately make
18378            // this decision.
18379            String skipPackages[] = null;
18380            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18381                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18382                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18383                Uri data = intent.getData();
18384                if (data != null) {
18385                    String pkgName = data.getSchemeSpecificPart();
18386                    if (pkgName != null) {
18387                        skipPackages = new String[] { pkgName };
18388                    }
18389                }
18390            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18391                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18392            }
18393            if (skipPackages != null && (skipPackages.length > 0)) {
18394                for (String skipPackage : skipPackages) {
18395                    if (skipPackage != null) {
18396                        int NT = receivers.size();
18397                        for (int it=0; it<NT; it++) {
18398                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18399                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18400                                receivers.remove(it);
18401                                it--;
18402                                NT--;
18403                            }
18404                        }
18405                    }
18406                }
18407            }
18408
18409            int NT = receivers != null ? receivers.size() : 0;
18410            int it = 0;
18411            ResolveInfo curt = null;
18412            BroadcastFilter curr = null;
18413            while (it < NT && ir < NR) {
18414                if (curt == null) {
18415                    curt = (ResolveInfo)receivers.get(it);
18416                }
18417                if (curr == null) {
18418                    curr = registeredReceivers.get(ir);
18419                }
18420                if (curr.getPriority() >= curt.priority) {
18421                    // Insert this broadcast record into the final list.
18422                    receivers.add(it, curr);
18423                    ir++;
18424                    curr = null;
18425                    it++;
18426                    NT++;
18427                } else {
18428                    // Skip to the next ResolveInfo in the final list.
18429                    it++;
18430                    curt = null;
18431                }
18432            }
18433        }
18434        while (ir < NR) {
18435            if (receivers == null) {
18436                receivers = new ArrayList();
18437            }
18438            receivers.add(registeredReceivers.get(ir));
18439            ir++;
18440        }
18441
18442        if (isCallerSystem) {
18443            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18444                    isProtectedBroadcast, receivers);
18445        }
18446
18447        if ((receivers != null && receivers.size() > 0)
18448                || resultTo != null) {
18449            BroadcastQueue queue = broadcastQueueForIntent(intent);
18450            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18451                    callerPackage, callingPid, callingUid, resolvedType,
18452                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18453                    resultData, resultExtras, ordered, sticky, false, userId);
18454
18455            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18456                    + ": prev had " + queue.mOrderedBroadcasts.size());
18457            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18458                    "Enqueueing broadcast " + r.intent.getAction());
18459
18460            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18461            if (!replaced) {
18462                queue.enqueueOrderedBroadcastLocked(r);
18463                queue.scheduleBroadcastsLocked();
18464            }
18465        } else {
18466            // There was nobody interested in the broadcast, but we still want to record
18467            // that it happened.
18468            if (intent.getComponent() == null && intent.getPackage() == null
18469                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18470                // This was an implicit broadcast... let's record it for posterity.
18471                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18472            }
18473        }
18474
18475        return ActivityManager.BROADCAST_SUCCESS;
18476    }
18477
18478    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18479            int skipCount, long dispatchTime) {
18480        final long now = SystemClock.elapsedRealtime();
18481        if (mCurBroadcastStats == null ||
18482                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18483            mLastBroadcastStats = mCurBroadcastStats;
18484            if (mLastBroadcastStats != null) {
18485                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18486                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18487            }
18488            mCurBroadcastStats = new BroadcastStats();
18489        }
18490        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18491    }
18492
18493    final Intent verifyBroadcastLocked(Intent intent) {
18494        // Refuse possible leaked file descriptors
18495        if (intent != null && intent.hasFileDescriptors() == true) {
18496            throw new IllegalArgumentException("File descriptors passed in Intent");
18497        }
18498
18499        int flags = intent.getFlags();
18500
18501        if (!mProcessesReady) {
18502            // if the caller really truly claims to know what they're doing, go
18503            // ahead and allow the broadcast without launching any receivers
18504            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18505                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18506            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18507                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18508                        + " before boot completion");
18509                throw new IllegalStateException("Cannot broadcast before boot completed");
18510            }
18511        }
18512
18513        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18514            throw new IllegalArgumentException(
18515                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18516        }
18517
18518        return intent;
18519    }
18520
18521    public final int broadcastIntent(IApplicationThread caller,
18522            Intent intent, String resolvedType, IIntentReceiver resultTo,
18523            int resultCode, String resultData, Bundle resultExtras,
18524            String[] requiredPermissions, int appOp, Bundle bOptions,
18525            boolean serialized, boolean sticky, int userId) {
18526        enforceNotIsolatedCaller("broadcastIntent");
18527        synchronized(this) {
18528            intent = verifyBroadcastLocked(intent);
18529
18530            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18531            final int callingPid = Binder.getCallingPid();
18532            final int callingUid = Binder.getCallingUid();
18533            final long origId = Binder.clearCallingIdentity();
18534            int res = broadcastIntentLocked(callerApp,
18535                    callerApp != null ? callerApp.info.packageName : null,
18536                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18537                    requiredPermissions, appOp, bOptions, serialized, sticky,
18538                    callingPid, callingUid, userId);
18539            Binder.restoreCallingIdentity(origId);
18540            return res;
18541        }
18542    }
18543
18544
18545    int broadcastIntentInPackage(String packageName, int uid,
18546            Intent intent, String resolvedType, IIntentReceiver resultTo,
18547            int resultCode, String resultData, Bundle resultExtras,
18548            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18549            int userId) {
18550        synchronized(this) {
18551            intent = verifyBroadcastLocked(intent);
18552
18553            final long origId = Binder.clearCallingIdentity();
18554            String[] requiredPermissions = requiredPermission == null ? null
18555                    : new String[] {requiredPermission};
18556            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18557                    resultTo, resultCode, resultData, resultExtras,
18558                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18559                    sticky, -1, uid, userId);
18560            Binder.restoreCallingIdentity(origId);
18561            return res;
18562        }
18563    }
18564
18565    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18566        // Refuse possible leaked file descriptors
18567        if (intent != null && intent.hasFileDescriptors() == true) {
18568            throw new IllegalArgumentException("File descriptors passed in Intent");
18569        }
18570
18571        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18572                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18573
18574        synchronized(this) {
18575            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18576                    != PackageManager.PERMISSION_GRANTED) {
18577                String msg = "Permission Denial: unbroadcastIntent() from pid="
18578                        + Binder.getCallingPid()
18579                        + ", uid=" + Binder.getCallingUid()
18580                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18581                Slog.w(TAG, msg);
18582                throw new SecurityException(msg);
18583            }
18584            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18585            if (stickies != null) {
18586                ArrayList<Intent> list = stickies.get(intent.getAction());
18587                if (list != null) {
18588                    int N = list.size();
18589                    int i;
18590                    for (i=0; i<N; i++) {
18591                        if (intent.filterEquals(list.get(i))) {
18592                            list.remove(i);
18593                            break;
18594                        }
18595                    }
18596                    if (list.size() <= 0) {
18597                        stickies.remove(intent.getAction());
18598                    }
18599                }
18600                if (stickies.size() <= 0) {
18601                    mStickyBroadcasts.remove(userId);
18602                }
18603            }
18604        }
18605    }
18606
18607    void backgroundServicesFinishedLocked(int userId) {
18608        for (BroadcastQueue queue : mBroadcastQueues) {
18609            queue.backgroundServicesFinishedLocked(userId);
18610        }
18611    }
18612
18613    public void finishReceiver(IBinder who, int resultCode, String resultData,
18614            Bundle resultExtras, boolean resultAbort, int flags) {
18615        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18616
18617        // Refuse possible leaked file descriptors
18618        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18619            throw new IllegalArgumentException("File descriptors passed in Bundle");
18620        }
18621
18622        final long origId = Binder.clearCallingIdentity();
18623        try {
18624            boolean doNext = false;
18625            BroadcastRecord r;
18626
18627            synchronized(this) {
18628                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18629                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18630                r = queue.getMatchingOrderedReceiver(who);
18631                if (r != null) {
18632                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18633                        resultData, resultExtras, resultAbort, true);
18634                }
18635            }
18636
18637            if (doNext) {
18638                r.queue.processNextBroadcast(false);
18639            }
18640            trimApplications();
18641        } finally {
18642            Binder.restoreCallingIdentity(origId);
18643        }
18644    }
18645
18646    // =========================================================
18647    // INSTRUMENTATION
18648    // =========================================================
18649
18650    public boolean startInstrumentation(ComponentName className,
18651            String profileFile, int flags, Bundle arguments,
18652            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18653            int userId, String abiOverride) {
18654        enforceNotIsolatedCaller("startInstrumentation");
18655        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18656                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18657        // Refuse possible leaked file descriptors
18658        if (arguments != null && arguments.hasFileDescriptors()) {
18659            throw new IllegalArgumentException("File descriptors passed in Bundle");
18660        }
18661
18662        synchronized(this) {
18663            InstrumentationInfo ii = null;
18664            ApplicationInfo ai = null;
18665            try {
18666                ii = mContext.getPackageManager().getInstrumentationInfo(
18667                    className, STOCK_PM_FLAGS);
18668                ai = AppGlobals.getPackageManager().getApplicationInfo(
18669                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18670            } catch (PackageManager.NameNotFoundException e) {
18671            } catch (RemoteException e) {
18672            }
18673            if (ii == null) {
18674                reportStartInstrumentationFailureLocked(watcher, className,
18675                        "Unable to find instrumentation info for: " + className);
18676                return false;
18677            }
18678            if (ai == null) {
18679                reportStartInstrumentationFailureLocked(watcher, className,
18680                        "Unable to find instrumentation target package: " + ii.targetPackage);
18681                return false;
18682            }
18683            if (!ai.hasCode()) {
18684                reportStartInstrumentationFailureLocked(watcher, className,
18685                        "Instrumentation target has no code: " + ii.targetPackage);
18686                return false;
18687            }
18688
18689            int match = mContext.getPackageManager().checkSignatures(
18690                    ii.targetPackage, ii.packageName);
18691            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18692                String msg = "Permission Denial: starting instrumentation "
18693                        + className + " from pid="
18694                        + Binder.getCallingPid()
18695                        + ", uid=" + Binder.getCallingPid()
18696                        + " not allowed because package " + ii.packageName
18697                        + " does not have a signature matching the target "
18698                        + ii.targetPackage;
18699                reportStartInstrumentationFailureLocked(watcher, className, msg);
18700                throw new SecurityException(msg);
18701            }
18702
18703            final long origId = Binder.clearCallingIdentity();
18704            // Instrumentation can kill and relaunch even persistent processes
18705            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18706                    "start instr");
18707            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18708            app.instrumentationClass = className;
18709            app.instrumentationInfo = ai;
18710            app.instrumentationProfileFile = profileFile;
18711            app.instrumentationArguments = arguments;
18712            app.instrumentationWatcher = watcher;
18713            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18714            app.instrumentationResultClass = className;
18715            Binder.restoreCallingIdentity(origId);
18716        }
18717
18718        return true;
18719    }
18720
18721    /**
18722     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18723     * error to the logs, but if somebody is watching, send the report there too.  This enables
18724     * the "am" command to report errors with more information.
18725     *
18726     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18727     * @param cn The component name of the instrumentation.
18728     * @param report The error report.
18729     */
18730    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18731            ComponentName cn, String report) {
18732        Slog.w(TAG, report);
18733        if (watcher != null) {
18734            Bundle results = new Bundle();
18735            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18736            results.putString("Error", report);
18737            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18738        }
18739    }
18740
18741    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18742        if (app.instrumentationWatcher != null) {
18743            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18744                    app.instrumentationClass, resultCode, results);
18745        }
18746
18747        // Can't call out of the system process with a lock held, so post a message.
18748        if (app.instrumentationUiAutomationConnection != null) {
18749            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18750                    app.instrumentationUiAutomationConnection).sendToTarget();
18751        }
18752
18753        app.instrumentationWatcher = null;
18754        app.instrumentationUiAutomationConnection = null;
18755        app.instrumentationClass = null;
18756        app.instrumentationInfo = null;
18757        app.instrumentationProfileFile = null;
18758        app.instrumentationArguments = null;
18759
18760        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18761                "finished inst");
18762    }
18763
18764    public void finishInstrumentation(IApplicationThread target,
18765            int resultCode, Bundle results) {
18766        int userId = UserHandle.getCallingUserId();
18767        // Refuse possible leaked file descriptors
18768        if (results != null && results.hasFileDescriptors()) {
18769            throw new IllegalArgumentException("File descriptors passed in Intent");
18770        }
18771
18772        synchronized(this) {
18773            ProcessRecord app = getRecordForAppLocked(target);
18774            if (app == null) {
18775                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18776                return;
18777            }
18778            final long origId = Binder.clearCallingIdentity();
18779            finishInstrumentationLocked(app, resultCode, results);
18780            Binder.restoreCallingIdentity(origId);
18781        }
18782    }
18783
18784    // =========================================================
18785    // CONFIGURATION
18786    // =========================================================
18787
18788    public ConfigurationInfo getDeviceConfigurationInfo() {
18789        ConfigurationInfo config = new ConfigurationInfo();
18790        synchronized (this) {
18791            final Configuration globalConfig = getGlobalConfiguration();
18792            config.reqTouchScreen = globalConfig.touchscreen;
18793            config.reqKeyboardType = globalConfig.keyboard;
18794            config.reqNavigation = globalConfig.navigation;
18795            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
18796                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
18797                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18798            }
18799            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
18800                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
18801                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18802            }
18803            config.reqGlEsVersion = GL_ES_VERSION;
18804        }
18805        return config;
18806    }
18807
18808    ActivityStack getFocusedStack() {
18809        return mStackSupervisor.getFocusedStack();
18810    }
18811
18812    @Override
18813    public int getFocusedStackId() throws RemoteException {
18814        ActivityStack focusedStack = getFocusedStack();
18815        if (focusedStack != null) {
18816            return focusedStack.getStackId();
18817        }
18818        return -1;
18819    }
18820
18821    public Configuration getConfiguration() {
18822        Configuration ci;
18823        synchronized(this) {
18824            ci = new Configuration(getGlobalConfiguration());
18825            ci.userSetLocale = false;
18826        }
18827        return ci;
18828    }
18829
18830    @Override
18831    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18832        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18833        synchronized (this) {
18834            mSuppressResizeConfigChanges = suppress;
18835        }
18836    }
18837
18838    @Override
18839    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18840        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18841        if (fromStackId == HOME_STACK_ID) {
18842            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18843        }
18844        synchronized (this) {
18845            final long origId = Binder.clearCallingIdentity();
18846            try {
18847                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18848            } finally {
18849                Binder.restoreCallingIdentity(origId);
18850            }
18851        }
18852    }
18853
18854    @Override
18855    public void updatePersistentConfiguration(Configuration values) {
18856        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
18857        enforceWriteSettingsPermission("updatePersistentConfiguration()");
18858        if (values == null) {
18859            throw new NullPointerException("Configuration must not be null");
18860        }
18861
18862        int userId = UserHandle.getCallingUserId();
18863
18864        synchronized(this) {
18865            updatePersistentConfigurationLocked(values, userId);
18866        }
18867    }
18868
18869    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18870        final long origId = Binder.clearCallingIdentity();
18871        try {
18872            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18873        } finally {
18874            Binder.restoreCallingIdentity(origId);
18875        }
18876    }
18877
18878    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18879        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18880                FONT_SCALE, 1.0f, userId);
18881
18882        synchronized (this) {
18883            if (getGlobalConfiguration().fontScale == scaleFactor) {
18884                return;
18885            }
18886
18887            final Configuration configuration
18888                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
18889            configuration.fontScale = scaleFactor;
18890            updatePersistentConfigurationLocked(configuration, userId);
18891        }
18892    }
18893
18894    private void enforceWriteSettingsPermission(String func) {
18895        int uid = Binder.getCallingUid();
18896        if (uid == Process.ROOT_UID) {
18897            return;
18898        }
18899
18900        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18901                Settings.getPackageNameForUid(mContext, uid), false)) {
18902            return;
18903        }
18904
18905        String msg = "Permission Denial: " + func + " from pid="
18906                + Binder.getCallingPid()
18907                + ", uid=" + uid
18908                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18909        Slog.w(TAG, msg);
18910        throw new SecurityException(msg);
18911    }
18912
18913    @Override
18914    public boolean updateConfiguration(Configuration values) {
18915        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
18916
18917        synchronized(this) {
18918            if (values == null && mWindowManager != null) {
18919                // sentinel: fetch the current configuration from the window manager
18920                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
18921            }
18922
18923            if (mWindowManager != null) {
18924                // Update OOM levels based on display size.
18925                mProcessList.applyDisplaySize(mWindowManager);
18926            }
18927
18928            final long origId = Binder.clearCallingIdentity();
18929            try {
18930                if (values != null) {
18931                    Settings.System.clearConfiguration(values);
18932                }
18933                updateConfigurationLocked(values, null, false, false /* persistent */,
18934                        UserHandle.USER_NULL, false /* deferResume */,
18935                        mTmpUpdateConfigurationResult);
18936                return mTmpUpdateConfigurationResult.changes != 0;
18937            } finally {
18938                Binder.restoreCallingIdentity(origId);
18939            }
18940        }
18941    }
18942
18943    void updateUserConfigurationLocked() {
18944        final Configuration configuration = new Configuration(getGlobalConfiguration());
18945        final int currentUserId = mUserController.getCurrentUserIdLocked();
18946        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18947                currentUserId, Settings.System.canWrite(mContext));
18948        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
18949                false /* persistent */, currentUserId, false /* deferResume */);
18950    }
18951
18952    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18953            boolean initLocale) {
18954        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18955    }
18956
18957    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18958            boolean initLocale, boolean deferResume) {
18959        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18960        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18961                UserHandle.USER_NULL, deferResume);
18962    }
18963
18964    // To cache the list of supported system locales
18965    private String[] mSupportedSystemLocales = null;
18966
18967    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18968            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18969        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
18970                deferResume, null /* result */);
18971    }
18972
18973    /**
18974     * Do either or both things: (1) change the current configuration, and (2)
18975     * make sure the given activity is running with the (now) current
18976     * configuration.  Returns true if the activity has been left running, or
18977     * false if <var>starting</var> is being destroyed to match the new
18978     * configuration.
18979     *
18980     * @param userId is only used when persistent parameter is set to true to persist configuration
18981     *               for that particular user
18982     */
18983    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18984            boolean initLocale, boolean persistent, int userId, boolean deferResume,
18985            UpdateConfigurationResult result) {
18986        int changes = 0;
18987        boolean kept = true;
18988
18989        if (mWindowManager != null) {
18990            mWindowManager.deferSurfaceLayout();
18991        }
18992        try {
18993            if (values != null) {
18994                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
18995                        deferResume);
18996            }
18997
18998            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
18999        } finally {
19000            if (mWindowManager != null) {
19001                mWindowManager.continueSurfaceLayout();
19002            }
19003        }
19004
19005        if (result != null) {
19006            result.changes = changes;
19007            result.activityRelaunched = !kept;
19008        }
19009        return kept;
19010    }
19011
19012    /** Update default (global) configuration and notify listeners about changes. */
19013    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
19014            boolean persistent, int userId, boolean deferResume) {
19015        mTempConfig.setTo(getGlobalConfiguration());
19016        final int changes = mTempConfig.updateFrom(values);
19017        if (changes == 0) {
19018            return 0;
19019        }
19020
19021        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19022                "Updating global configuration to: " + values);
19023
19024        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19025
19026        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19027            final LocaleList locales = values.getLocales();
19028            int bestLocaleIndex = 0;
19029            if (locales.size() > 1) {
19030                if (mSupportedSystemLocales == null) {
19031                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
19032                }
19033                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
19034            }
19035            SystemProperties.set("persist.sys.locale",
19036                    locales.get(bestLocaleIndex).toLanguageTag());
19037            LocaleList.setDefault(locales, bestLocaleIndex);
19038            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19039                    locales.get(bestLocaleIndex)));
19040        }
19041
19042        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
19043        mTempConfig.seq = mConfigurationSeq;
19044
19045        // Update stored global config and notify everyone about the change.
19046        mStackSupervisor.onConfigurationChanged(mTempConfig);
19047
19048        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
19049        // TODO(multi-display): Update UsageEvents#Event to include displayId.
19050        mUsageStatsService.reportConfigurationChange(mTempConfig,
19051                mUserController.getCurrentUserIdLocked());
19052
19053        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
19054        mShowDialogs = shouldShowDialogs(mTempConfig, mInVrMode);
19055
19056        AttributeCache ac = AttributeCache.instance();
19057        if (ac != null) {
19058            ac.updateConfiguration(mTempConfig);
19059        }
19060
19061        // Make sure all resources in our process are updated right now, so that anyone who is going
19062        // to retrieve resource values after we return will be sure to get the new ones. This is
19063        // especially important during boot, where the first config change needs to guarantee all
19064        // resources have that config before following boot code is executed.
19065        mSystemThread.applyConfigurationToResources(mTempConfig);
19066
19067        // We need another copy of global config because we're scheduling some calls instead of
19068        // running them in place. We need to be sure that object we send will be handled unchanged.
19069        final Configuration configCopy = new Configuration(mTempConfig);
19070        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19071            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19072            msg.obj = configCopy;
19073            msg.arg1 = userId;
19074            mHandler.sendMessage(msg);
19075        }
19076
19077        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19078            ProcessRecord app = mLruProcesses.get(i);
19079            try {
19080                if (app.thread != null) {
19081                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19082                            + app.processName + " new config " + configCopy);
19083                    app.thread.scheduleConfigurationChanged(configCopy);
19084                }
19085            } catch (Exception e) {
19086            }
19087        }
19088
19089        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19090        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
19091                | Intent.FLAG_RECEIVER_FOREGROUND);
19092        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19093                AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19094                UserHandle.USER_ALL);
19095        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
19096            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19097            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19098            if (initLocale || !mProcessesReady) {
19099                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19100            }
19101            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19102                    AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19103                    UserHandle.USER_ALL);
19104        }
19105
19106        // Override configuration of the default display duplicates global config, so we need to
19107        // update it also. This will also notify WindowManager about changes.
19108        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
19109                DEFAULT_DISPLAY);
19110
19111        return changes;
19112    }
19113
19114    @Override
19115    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
19116        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
19117
19118        synchronized (this) {
19119            // Check if display is initialized in AM.
19120            if (!mStackSupervisor.isDisplayAdded(displayId)) {
19121                // Call might come when display is not yet added or has already been removed.
19122                if (DEBUG_CONFIGURATION) {
19123                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
19124                            + displayId);
19125                }
19126                return false;
19127            }
19128
19129            if (values == null && mWindowManager != null) {
19130                // sentinel: fetch the current configuration from the window manager
19131                values = mWindowManager.computeNewConfiguration(displayId);
19132            }
19133
19134            if (mWindowManager != null) {
19135                // Update OOM levels based on display size.
19136                mProcessList.applyDisplaySize(mWindowManager);
19137            }
19138
19139            final long origId = Binder.clearCallingIdentity();
19140            try {
19141                if (values != null) {
19142                    Settings.System.clearConfiguration(values);
19143                }
19144                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
19145                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
19146                return mTmpUpdateConfigurationResult.changes != 0;
19147            } finally {
19148                Binder.restoreCallingIdentity(origId);
19149            }
19150        }
19151    }
19152
19153    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
19154            boolean deferResume, int displayId) {
19155        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
19156                displayId, null /* result */);
19157    }
19158
19159    /**
19160     * Updates override configuration specific for the selected display. If no config is provided,
19161     * new one will be computed in WM based on current display info.
19162     */
19163    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
19164            ActivityRecord starting, boolean deferResume, int displayId,
19165            UpdateConfigurationResult result) {
19166        int changes = 0;
19167        boolean kept = true;
19168
19169        if (mWindowManager != null) {
19170            mWindowManager.deferSurfaceLayout();
19171        }
19172        try {
19173            if (values != null) {
19174                if (displayId == DEFAULT_DISPLAY) {
19175                    // Override configuration of the default display duplicates global config, so
19176                    // we're calling global config update instead for default display. It will also
19177                    // apply the correct override config.
19178                    changes = updateGlobalConfiguration(values, false /* initLocale */,
19179                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
19180                } else {
19181                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
19182                }
19183            }
19184
19185            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19186        } finally {
19187            if (mWindowManager != null) {
19188                mWindowManager.continueSurfaceLayout();
19189            }
19190        }
19191
19192        if (result != null) {
19193            result.changes = changes;
19194            result.activityRelaunched = !kept;
19195        }
19196        return kept;
19197    }
19198
19199    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
19200            int displayId) {
19201        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
19202        final int changes = mTempConfig.updateFrom(values);
19203        if (changes == 0) {
19204            return 0;
19205        }
19206
19207        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
19208                + " for displayId=" + displayId);
19209        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
19210
19211        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19212        if (isDensityChange) {
19213            // Reset the unsupported display size dialog.
19214            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19215
19216            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19217        }
19218
19219        // Update the configuration with WM first and check if any of the stacks need to be resized
19220        // due to the configuration change. If so, resize the stacks now and do any relaunches if
19221        // necessary. This way we don't need to relaunch again afterwards in
19222        // ensureActivityConfigurationLocked().
19223        if (mWindowManager != null) {
19224            final int[] resizedStacks =
19225                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
19226            if (resizedStacks != null) {
19227                for (int stackId : resizedStacks) {
19228                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
19229                }
19230            }
19231        }
19232
19233        return changes;
19234    }
19235
19236    /** Applies latest configuration and/or visibility updates if needed. */
19237    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
19238        boolean kept = true;
19239        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19240        // mainStack is null during startup.
19241        if (mainStack != null) {
19242            if (changes != 0 && starting == null) {
19243                // If the configuration changed, and the caller is not already
19244                // in the process of starting an activity, then find the top
19245                // activity to check if its configuration needs to change.
19246                starting = mainStack.topRunningActivityLocked();
19247            }
19248
19249            if (starting != null) {
19250                kept = starting.ensureActivityConfigurationLocked(changes,
19251                        false /* preserveWindow */);
19252                // And we need to make sure at this point that all other activities
19253                // are made visible with the correct configuration.
19254                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19255                        !PRESERVE_WINDOWS);
19256            }
19257        }
19258
19259        return kept;
19260    }
19261
19262    /** Helper method that requests bounds from WM and applies them to stack. */
19263    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
19264        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19265        mStackSupervisor.resizeStackLocked(
19266                stackId, newBounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
19267                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
19268    }
19269
19270    /**
19271     * Decide based on the configuration whether we should show the ANR,
19272     * crash, etc dialogs.  The idea is that if there is no affordance to
19273     * press the on-screen buttons, or the user experience would be more
19274     * greatly impacted than the crash itself, we shouldn't show the dialog.
19275     *
19276     * A thought: SystemUI might also want to get told about this, the Power
19277     * dialog / global actions also might want different behaviors.
19278     */
19279    private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19280        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19281                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19282                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19283        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19284        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19285                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19286        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19287    }
19288
19289    @Override
19290    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19291        synchronized (this) {
19292            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19293            if (srec != null) {
19294                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
19295            }
19296        }
19297        return false;
19298    }
19299
19300    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19301            Intent resultData) {
19302
19303        synchronized (this) {
19304            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19305            if (r != null) {
19306                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
19307            }
19308            return false;
19309        }
19310    }
19311
19312    public int getLaunchedFromUid(IBinder activityToken) {
19313        ActivityRecord srec;
19314        synchronized (this) {
19315            srec = ActivityRecord.forTokenLocked(activityToken);
19316        }
19317        if (srec == null) {
19318            return -1;
19319        }
19320        return srec.launchedFromUid;
19321    }
19322
19323    public String getLaunchedFromPackage(IBinder activityToken) {
19324        ActivityRecord srec;
19325        synchronized (this) {
19326            srec = ActivityRecord.forTokenLocked(activityToken);
19327        }
19328        if (srec == null) {
19329            return null;
19330        }
19331        return srec.launchedFromPackage;
19332    }
19333
19334    // =========================================================
19335    // LIFETIME MANAGEMENT
19336    // =========================================================
19337
19338    // Returns whether the app is receiving broadcast.
19339    // If receiving, fetch all broadcast queues which the app is
19340    // the current [or imminent] receiver on.
19341    private boolean isReceivingBroadcastLocked(ProcessRecord app,
19342            ArraySet<BroadcastQueue> receivingQueues) {
19343        if (!app.curReceivers.isEmpty()) {
19344            for (BroadcastRecord r : app.curReceivers) {
19345                receivingQueues.add(r.queue);
19346            }
19347            return true;
19348        }
19349
19350        // It's not the current receiver, but it might be starting up to become one
19351        for (BroadcastQueue queue : mBroadcastQueues) {
19352            final BroadcastRecord r = queue.mPendingBroadcast;
19353            if (r != null && r.curApp == app) {
19354                // found it; report which queue it's in
19355                receivingQueues.add(queue);
19356            }
19357        }
19358
19359        return !receivingQueues.isEmpty();
19360    }
19361
19362    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19363            int targetUid, ComponentName targetComponent, String targetProcess) {
19364        if (!mTrackingAssociations) {
19365            return null;
19366        }
19367        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19368                = mAssociations.get(targetUid);
19369        if (components == null) {
19370            components = new ArrayMap<>();
19371            mAssociations.put(targetUid, components);
19372        }
19373        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19374        if (sourceUids == null) {
19375            sourceUids = new SparseArray<>();
19376            components.put(targetComponent, sourceUids);
19377        }
19378        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19379        if (sourceProcesses == null) {
19380            sourceProcesses = new ArrayMap<>();
19381            sourceUids.put(sourceUid, sourceProcesses);
19382        }
19383        Association ass = sourceProcesses.get(sourceProcess);
19384        if (ass == null) {
19385            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19386                    targetProcess);
19387            sourceProcesses.put(sourceProcess, ass);
19388        }
19389        ass.mCount++;
19390        ass.mNesting++;
19391        if (ass.mNesting == 1) {
19392            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19393            ass.mLastState = sourceState;
19394        }
19395        return ass;
19396    }
19397
19398    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19399            ComponentName targetComponent) {
19400        if (!mTrackingAssociations) {
19401            return;
19402        }
19403        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19404                = mAssociations.get(targetUid);
19405        if (components == null) {
19406            return;
19407        }
19408        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19409        if (sourceUids == null) {
19410            return;
19411        }
19412        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19413        if (sourceProcesses == null) {
19414            return;
19415        }
19416        Association ass = sourceProcesses.get(sourceProcess);
19417        if (ass == null || ass.mNesting <= 0) {
19418            return;
19419        }
19420        ass.mNesting--;
19421        if (ass.mNesting == 0) {
19422            long uptime = SystemClock.uptimeMillis();
19423            ass.mTime += uptime - ass.mStartTime;
19424            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19425                    += uptime - ass.mLastStateUptime;
19426            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19427        }
19428    }
19429
19430    private void noteUidProcessState(final int uid, final int state) {
19431        mBatteryStatsService.noteUidProcessState(uid, state);
19432        if (mTrackingAssociations) {
19433            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19434                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19435                        = mAssociations.valueAt(i1);
19436                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19437                    SparseArray<ArrayMap<String, Association>> sourceUids
19438                            = targetComponents.valueAt(i2);
19439                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19440                    if (sourceProcesses != null) {
19441                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19442                            Association ass = sourceProcesses.valueAt(i4);
19443                            if (ass.mNesting >= 1) {
19444                                // currently associated
19445                                long uptime = SystemClock.uptimeMillis();
19446                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19447                                        += uptime - ass.mLastStateUptime;
19448                                ass.mLastState = state;
19449                                ass.mLastStateUptime = uptime;
19450                            }
19451                        }
19452                    }
19453                }
19454            }
19455        }
19456    }
19457
19458    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19459            boolean doingAll, long now) {
19460        if (mAdjSeq == app.adjSeq) {
19461            // This adjustment has already been computed.
19462            return app.curRawAdj;
19463        }
19464
19465        if (app.thread == null) {
19466            app.adjSeq = mAdjSeq;
19467            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19468            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19469            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19470        }
19471
19472        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19473        app.adjSource = null;
19474        app.adjTarget = null;
19475        app.empty = false;
19476        app.cached = false;
19477
19478        final int activitiesSize = app.activities.size();
19479
19480        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19481            // The max adjustment doesn't allow this app to be anything
19482            // below foreground, so it is not worth doing work for it.
19483            app.adjType = "fixed";
19484            app.adjSeq = mAdjSeq;
19485            app.curRawAdj = app.maxAdj;
19486            app.foregroundActivities = false;
19487            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19488            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19489            // System processes can do UI, and when they do we want to have
19490            // them trim their memory after the user leaves the UI.  To
19491            // facilitate this, here we need to determine whether or not it
19492            // is currently showing UI.
19493            app.systemNoUi = true;
19494            if (app == TOP_APP) {
19495                app.systemNoUi = false;
19496                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19497                app.adjType = "pers-top-activity";
19498            } else if (app.hasTopUi) {
19499                app.systemNoUi = false;
19500                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19501                app.adjType = "pers-top-ui";
19502            } else if (activitiesSize > 0) {
19503                for (int j = 0; j < activitiesSize; j++) {
19504                    final ActivityRecord r = app.activities.get(j);
19505                    if (r.visible) {
19506                        app.systemNoUi = false;
19507                    }
19508                }
19509            }
19510            if (!app.systemNoUi) {
19511                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19512            }
19513            return (app.curAdj=app.maxAdj);
19514        }
19515
19516        app.systemNoUi = false;
19517
19518        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19519
19520        // Determine the importance of the process, starting with most
19521        // important to least, and assign an appropriate OOM adjustment.
19522        int adj;
19523        int schedGroup;
19524        int procState;
19525        boolean foregroundActivities = false;
19526        final ArraySet<BroadcastQueue> queues = new ArraySet<BroadcastQueue>();
19527        if (app == TOP_APP) {
19528            // The last app on the list is the foreground app.
19529            adj = ProcessList.FOREGROUND_APP_ADJ;
19530            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19531            app.adjType = "top-activity";
19532            foregroundActivities = true;
19533            procState = PROCESS_STATE_CUR_TOP;
19534        } else if (app.instrumentationClass != null) {
19535            // Don't want to kill running instrumentation.
19536            adj = ProcessList.FOREGROUND_APP_ADJ;
19537            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19538            app.adjType = "instrumentation";
19539            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19540        } else if (isReceivingBroadcastLocked(app, queues)) {
19541            // An app that is currently receiving a broadcast also
19542            // counts as being in the foreground for OOM killer purposes.
19543            // It's placed in a sched group based on the nature of the
19544            // broadcast as reflected by which queue it's active in.
19545            adj = ProcessList.FOREGROUND_APP_ADJ;
19546            schedGroup = (queues.contains(mFgBroadcastQueue))
19547                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19548            app.adjType = "broadcast";
19549            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19550        } else if (app.executingServices.size() > 0) {
19551            // An app that is currently executing a service callback also
19552            // counts as being in the foreground.
19553            adj = ProcessList.FOREGROUND_APP_ADJ;
19554            schedGroup = app.execServicesFg ?
19555                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19556            app.adjType = "exec-service";
19557            procState = ActivityManager.PROCESS_STATE_SERVICE;
19558            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19559        } else {
19560            // As far as we know the process is empty.  We may change our mind later.
19561            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19562            // At this point we don't actually know the adjustment.  Use the cached adj
19563            // value that the caller wants us to.
19564            adj = cachedAdj;
19565            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19566            app.cached = true;
19567            app.empty = true;
19568            app.adjType = "cch-empty";
19569        }
19570
19571        // Examine all activities if not already foreground.
19572        if (!foregroundActivities && activitiesSize > 0) {
19573            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19574            for (int j = 0; j < activitiesSize; j++) {
19575                final ActivityRecord r = app.activities.get(j);
19576                if (r.app != app) {
19577                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19578                            + " instead of expected " + app);
19579                    if (r.app == null || (r.app.uid == app.uid)) {
19580                        // Only fix things up when they look sane
19581                        r.app = app;
19582                    } else {
19583                        continue;
19584                    }
19585                }
19586                if (r.visible) {
19587                    // App has a visible activity; only upgrade adjustment.
19588                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19589                        adj = ProcessList.VISIBLE_APP_ADJ;
19590                        app.adjType = "visible";
19591                    }
19592                    if (procState > PROCESS_STATE_CUR_TOP) {
19593                        procState = PROCESS_STATE_CUR_TOP;
19594                    }
19595                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19596                    app.cached = false;
19597                    app.empty = false;
19598                    foregroundActivities = true;
19599                    if (r.task != null && minLayer > 0) {
19600                        final int layer = r.task.mLayerRank;
19601                        if (layer >= 0 && minLayer > layer) {
19602                            minLayer = layer;
19603                        }
19604                    }
19605                    break;
19606                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19607                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19608                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19609                        app.adjType = "pausing";
19610                    }
19611                    if (procState > PROCESS_STATE_CUR_TOP) {
19612                        procState = PROCESS_STATE_CUR_TOP;
19613                    }
19614                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19615                    app.cached = false;
19616                    app.empty = false;
19617                    foregroundActivities = true;
19618                } else if (r.state == ActivityState.STOPPING) {
19619                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19620                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19621                        app.adjType = "stopping";
19622                    }
19623                    // For the process state, we will at this point consider the
19624                    // process to be cached.  It will be cached either as an activity
19625                    // or empty depending on whether the activity is finishing.  We do
19626                    // this so that we can treat the process as cached for purposes of
19627                    // memory trimming (determing current memory level, trim command to
19628                    // send to process) since there can be an arbitrary number of stopping
19629                    // processes and they should soon all go into the cached state.
19630                    if (!r.finishing) {
19631                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19632                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19633                        }
19634                    }
19635                    app.cached = false;
19636                    app.empty = false;
19637                    foregroundActivities = true;
19638                } else {
19639                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19640                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19641                        app.adjType = "cch-act";
19642                    }
19643                }
19644            }
19645            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19646                adj += minLayer;
19647            }
19648        }
19649
19650        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19651                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19652            if (app.foregroundServices) {
19653                // The user is aware of this app, so make it visible.
19654                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19655                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19656                app.cached = false;
19657                app.adjType = "fg-service";
19658                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19659            } else if (app.forcingToForeground != null) {
19660                // The user is aware of this app, so make it visible.
19661                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19662                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19663                app.cached = false;
19664                app.adjType = "force-fg";
19665                app.adjSource = app.forcingToForeground;
19666                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19667            }
19668        }
19669
19670        if (app == mHeavyWeightProcess) {
19671            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19672                // We don't want to kill the current heavy-weight process.
19673                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19674                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19675                app.cached = false;
19676                app.adjType = "heavy";
19677            }
19678            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19679                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19680            }
19681        }
19682
19683        if (app == mHomeProcess) {
19684            if (adj > ProcessList.HOME_APP_ADJ) {
19685                // This process is hosting what we currently consider to be the
19686                // home app, so we don't want to let it go into the background.
19687                adj = ProcessList.HOME_APP_ADJ;
19688                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19689                app.cached = false;
19690                app.adjType = "home";
19691            }
19692            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19693                procState = ActivityManager.PROCESS_STATE_HOME;
19694            }
19695        }
19696
19697        if (app == mPreviousProcess && app.activities.size() > 0) {
19698            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19699                // This was the previous process that showed UI to the user.
19700                // We want to try to keep it around more aggressively, to give
19701                // a good experience around switching between two apps.
19702                adj = ProcessList.PREVIOUS_APP_ADJ;
19703                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19704                app.cached = false;
19705                app.adjType = "previous";
19706            }
19707            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19708                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19709            }
19710        }
19711
19712        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19713                + " reason=" + app.adjType);
19714
19715        // By default, we use the computed adjustment.  It may be changed if
19716        // there are applications dependent on our services or providers, but
19717        // this gives us a baseline and makes sure we don't get into an
19718        // infinite recursion.
19719        app.adjSeq = mAdjSeq;
19720        app.curRawAdj = adj;
19721        app.hasStartedServices = false;
19722
19723        if (mBackupTarget != null && app == mBackupTarget.app) {
19724            // If possible we want to avoid killing apps while they're being backed up
19725            if (adj > ProcessList.BACKUP_APP_ADJ) {
19726                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19727                adj = ProcessList.BACKUP_APP_ADJ;
19728                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19729                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19730                }
19731                app.adjType = "backup";
19732                app.cached = false;
19733            }
19734            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19735                procState = ActivityManager.PROCESS_STATE_BACKUP;
19736            }
19737        }
19738
19739        boolean mayBeTop = false;
19740
19741        for (int is = app.services.size()-1;
19742                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19743                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19744                        || procState > ActivityManager.PROCESS_STATE_TOP);
19745                is--) {
19746            ServiceRecord s = app.services.valueAt(is);
19747            if (s.startRequested) {
19748                app.hasStartedServices = true;
19749                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19750                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19751                }
19752                if (app.hasShownUi && app != mHomeProcess) {
19753                    // If this process has shown some UI, let it immediately
19754                    // go to the LRU list because it may be pretty heavy with
19755                    // UI stuff.  We'll tag it with a label just to help
19756                    // debug and understand what is going on.
19757                    if (adj > ProcessList.SERVICE_ADJ) {
19758                        app.adjType = "cch-started-ui-services";
19759                    }
19760                } else {
19761                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19762                        // This service has seen some activity within
19763                        // recent memory, so we will keep its process ahead
19764                        // of the background processes.
19765                        if (adj > ProcessList.SERVICE_ADJ) {
19766                            adj = ProcessList.SERVICE_ADJ;
19767                            app.adjType = "started-services";
19768                            app.cached = false;
19769                        }
19770                    }
19771                    // If we have let the service slide into the background
19772                    // state, still have some text describing what it is doing
19773                    // even though the service no longer has an impact.
19774                    if (adj > ProcessList.SERVICE_ADJ) {
19775                        app.adjType = "cch-started-services";
19776                    }
19777                }
19778            }
19779
19780            for (int conni = s.connections.size()-1;
19781                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19782                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19783                            || procState > ActivityManager.PROCESS_STATE_TOP);
19784                    conni--) {
19785                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19786                for (int i = 0;
19787                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19788                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19789                                || procState > ActivityManager.PROCESS_STATE_TOP);
19790                        i++) {
19791                    // XXX should compute this based on the max of
19792                    // all connected clients.
19793                    ConnectionRecord cr = clist.get(i);
19794                    if (cr.binding.client == app) {
19795                        // Binding to ourself is not interesting.
19796                        continue;
19797                    }
19798
19799                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19800                        ProcessRecord client = cr.binding.client;
19801                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19802                                TOP_APP, doingAll, now);
19803                        int clientProcState = client.curProcState;
19804                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19805                            // If the other app is cached for any reason, for purposes here
19806                            // we are going to consider it empty.  The specific cached state
19807                            // doesn't propagate except under certain conditions.
19808                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19809                        }
19810                        String adjType = null;
19811                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19812                            // Not doing bind OOM management, so treat
19813                            // this guy more like a started service.
19814                            if (app.hasShownUi && app != mHomeProcess) {
19815                                // If this process has shown some UI, let it immediately
19816                                // go to the LRU list because it may be pretty heavy with
19817                                // UI stuff.  We'll tag it with a label just to help
19818                                // debug and understand what is going on.
19819                                if (adj > clientAdj) {
19820                                    adjType = "cch-bound-ui-services";
19821                                }
19822                                app.cached = false;
19823                                clientAdj = adj;
19824                                clientProcState = procState;
19825                            } else {
19826                                if (now >= (s.lastActivity
19827                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19828                                    // This service has not seen activity within
19829                                    // recent memory, so allow it to drop to the
19830                                    // LRU list if there is no other reason to keep
19831                                    // it around.  We'll also tag it with a label just
19832                                    // to help debug and undertand what is going on.
19833                                    if (adj > clientAdj) {
19834                                        adjType = "cch-bound-services";
19835                                    }
19836                                    clientAdj = adj;
19837                                }
19838                            }
19839                        }
19840                        if (adj > clientAdj) {
19841                            // If this process has recently shown UI, and
19842                            // the process that is binding to it is less
19843                            // important than being visible, then we don't
19844                            // care about the binding as much as we care
19845                            // about letting this process get into the LRU
19846                            // list to be killed and restarted if needed for
19847                            // memory.
19848                            if (app.hasShownUi && app != mHomeProcess
19849                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19850                                adjType = "cch-bound-ui-services";
19851                            } else {
19852                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19853                                        |Context.BIND_IMPORTANT)) != 0) {
19854                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19855                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19856                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19857                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19858                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19859                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19860                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19861                                    adj = clientAdj;
19862                                } else {
19863                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19864                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19865                                    }
19866                                }
19867                                if (!client.cached) {
19868                                    app.cached = false;
19869                                }
19870                                adjType = "service";
19871                            }
19872                        }
19873                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19874                            // This will treat important bound services identically to
19875                            // the top app, which may behave differently than generic
19876                            // foreground work.
19877                            if (client.curSchedGroup > schedGroup) {
19878                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19879                                    schedGroup = client.curSchedGroup;
19880                                } else {
19881                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19882                                }
19883                            }
19884                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19885                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19886                                    // Special handling of clients who are in the top state.
19887                                    // We *may* want to consider this process to be in the
19888                                    // top state as well, but only if there is not another
19889                                    // reason for it to be running.  Being on the top is a
19890                                    // special state, meaning you are specifically running
19891                                    // for the current top app.  If the process is already
19892                                    // running in the background for some other reason, it
19893                                    // is more important to continue considering it to be
19894                                    // in the background state.
19895                                    mayBeTop = true;
19896                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19897                                } else {
19898                                    // Special handling for above-top states (persistent
19899                                    // processes).  These should not bring the current process
19900                                    // into the top state, since they are not on top.  Instead
19901                                    // give them the best state after that.
19902                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19903                                        clientProcState =
19904                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19905                                    } else if (mWakefulness
19906                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19907                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19908                                                    != 0) {
19909                                        clientProcState =
19910                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19911                                    } else {
19912                                        clientProcState =
19913                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19914                                    }
19915                                }
19916                            }
19917                        } else {
19918                            if (clientProcState <
19919                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19920                                clientProcState =
19921                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19922                            }
19923                        }
19924                        if (procState > clientProcState) {
19925                            procState = clientProcState;
19926                        }
19927                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19928                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19929                            app.pendingUiClean = true;
19930                        }
19931                        if (adjType != null) {
19932                            app.adjType = adjType;
19933                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19934                                    .REASON_SERVICE_IN_USE;
19935                            app.adjSource = cr.binding.client;
19936                            app.adjSourceProcState = clientProcState;
19937                            app.adjTarget = s.name;
19938                        }
19939                    }
19940                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19941                        app.treatLikeActivity = true;
19942                    }
19943                    final ActivityRecord a = cr.activity;
19944                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19945                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19946                            (a.visible || a.state == ActivityState.RESUMED ||
19947                             a.state == ActivityState.PAUSING)) {
19948                            adj = ProcessList.FOREGROUND_APP_ADJ;
19949                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19950                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19951                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19952                                } else {
19953                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19954                                }
19955                            }
19956                            app.cached = false;
19957                            app.adjType = "service";
19958                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19959                                    .REASON_SERVICE_IN_USE;
19960                            app.adjSource = a;
19961                            app.adjSourceProcState = procState;
19962                            app.adjTarget = s.name;
19963                        }
19964                    }
19965                }
19966            }
19967        }
19968
19969        for (int provi = app.pubProviders.size()-1;
19970                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19971                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19972                        || procState > ActivityManager.PROCESS_STATE_TOP);
19973                provi--) {
19974            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19975            for (int i = cpr.connections.size()-1;
19976                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19977                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19978                            || procState > ActivityManager.PROCESS_STATE_TOP);
19979                    i--) {
19980                ContentProviderConnection conn = cpr.connections.get(i);
19981                ProcessRecord client = conn.client;
19982                if (client == app) {
19983                    // Being our own client is not interesting.
19984                    continue;
19985                }
19986                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19987                int clientProcState = client.curProcState;
19988                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19989                    // If the other app is cached for any reason, for purposes here
19990                    // we are going to consider it empty.
19991                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19992                }
19993                if (adj > clientAdj) {
19994                    if (app.hasShownUi && app != mHomeProcess
19995                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19996                        app.adjType = "cch-ui-provider";
19997                    } else {
19998                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19999                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
20000                        app.adjType = "provider";
20001                    }
20002                    app.cached &= client.cached;
20003                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20004                            .REASON_PROVIDER_IN_USE;
20005                    app.adjSource = client;
20006                    app.adjSourceProcState = clientProcState;
20007                    app.adjTarget = cpr.name;
20008                }
20009                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20010                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20011                        // Special handling of clients who are in the top state.
20012                        // We *may* want to consider this process to be in the
20013                        // top state as well, but only if there is not another
20014                        // reason for it to be running.  Being on the top is a
20015                        // special state, meaning you are specifically running
20016                        // for the current top app.  If the process is already
20017                        // running in the background for some other reason, it
20018                        // is more important to continue considering it to be
20019                        // in the background state.
20020                        mayBeTop = true;
20021                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20022                    } else {
20023                        // Special handling for above-top states (persistent
20024                        // processes).  These should not bring the current process
20025                        // into the top state, since they are not on top.  Instead
20026                        // give them the best state after that.
20027                        clientProcState =
20028                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20029                    }
20030                }
20031                if (procState > clientProcState) {
20032                    procState = clientProcState;
20033                }
20034                if (client.curSchedGroup > schedGroup) {
20035                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20036                }
20037            }
20038            // If the provider has external (non-framework) process
20039            // dependencies, ensure that its adjustment is at least
20040            // FOREGROUND_APP_ADJ.
20041            if (cpr.hasExternalProcessHandles()) {
20042                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
20043                    adj = ProcessList.FOREGROUND_APP_ADJ;
20044                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20045                    app.cached = false;
20046                    app.adjType = "provider";
20047                    app.adjTarget = cpr.name;
20048                }
20049                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20050                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20051                }
20052            }
20053        }
20054
20055        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
20056            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20057                adj = ProcessList.PREVIOUS_APP_ADJ;
20058                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20059                app.cached = false;
20060                app.adjType = "provider";
20061            }
20062            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20063                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20064            }
20065        }
20066
20067        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
20068            // A client of one of our services or providers is in the top state.  We
20069            // *may* want to be in the top state, but not if we are already running in
20070            // the background for some other reason.  For the decision here, we are going
20071            // to pick out a few specific states that we want to remain in when a client
20072            // is top (states that tend to be longer-term) and otherwise allow it to go
20073            // to the top state.
20074            switch (procState) {
20075                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
20076                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
20077                case ActivityManager.PROCESS_STATE_SERVICE:
20078                    // These all are longer-term states, so pull them up to the top
20079                    // of the background states, but not all the way to the top state.
20080                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20081                    break;
20082                default:
20083                    // Otherwise, top is a better choice, so take it.
20084                    procState = ActivityManager.PROCESS_STATE_TOP;
20085                    break;
20086            }
20087        }
20088
20089        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
20090            if (app.hasClientActivities) {
20091                // This is a cached process, but with client activities.  Mark it so.
20092                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
20093                app.adjType = "cch-client-act";
20094            } else if (app.treatLikeActivity) {
20095                // This is a cached process, but somebody wants us to treat it like it has
20096                // an activity, okay!
20097                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20098                app.adjType = "cch-as-act";
20099            }
20100        }
20101
20102        if (adj == ProcessList.SERVICE_ADJ) {
20103            if (doingAll) {
20104                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20105                mNewNumServiceProcs++;
20106                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20107                if (!app.serviceb) {
20108                    // This service isn't far enough down on the LRU list to
20109                    // normally be a B service, but if we are low on RAM and it
20110                    // is large we want to force it down since we would prefer to
20111                    // keep launcher over it.
20112                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20113                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20114                        app.serviceHighRam = true;
20115                        app.serviceb = true;
20116                        //Slog.i(TAG, "ADJ " + app + " high ram!");
20117                    } else {
20118                        mNewNumAServiceProcs++;
20119                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
20120                    }
20121                } else {
20122                    app.serviceHighRam = false;
20123                }
20124            }
20125            if (app.serviceb) {
20126                adj = ProcessList.SERVICE_B_ADJ;
20127            }
20128        }
20129
20130        app.curRawAdj = adj;
20131
20132        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20133        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20134        if (adj > app.maxAdj) {
20135            adj = app.maxAdj;
20136            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20137                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20138            }
20139        }
20140
20141        // Do final modification to adj.  Everything we do between here and applying
20142        // the final setAdj must be done in this function, because we will also use
20143        // it when computing the final cached adj later.  Note that we don't need to
20144        // worry about this for max adj above, since max adj will always be used to
20145        // keep it out of the cached vaues.
20146        app.curAdj = app.modifyRawOomAdj(adj);
20147        app.curSchedGroup = schedGroup;
20148        app.curProcState = procState;
20149        app.foregroundActivities = foregroundActivities;
20150
20151        return app.curRawAdj;
20152    }
20153
20154    /**
20155     * Record new PSS sample for a process.
20156     */
20157    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20158            long now) {
20159        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20160                swapPss * 1024);
20161        proc.lastPssTime = now;
20162        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20163        if (DEBUG_PSS) Slog.d(TAG_PSS,
20164                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20165                + " state=" + ProcessList.makeProcStateString(procState));
20166        if (proc.initialIdlePss == 0) {
20167            proc.initialIdlePss = pss;
20168        }
20169        proc.lastPss = pss;
20170        proc.lastSwapPss = swapPss;
20171        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20172            proc.lastCachedPss = pss;
20173            proc.lastCachedSwapPss = swapPss;
20174        }
20175
20176        final SparseArray<Pair<Long, String>> watchUids
20177                = mMemWatchProcesses.getMap().get(proc.processName);
20178        Long check = null;
20179        if (watchUids != null) {
20180            Pair<Long, String> val = watchUids.get(proc.uid);
20181            if (val == null) {
20182                val = watchUids.get(0);
20183            }
20184            if (val != null) {
20185                check = val.first;
20186            }
20187        }
20188        if (check != null) {
20189            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20190                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20191                if (!isDebuggable) {
20192                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20193                        isDebuggable = true;
20194                    }
20195                }
20196                if (isDebuggable) {
20197                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20198                    final ProcessRecord myProc = proc;
20199                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20200                    mMemWatchDumpProcName = proc.processName;
20201                    mMemWatchDumpFile = heapdumpFile.toString();
20202                    mMemWatchDumpPid = proc.pid;
20203                    mMemWatchDumpUid = proc.uid;
20204                    BackgroundThread.getHandler().post(new Runnable() {
20205                        @Override
20206                        public void run() {
20207                            revokeUriPermission(ActivityThread.currentActivityThread()
20208                                            .getApplicationThread(),
20209                                    DumpHeapActivity.JAVA_URI,
20210                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20211                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20212                                    UserHandle.myUserId());
20213                            ParcelFileDescriptor fd = null;
20214                            try {
20215                                heapdumpFile.delete();
20216                                fd = ParcelFileDescriptor.open(heapdumpFile,
20217                                        ParcelFileDescriptor.MODE_CREATE |
20218                                                ParcelFileDescriptor.MODE_TRUNCATE |
20219                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20220                                                ParcelFileDescriptor.MODE_APPEND);
20221                                IApplicationThread thread = myProc.thread;
20222                                if (thread != null) {
20223                                    try {
20224                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20225                                                "Requesting dump heap from "
20226                                                + myProc + " to " + heapdumpFile);
20227                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20228                                    } catch (RemoteException e) {
20229                                    }
20230                                }
20231                            } catch (FileNotFoundException e) {
20232                                e.printStackTrace();
20233                            } finally {
20234                                if (fd != null) {
20235                                    try {
20236                                        fd.close();
20237                                    } catch (IOException e) {
20238                                    }
20239                                }
20240                            }
20241                        }
20242                    });
20243                } else {
20244                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20245                            + ", but debugging not enabled");
20246                }
20247            }
20248        }
20249    }
20250
20251    /**
20252     * Schedule PSS collection of a process.
20253     */
20254    void requestPssLocked(ProcessRecord proc, int procState) {
20255        if (mPendingPssProcesses.contains(proc)) {
20256            return;
20257        }
20258        if (mPendingPssProcesses.size() == 0) {
20259            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20260        }
20261        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20262        proc.pssProcState = procState;
20263        mPendingPssProcesses.add(proc);
20264    }
20265
20266    /**
20267     * Schedule PSS collection of all processes.
20268     */
20269    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20270        if (!always) {
20271            if (now < (mLastFullPssTime +
20272                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20273                return;
20274            }
20275        }
20276        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20277        mLastFullPssTime = now;
20278        mFullPssPending = true;
20279        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20280        mPendingPssProcesses.clear();
20281        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20282            ProcessRecord app = mLruProcesses.get(i);
20283            if (app.thread == null
20284                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20285                continue;
20286            }
20287            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20288                app.pssProcState = app.setProcState;
20289                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20290                        mTestPssMode, isSleepingLocked(), now);
20291                mPendingPssProcesses.add(app);
20292            }
20293        }
20294        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20295    }
20296
20297    public void setTestPssMode(boolean enabled) {
20298        synchronized (this) {
20299            mTestPssMode = enabled;
20300            if (enabled) {
20301                // Whenever we enable the mode, we want to take a snapshot all of current
20302                // process mem use.
20303                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20304            }
20305        }
20306    }
20307
20308    /**
20309     * Ask a given process to GC right now.
20310     */
20311    final void performAppGcLocked(ProcessRecord app) {
20312        try {
20313            app.lastRequestedGc = SystemClock.uptimeMillis();
20314            if (app.thread != null) {
20315                if (app.reportLowMemory) {
20316                    app.reportLowMemory = false;
20317                    app.thread.scheduleLowMemory();
20318                } else {
20319                    app.thread.processInBackground();
20320                }
20321            }
20322        } catch (Exception e) {
20323            // whatever.
20324        }
20325    }
20326
20327    /**
20328     * Returns true if things are idle enough to perform GCs.
20329     */
20330    private final boolean canGcNowLocked() {
20331        boolean processingBroadcasts = false;
20332        for (BroadcastQueue q : mBroadcastQueues) {
20333            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20334                processingBroadcasts = true;
20335            }
20336        }
20337        return !processingBroadcasts
20338                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20339    }
20340
20341    /**
20342     * Perform GCs on all processes that are waiting for it, but only
20343     * if things are idle.
20344     */
20345    final void performAppGcsLocked() {
20346        final int N = mProcessesToGc.size();
20347        if (N <= 0) {
20348            return;
20349        }
20350        if (canGcNowLocked()) {
20351            while (mProcessesToGc.size() > 0) {
20352                ProcessRecord proc = mProcessesToGc.remove(0);
20353                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20354                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20355                            <= SystemClock.uptimeMillis()) {
20356                        // To avoid spamming the system, we will GC processes one
20357                        // at a time, waiting a few seconds between each.
20358                        performAppGcLocked(proc);
20359                        scheduleAppGcsLocked();
20360                        return;
20361                    } else {
20362                        // It hasn't been long enough since we last GCed this
20363                        // process...  put it in the list to wait for its time.
20364                        addProcessToGcListLocked(proc);
20365                        break;
20366                    }
20367                }
20368            }
20369
20370            scheduleAppGcsLocked();
20371        }
20372    }
20373
20374    /**
20375     * If all looks good, perform GCs on all processes waiting for them.
20376     */
20377    final void performAppGcsIfAppropriateLocked() {
20378        if (canGcNowLocked()) {
20379            performAppGcsLocked();
20380            return;
20381        }
20382        // Still not idle, wait some more.
20383        scheduleAppGcsLocked();
20384    }
20385
20386    /**
20387     * Schedule the execution of all pending app GCs.
20388     */
20389    final void scheduleAppGcsLocked() {
20390        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20391
20392        if (mProcessesToGc.size() > 0) {
20393            // Schedule a GC for the time to the next process.
20394            ProcessRecord proc = mProcessesToGc.get(0);
20395            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20396
20397            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20398            long now = SystemClock.uptimeMillis();
20399            if (when < (now+GC_TIMEOUT)) {
20400                when = now + GC_TIMEOUT;
20401            }
20402            mHandler.sendMessageAtTime(msg, when);
20403        }
20404    }
20405
20406    /**
20407     * Add a process to the array of processes waiting to be GCed.  Keeps the
20408     * list in sorted order by the last GC time.  The process can't already be
20409     * on the list.
20410     */
20411    final void addProcessToGcListLocked(ProcessRecord proc) {
20412        boolean added = false;
20413        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20414            if (mProcessesToGc.get(i).lastRequestedGc <
20415                    proc.lastRequestedGc) {
20416                added = true;
20417                mProcessesToGc.add(i+1, proc);
20418                break;
20419            }
20420        }
20421        if (!added) {
20422            mProcessesToGc.add(0, proc);
20423        }
20424    }
20425
20426    /**
20427     * Set up to ask a process to GC itself.  This will either do it
20428     * immediately, or put it on the list of processes to gc the next
20429     * time things are idle.
20430     */
20431    final void scheduleAppGcLocked(ProcessRecord app) {
20432        long now = SystemClock.uptimeMillis();
20433        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20434            return;
20435        }
20436        if (!mProcessesToGc.contains(app)) {
20437            addProcessToGcListLocked(app);
20438            scheduleAppGcsLocked();
20439        }
20440    }
20441
20442    final void checkExcessivePowerUsageLocked(boolean doKills) {
20443        updateCpuStatsNow();
20444
20445        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20446        boolean doWakeKills = doKills;
20447        boolean doCpuKills = doKills;
20448        if (mLastPowerCheckRealtime == 0) {
20449            doWakeKills = false;
20450        }
20451        if (mLastPowerCheckUptime == 0) {
20452            doCpuKills = false;
20453        }
20454        if (stats.isScreenOn()) {
20455            doWakeKills = false;
20456        }
20457        final long curRealtime = SystemClock.elapsedRealtime();
20458        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20459        final long curUptime = SystemClock.uptimeMillis();
20460        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20461        mLastPowerCheckRealtime = curRealtime;
20462        mLastPowerCheckUptime = curUptime;
20463        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20464            doWakeKills = false;
20465        }
20466        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20467            doCpuKills = false;
20468        }
20469        int i = mLruProcesses.size();
20470        while (i > 0) {
20471            i--;
20472            ProcessRecord app = mLruProcesses.get(i);
20473            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20474                long wtime;
20475                synchronized (stats) {
20476                    wtime = stats.getProcessWakeTime(app.info.uid,
20477                            app.pid, curRealtime);
20478                }
20479                long wtimeUsed = wtime - app.lastWakeTime;
20480                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20481                if (DEBUG_POWER) {
20482                    StringBuilder sb = new StringBuilder(128);
20483                    sb.append("Wake for ");
20484                    app.toShortString(sb);
20485                    sb.append(": over ");
20486                    TimeUtils.formatDuration(realtimeSince, sb);
20487                    sb.append(" used ");
20488                    TimeUtils.formatDuration(wtimeUsed, sb);
20489                    sb.append(" (");
20490                    sb.append((wtimeUsed*100)/realtimeSince);
20491                    sb.append("%)");
20492                    Slog.i(TAG_POWER, sb.toString());
20493                    sb.setLength(0);
20494                    sb.append("CPU for ");
20495                    app.toShortString(sb);
20496                    sb.append(": over ");
20497                    TimeUtils.formatDuration(uptimeSince, sb);
20498                    sb.append(" used ");
20499                    TimeUtils.formatDuration(cputimeUsed, sb);
20500                    sb.append(" (");
20501                    sb.append((cputimeUsed*100)/uptimeSince);
20502                    sb.append("%)");
20503                    Slog.i(TAG_POWER, sb.toString());
20504                }
20505                // If a process has held a wake lock for more
20506                // than 50% of the time during this period,
20507                // that sounds bad.  Kill!
20508                if (doWakeKills && realtimeSince > 0
20509                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20510                    synchronized (stats) {
20511                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20512                                realtimeSince, wtimeUsed);
20513                    }
20514                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20515                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20516                } else if (doCpuKills && uptimeSince > 0
20517                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20518                    synchronized (stats) {
20519                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20520                                uptimeSince, cputimeUsed);
20521                    }
20522                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20523                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20524                } else {
20525                    app.lastWakeTime = wtime;
20526                    app.lastCpuTime = app.curCpuTime;
20527                }
20528            }
20529        }
20530    }
20531
20532    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20533            long nowElapsed) {
20534        boolean success = true;
20535
20536        if (app.curRawAdj != app.setRawAdj) {
20537            app.setRawAdj = app.curRawAdj;
20538        }
20539
20540        int changes = 0;
20541
20542        if (app.curAdj != app.setAdj) {
20543            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20544            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20545                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20546                    + app.adjType);
20547            app.setAdj = app.curAdj;
20548            app.verifiedAdj = ProcessList.INVALID_ADJ;
20549        }
20550
20551        if (app.setSchedGroup != app.curSchedGroup) {
20552            int oldSchedGroup = app.setSchedGroup;
20553            app.setSchedGroup = app.curSchedGroup;
20554            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20555                    "Setting sched group of " + app.processName
20556                    + " to " + app.curSchedGroup);
20557            if (app.waitingToKill != null && app.curReceivers.isEmpty()
20558                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20559                app.kill(app.waitingToKill, true);
20560                success = false;
20561            } else {
20562                int processGroup;
20563                switch (app.curSchedGroup) {
20564                    case ProcessList.SCHED_GROUP_BACKGROUND:
20565                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20566                        break;
20567                    case ProcessList.SCHED_GROUP_TOP_APP:
20568                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20569                        processGroup = Process.THREAD_GROUP_TOP_APP;
20570                        break;
20571                    default:
20572                        processGroup = Process.THREAD_GROUP_DEFAULT;
20573                        break;
20574                }
20575                long oldId = Binder.clearCallingIdentity();
20576                try {
20577                    Process.setProcessGroup(app.pid, processGroup);
20578                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20579                        // do nothing if we already switched to RT
20580                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20581                            // Switch VR thread for app to SCHED_FIFO
20582                            if (mInVrMode && app.vrThreadTid != 0) {
20583                                try {
20584                                    Process.setThreadScheduler(app.vrThreadTid,
20585                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20586                                } catch (IllegalArgumentException e) {
20587                                    // thread died, ignore
20588                                }
20589                            }
20590                            if (mUseFifoUiScheduling) {
20591                                // Switch UI pipeline for app to SCHED_FIFO
20592                                app.savedPriority = Process.getThreadPriority(app.pid);
20593                                try {
20594                                    Process.setThreadScheduler(app.pid,
20595                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20596                                } catch (IllegalArgumentException e) {
20597                                    // thread died, ignore
20598                                }
20599                                if (app.renderThreadTid != 0) {
20600                                    try {
20601                                        Process.setThreadScheduler(app.renderThreadTid,
20602                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20603                                    } catch (IllegalArgumentException e) {
20604                                        // thread died, ignore
20605                                    }
20606                                    if (DEBUG_OOM_ADJ) {
20607                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20608                                            app.renderThreadTid + ") to FIFO");
20609                                    }
20610                                } else {
20611                                    if (DEBUG_OOM_ADJ) {
20612                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20613                                    }
20614                                }
20615                            } else {
20616                                // Boost priority for top app UI and render threads
20617                                Process.setThreadPriority(app.pid, -10);
20618                                if (app.renderThreadTid != 0) {
20619                                    try {
20620                                        Process.setThreadPriority(app.renderThreadTid, -10);
20621                                    } catch (IllegalArgumentException e) {
20622                                        // thread died, ignore
20623                                    }
20624                                }
20625                            }
20626                        }
20627                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20628                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20629                        // Reset VR thread to SCHED_OTHER
20630                        // Safe to do even if we're not in VR mode
20631                        if (app.vrThreadTid != 0) {
20632                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20633                        }
20634                        if (mUseFifoUiScheduling) {
20635                            // Reset UI pipeline to SCHED_OTHER
20636                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20637                            Process.setThreadPriority(app.pid, app.savedPriority);
20638                            if (app.renderThreadTid != 0) {
20639                                Process.setThreadScheduler(app.renderThreadTid,
20640                                    Process.SCHED_OTHER, 0);
20641                                Process.setThreadPriority(app.renderThreadTid, -4);
20642                            }
20643                        } else {
20644                            // Reset priority for top app UI and render threads
20645                            Process.setThreadPriority(app.pid, 0);
20646                            if (app.renderThreadTid != 0) {
20647                                Process.setThreadPriority(app.renderThreadTid, 0);
20648                            }
20649                        }
20650                    }
20651                } catch (Exception e) {
20652                    Slog.w(TAG, "Failed setting process group of " + app.pid
20653                            + " to " + app.curSchedGroup);
20654                    e.printStackTrace();
20655                } finally {
20656                    Binder.restoreCallingIdentity(oldId);
20657                }
20658            }
20659        }
20660        if (app.repForegroundActivities != app.foregroundActivities) {
20661            app.repForegroundActivities = app.foregroundActivities;
20662            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20663        }
20664        if (app.repProcState != app.curProcState) {
20665            app.repProcState = app.curProcState;
20666            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20667            if (app.thread != null) {
20668                try {
20669                    if (false) {
20670                        //RuntimeException h = new RuntimeException("here");
20671                        Slog.i(TAG, "Sending new process state " + app.repProcState
20672                                + " to " + app /*, h*/);
20673                    }
20674                    app.thread.setProcessState(app.repProcState);
20675                } catch (RemoteException e) {
20676                }
20677            }
20678        }
20679        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20680                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20681            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20682                // Experimental code to more aggressively collect pss while
20683                // running test...  the problem is that this tends to collect
20684                // the data right when a process is transitioning between process
20685                // states, which well tend to give noisy data.
20686                long start = SystemClock.uptimeMillis();
20687                long pss = Debug.getPss(app.pid, mTmpLong, null);
20688                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20689                mPendingPssProcesses.remove(app);
20690                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20691                        + " to " + app.curProcState + ": "
20692                        + (SystemClock.uptimeMillis()-start) + "ms");
20693            }
20694            app.lastStateTime = now;
20695            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20696                    mTestPssMode, isSleepingLocked(), now);
20697            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20698                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20699                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20700                    + (app.nextPssTime-now) + ": " + app);
20701        } else {
20702            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20703                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20704                    mTestPssMode)))) {
20705                requestPssLocked(app, app.setProcState);
20706                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20707                        mTestPssMode, isSleepingLocked(), now);
20708            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20709                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20710        }
20711        if (app.setProcState != app.curProcState) {
20712            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20713                    "Proc state change of " + app.processName
20714                            + " to " + app.curProcState);
20715            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20716            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20717            if (setImportant && !curImportant) {
20718                // This app is no longer something we consider important enough to allow to
20719                // use arbitrary amounts of battery power.  Note
20720                // its current wake lock time to later know to kill it if
20721                // it is not behaving well.
20722                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20723                synchronized (stats) {
20724                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20725                            app.pid, nowElapsed);
20726                }
20727                app.lastCpuTime = app.curCpuTime;
20728
20729            }
20730            // Inform UsageStats of important process state change
20731            // Must be called before updating setProcState
20732            maybeUpdateUsageStatsLocked(app, nowElapsed);
20733
20734            app.setProcState = app.curProcState;
20735            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20736                app.notCachedSinceIdle = false;
20737            }
20738            if (!doingAll) {
20739                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20740            } else {
20741                app.procStateChanged = true;
20742            }
20743        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20744                > USAGE_STATS_INTERACTION_INTERVAL) {
20745            // For apps that sit around for a long time in the interactive state, we need
20746            // to report this at least once a day so they don't go idle.
20747            maybeUpdateUsageStatsLocked(app, nowElapsed);
20748        }
20749
20750        if (changes != 0) {
20751            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20752                    "Changes in " + app + ": " + changes);
20753            int i = mPendingProcessChanges.size()-1;
20754            ProcessChangeItem item = null;
20755            while (i >= 0) {
20756                item = mPendingProcessChanges.get(i);
20757                if (item.pid == app.pid) {
20758                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20759                            "Re-using existing item: " + item);
20760                    break;
20761                }
20762                i--;
20763            }
20764            if (i < 0) {
20765                // No existing item in pending changes; need a new one.
20766                final int NA = mAvailProcessChanges.size();
20767                if (NA > 0) {
20768                    item = mAvailProcessChanges.remove(NA-1);
20769                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20770                            "Retrieving available item: " + item);
20771                } else {
20772                    item = new ProcessChangeItem();
20773                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20774                            "Allocating new item: " + item);
20775                }
20776                item.changes = 0;
20777                item.pid = app.pid;
20778                item.uid = app.info.uid;
20779                if (mPendingProcessChanges.size() == 0) {
20780                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20781                            "*** Enqueueing dispatch processes changed!");
20782                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20783                }
20784                mPendingProcessChanges.add(item);
20785            }
20786            item.changes |= changes;
20787            item.processState = app.repProcState;
20788            item.foregroundActivities = app.repForegroundActivities;
20789            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20790                    "Item " + Integer.toHexString(System.identityHashCode(item))
20791                    + " " + app.toShortString() + ": changes=" + item.changes
20792                    + " procState=" + item.processState
20793                    + " foreground=" + item.foregroundActivities
20794                    + " type=" + app.adjType + " source=" + app.adjSource
20795                    + " target=" + app.adjTarget);
20796        }
20797
20798        return success;
20799    }
20800
20801    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20802        final UidRecord.ChangeItem pendingChange;
20803        if (uidRec == null || uidRec.pendingChange == null) {
20804            if (mPendingUidChanges.size() == 0) {
20805                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20806                        "*** Enqueueing dispatch uid changed!");
20807                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20808            }
20809            final int NA = mAvailUidChanges.size();
20810            if (NA > 0) {
20811                pendingChange = mAvailUidChanges.remove(NA-1);
20812                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20813                        "Retrieving available item: " + pendingChange);
20814            } else {
20815                pendingChange = new UidRecord.ChangeItem();
20816                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20817                        "Allocating new item: " + pendingChange);
20818            }
20819            if (uidRec != null) {
20820                uidRec.pendingChange = pendingChange;
20821                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20822                    // If this uid is going away, and we haven't yet reported it is gone,
20823                    // then do so now.
20824                    change = UidRecord.CHANGE_GONE_IDLE;
20825                }
20826            } else if (uid < 0) {
20827                throw new IllegalArgumentException("No UidRecord or uid");
20828            }
20829            pendingChange.uidRecord = uidRec;
20830            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20831            mPendingUidChanges.add(pendingChange);
20832        } else {
20833            pendingChange = uidRec.pendingChange;
20834            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20835                change = UidRecord.CHANGE_GONE_IDLE;
20836            }
20837        }
20838        pendingChange.change = change;
20839        pendingChange.processState = uidRec != null
20840                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20841        pendingChange.ephemeral = uidRec.ephemeral;
20842
20843        // Directly update the power manager, since we sit on top of it and it is critical
20844        // it be kept in sync (so wake locks will be held as soon as appropriate).
20845        if (mLocalPowerManager != null) {
20846            switch (change) {
20847                case UidRecord.CHANGE_GONE:
20848                case UidRecord.CHANGE_GONE_IDLE:
20849                    mLocalPowerManager.uidGone(pendingChange.uid);
20850                    break;
20851                case UidRecord.CHANGE_IDLE:
20852                    mLocalPowerManager.uidIdle(pendingChange.uid);
20853                    break;
20854                case UidRecord.CHANGE_ACTIVE:
20855                    mLocalPowerManager.uidActive(pendingChange.uid);
20856                    break;
20857                default:
20858                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
20859                            pendingChange.processState);
20860                    break;
20861            }
20862        }
20863    }
20864
20865    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20866            String authority) {
20867        if (app == null) return;
20868        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20869            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20870            if (userState == null) return;
20871            final long now = SystemClock.elapsedRealtime();
20872            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20873            if (lastReported == null || lastReported < now - 60 * 1000L) {
20874                if (mSystemReady) {
20875                    // Cannot touch the user stats if not system ready
20876                    mUsageStatsService.reportContentProviderUsage(
20877                            authority, providerPkgName, app.userId);
20878                }
20879                userState.mProviderLastReportedFg.put(authority, now);
20880            }
20881        }
20882    }
20883
20884    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20885        if (DEBUG_USAGE_STATS) {
20886            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20887                    + "] state changes: old = " + app.setProcState + ", new = "
20888                    + app.curProcState);
20889        }
20890        if (mUsageStatsService == null) {
20891            return;
20892        }
20893        boolean isInteraction;
20894        // To avoid some abuse patterns, we are going to be careful about what we consider
20895        // to be an app interaction.  Being the top activity doesn't count while the display
20896        // is sleeping, nor do short foreground services.
20897        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20898            isInteraction = true;
20899            app.fgInteractionTime = 0;
20900        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20901            if (app.fgInteractionTime == 0) {
20902                app.fgInteractionTime = nowElapsed;
20903                isInteraction = false;
20904            } else {
20905                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20906            }
20907        } else {
20908            // If the app was being forced to the foreground, by say a Toast, then
20909            // no need to treat it as an interaction
20910            isInteraction = app.forcingToForeground == null
20911                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20912            app.fgInteractionTime = 0;
20913        }
20914        if (isInteraction && (!app.reportedInteraction
20915                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20916            app.interactionEventTime = nowElapsed;
20917            String[] packages = app.getPackageList();
20918            if (packages != null) {
20919                for (int i = 0; i < packages.length; i++) {
20920                    mUsageStatsService.reportEvent(packages[i], app.userId,
20921                            UsageEvents.Event.SYSTEM_INTERACTION);
20922                }
20923            }
20924        }
20925        app.reportedInteraction = isInteraction;
20926        if (!isInteraction) {
20927            app.interactionEventTime = 0;
20928        }
20929    }
20930
20931    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20932        if (proc.thread != null) {
20933            if (proc.baseProcessTracker != null) {
20934                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20935            }
20936        }
20937    }
20938
20939    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20940            ProcessRecord TOP_APP, boolean doingAll, long now) {
20941        if (app.thread == null) {
20942            return false;
20943        }
20944
20945        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20946
20947        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20948    }
20949
20950    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20951            boolean oomAdj) {
20952        if (isForeground != proc.foregroundServices) {
20953            proc.foregroundServices = isForeground;
20954            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20955                    proc.info.uid);
20956            if (isForeground) {
20957                if (curProcs == null) {
20958                    curProcs = new ArrayList<ProcessRecord>();
20959                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20960                }
20961                if (!curProcs.contains(proc)) {
20962                    curProcs.add(proc);
20963                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20964                            proc.info.packageName, proc.info.uid);
20965                }
20966            } else {
20967                if (curProcs != null) {
20968                    if (curProcs.remove(proc)) {
20969                        mBatteryStatsService.noteEvent(
20970                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20971                                proc.info.packageName, proc.info.uid);
20972                        if (curProcs.size() <= 0) {
20973                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20974                        }
20975                    }
20976                }
20977            }
20978            if (oomAdj) {
20979                updateOomAdjLocked();
20980            }
20981        }
20982    }
20983
20984    private final ActivityRecord resumedAppLocked() {
20985        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
20986        String pkg;
20987        int uid;
20988        if (act != null) {
20989            pkg = act.packageName;
20990            uid = act.info.applicationInfo.uid;
20991        } else {
20992            pkg = null;
20993            uid = -1;
20994        }
20995        // Has the UID or resumed package name changed?
20996        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20997                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20998            if (mCurResumedPackage != null) {
20999                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
21000                        mCurResumedPackage, mCurResumedUid);
21001            }
21002            mCurResumedPackage = pkg;
21003            mCurResumedUid = uid;
21004            if (mCurResumedPackage != null) {
21005                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
21006                        mCurResumedPackage, mCurResumedUid);
21007            }
21008        }
21009        return act;
21010    }
21011
21012    final boolean updateOomAdjLocked(ProcessRecord app) {
21013        final ActivityRecord TOP_ACT = resumedAppLocked();
21014        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21015        final boolean wasCached = app.cached;
21016
21017        mAdjSeq++;
21018
21019        // This is the desired cached adjusment we want to tell it to use.
21020        // If our app is currently cached, we know it, and that is it.  Otherwise,
21021        // we don't know it yet, and it needs to now be cached we will then
21022        // need to do a complete oom adj.
21023        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
21024                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
21025        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
21026                SystemClock.uptimeMillis());
21027        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
21028            // Changed to/from cached state, so apps after it in the LRU
21029            // list may also be changed.
21030            updateOomAdjLocked();
21031        }
21032        return success;
21033    }
21034
21035    final void updateOomAdjLocked() {
21036        final ActivityRecord TOP_ACT = resumedAppLocked();
21037        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21038        final long now = SystemClock.uptimeMillis();
21039        final long nowElapsed = SystemClock.elapsedRealtime();
21040        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
21041        final int N = mLruProcesses.size();
21042
21043        if (false) {
21044            RuntimeException e = new RuntimeException();
21045            e.fillInStackTrace();
21046            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
21047        }
21048
21049        // Reset state in all uid records.
21050        for (int i=mActiveUids.size()-1; i>=0; i--) {
21051            final UidRecord uidRec = mActiveUids.valueAt(i);
21052            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21053                    "Starting update of " + uidRec);
21054            uidRec.reset();
21055        }
21056
21057        mStackSupervisor.rankTaskLayersIfNeeded();
21058
21059        mAdjSeq++;
21060        mNewNumServiceProcs = 0;
21061        mNewNumAServiceProcs = 0;
21062
21063        final int emptyProcessLimit;
21064        final int cachedProcessLimit;
21065        if (mProcessLimit <= 0) {
21066            emptyProcessLimit = cachedProcessLimit = 0;
21067        } else if (mProcessLimit == 1) {
21068            emptyProcessLimit = 1;
21069            cachedProcessLimit = 0;
21070        } else {
21071            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
21072            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
21073        }
21074
21075        // Let's determine how many processes we have running vs.
21076        // how many slots we have for background processes; we may want
21077        // to put multiple processes in a slot of there are enough of
21078        // them.
21079        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
21080                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
21081        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
21082        if (numEmptyProcs > cachedProcessLimit) {
21083            // If there are more empty processes than our limit on cached
21084            // processes, then use the cached process limit for the factor.
21085            // This ensures that the really old empty processes get pushed
21086            // down to the bottom, so if we are running low on memory we will
21087            // have a better chance at keeping around more cached processes
21088            // instead of a gazillion empty processes.
21089            numEmptyProcs = cachedProcessLimit;
21090        }
21091        int emptyFactor = numEmptyProcs/numSlots;
21092        if (emptyFactor < 1) emptyFactor = 1;
21093        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
21094        if (cachedFactor < 1) cachedFactor = 1;
21095        int stepCached = 0;
21096        int stepEmpty = 0;
21097        int numCached = 0;
21098        int numEmpty = 0;
21099        int numTrimming = 0;
21100
21101        mNumNonCachedProcs = 0;
21102        mNumCachedHiddenProcs = 0;
21103
21104        // First update the OOM adjustment for each of the
21105        // application processes based on their current state.
21106        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
21107        int nextCachedAdj = curCachedAdj+1;
21108        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
21109        int nextEmptyAdj = curEmptyAdj+2;
21110        for (int i=N-1; i>=0; i--) {
21111            ProcessRecord app = mLruProcesses.get(i);
21112            if (!app.killedByAm && app.thread != null) {
21113                app.procStateChanged = false;
21114                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
21115
21116                // If we haven't yet assigned the final cached adj
21117                // to the process, do that now.
21118                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21119                    switch (app.curProcState) {
21120                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21121                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21122                            // This process is a cached process holding activities...
21123                            // assign it the next cached value for that type, and then
21124                            // step that cached level.
21125                            app.curRawAdj = curCachedAdj;
21126                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21127                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21128                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21129                                    + ")");
21130                            if (curCachedAdj != nextCachedAdj) {
21131                                stepCached++;
21132                                if (stepCached >= cachedFactor) {
21133                                    stepCached = 0;
21134                                    curCachedAdj = nextCachedAdj;
21135                                    nextCachedAdj += 2;
21136                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21137                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21138                                    }
21139                                }
21140                            }
21141                            break;
21142                        default:
21143                            // For everything else, assign next empty cached process
21144                            // level and bump that up.  Note that this means that
21145                            // long-running services that have dropped down to the
21146                            // cached level will be treated as empty (since their process
21147                            // state is still as a service), which is what we want.
21148                            app.curRawAdj = curEmptyAdj;
21149                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21150                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21151                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21152                                    + ")");
21153                            if (curEmptyAdj != nextEmptyAdj) {
21154                                stepEmpty++;
21155                                if (stepEmpty >= emptyFactor) {
21156                                    stepEmpty = 0;
21157                                    curEmptyAdj = nextEmptyAdj;
21158                                    nextEmptyAdj += 2;
21159                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21160                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21161                                    }
21162                                }
21163                            }
21164                            break;
21165                    }
21166                }
21167
21168                applyOomAdjLocked(app, true, now, nowElapsed);
21169
21170                // Count the number of process types.
21171                switch (app.curProcState) {
21172                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21173                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21174                        mNumCachedHiddenProcs++;
21175                        numCached++;
21176                        if (numCached > cachedProcessLimit) {
21177                            app.kill("cached #" + numCached, true);
21178                        }
21179                        break;
21180                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21181                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21182                                && app.lastActivityTime < oldTime) {
21183                            app.kill("empty for "
21184                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21185                                    / 1000) + "s", true);
21186                        } else {
21187                            numEmpty++;
21188                            if (numEmpty > emptyProcessLimit) {
21189                                app.kill("empty #" + numEmpty, true);
21190                            }
21191                        }
21192                        break;
21193                    default:
21194                        mNumNonCachedProcs++;
21195                        break;
21196                }
21197
21198                if (app.isolated && app.services.size() <= 0) {
21199                    // If this is an isolated process, and there are no
21200                    // services running in it, then the process is no longer
21201                    // needed.  We agressively kill these because we can by
21202                    // definition not re-use the same process again, and it is
21203                    // good to avoid having whatever code was running in them
21204                    // left sitting around after no longer needed.
21205                    app.kill("isolated not needed", true);
21206                } else {
21207                    // Keeping this process, update its uid.
21208                    final UidRecord uidRec = app.uidRecord;
21209                    if (uidRec != null) {
21210                        uidRec.ephemeral = app.info.isEphemeralApp();
21211                        if (uidRec.curProcState > app.curProcState) {
21212                            uidRec.curProcState = app.curProcState;
21213                        }
21214                    }
21215                }
21216
21217                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21218                        && !app.killedByAm) {
21219                    numTrimming++;
21220                }
21221            }
21222        }
21223
21224        mNumServiceProcs = mNewNumServiceProcs;
21225
21226        // Now determine the memory trimming level of background processes.
21227        // Unfortunately we need to start at the back of the list to do this
21228        // properly.  We only do this if the number of background apps we
21229        // are managing to keep around is less than half the maximum we desire;
21230        // if we are keeping a good number around, we'll let them use whatever
21231        // memory they want.
21232        final int numCachedAndEmpty = numCached + numEmpty;
21233        int memFactor;
21234        if (numCached <= ProcessList.TRIM_CACHED_APPS
21235                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21236            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21237                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21238            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21239                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21240            } else {
21241                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21242            }
21243        } else {
21244            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21245        }
21246        // We always allow the memory level to go up (better).  We only allow it to go
21247        // down if we are in a state where that is allowed, *and* the total number of processes
21248        // has gone down since last time.
21249        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21250                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21251                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21252        if (memFactor > mLastMemoryLevel) {
21253            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21254                memFactor = mLastMemoryLevel;
21255                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21256            }
21257        }
21258        if (memFactor != mLastMemoryLevel) {
21259            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21260        }
21261        mLastMemoryLevel = memFactor;
21262        mLastNumProcesses = mLruProcesses.size();
21263        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21264        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21265        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21266            if (mLowRamStartTime == 0) {
21267                mLowRamStartTime = now;
21268            }
21269            int step = 0;
21270            int fgTrimLevel;
21271            switch (memFactor) {
21272                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21273                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21274                    break;
21275                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21276                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21277                    break;
21278                default:
21279                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21280                    break;
21281            }
21282            int factor = numTrimming/3;
21283            int minFactor = 2;
21284            if (mHomeProcess != null) minFactor++;
21285            if (mPreviousProcess != null) minFactor++;
21286            if (factor < minFactor) factor = minFactor;
21287            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21288            for (int i=N-1; i>=0; i--) {
21289                ProcessRecord app = mLruProcesses.get(i);
21290                if (allChanged || app.procStateChanged) {
21291                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21292                    app.procStateChanged = false;
21293                }
21294                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21295                        && !app.killedByAm) {
21296                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21297                        try {
21298                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21299                                    "Trimming memory of " + app.processName + " to " + curLevel);
21300                            app.thread.scheduleTrimMemory(curLevel);
21301                        } catch (RemoteException e) {
21302                        }
21303                        if (false) {
21304                            // For now we won't do this; our memory trimming seems
21305                            // to be good enough at this point that destroying
21306                            // activities causes more harm than good.
21307                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21308                                    && app != mHomeProcess && app != mPreviousProcess) {
21309                                // Need to do this on its own message because the stack may not
21310                                // be in a consistent state at this point.
21311                                // For these apps we will also finish their activities
21312                                // to help them free memory.
21313                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21314                            }
21315                        }
21316                    }
21317                    app.trimMemoryLevel = curLevel;
21318                    step++;
21319                    if (step >= factor) {
21320                        step = 0;
21321                        switch (curLevel) {
21322                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21323                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21324                                break;
21325                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21326                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21327                                break;
21328                        }
21329                    }
21330                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21331                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21332                            && app.thread != null) {
21333                        try {
21334                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21335                                    "Trimming memory of heavy-weight " + app.processName
21336                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21337                            app.thread.scheduleTrimMemory(
21338                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21339                        } catch (RemoteException e) {
21340                        }
21341                    }
21342                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21343                } else {
21344                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21345                            || app.systemNoUi) && app.pendingUiClean) {
21346                        // If this application is now in the background and it
21347                        // had done UI, then give it the special trim level to
21348                        // have it free UI resources.
21349                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21350                        if (app.trimMemoryLevel < level && app.thread != null) {
21351                            try {
21352                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21353                                        "Trimming memory of bg-ui " + app.processName
21354                                        + " to " + level);
21355                                app.thread.scheduleTrimMemory(level);
21356                            } catch (RemoteException e) {
21357                            }
21358                        }
21359                        app.pendingUiClean = false;
21360                    }
21361                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21362                        try {
21363                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21364                                    "Trimming memory of fg " + app.processName
21365                                    + " to " + fgTrimLevel);
21366                            app.thread.scheduleTrimMemory(fgTrimLevel);
21367                        } catch (RemoteException e) {
21368                        }
21369                    }
21370                    app.trimMemoryLevel = fgTrimLevel;
21371                }
21372            }
21373        } else {
21374            if (mLowRamStartTime != 0) {
21375                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21376                mLowRamStartTime = 0;
21377            }
21378            for (int i=N-1; i>=0; i--) {
21379                ProcessRecord app = mLruProcesses.get(i);
21380                if (allChanged || app.procStateChanged) {
21381                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21382                    app.procStateChanged = false;
21383                }
21384                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21385                        || app.systemNoUi) && app.pendingUiClean) {
21386                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21387                            && app.thread != null) {
21388                        try {
21389                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21390                                    "Trimming memory of ui hidden " + app.processName
21391                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21392                            app.thread.scheduleTrimMemory(
21393                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21394                        } catch (RemoteException e) {
21395                        }
21396                    }
21397                    app.pendingUiClean = false;
21398                }
21399                app.trimMemoryLevel = 0;
21400            }
21401        }
21402
21403        if (mAlwaysFinishActivities) {
21404            // Need to do this on its own message because the stack may not
21405            // be in a consistent state at this point.
21406            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21407        }
21408
21409        if (allChanged) {
21410            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21411        }
21412
21413        // Update from any uid changes.
21414        if (mLocalPowerManager != null) {
21415            mLocalPowerManager.startUidChanges();
21416        }
21417        for (int i=mActiveUids.size()-1; i>=0; i--) {
21418            final UidRecord uidRec = mActiveUids.valueAt(i);
21419            int uidChange = UidRecord.CHANGE_PROCSTATE;
21420            if (uidRec.setProcState != uidRec.curProcState) {
21421                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21422                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21423                        + " to " + uidRec.curProcState);
21424                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21425                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21426                        uidRec.lastBackgroundTime = nowElapsed;
21427                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21428                            // Note: the background settle time is in elapsed realtime, while
21429                            // the handler time base is uptime.  All this means is that we may
21430                            // stop background uids later than we had intended, but that only
21431                            // happens because the device was sleeping so we are okay anyway.
21432                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21433                        }
21434                    }
21435                } else {
21436                    if (uidRec.idle) {
21437                        uidChange = UidRecord.CHANGE_ACTIVE;
21438                        uidRec.idle = false;
21439                    }
21440                    uidRec.lastBackgroundTime = 0;
21441                }
21442                uidRec.setProcState = uidRec.curProcState;
21443                enqueueUidChangeLocked(uidRec, -1, uidChange);
21444                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21445            }
21446        }
21447        if (mLocalPowerManager != null) {
21448            mLocalPowerManager.finishUidChanges();
21449        }
21450
21451        if (mProcessStats.shouldWriteNowLocked(now)) {
21452            mHandler.post(new Runnable() {
21453                @Override public void run() {
21454                    synchronized (ActivityManagerService.this) {
21455                        mProcessStats.writeStateAsyncLocked();
21456                    }
21457                }
21458            });
21459        }
21460
21461        if (DEBUG_OOM_ADJ) {
21462            final long duration = SystemClock.uptimeMillis() - now;
21463            if (false) {
21464                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21465                        new RuntimeException("here").fillInStackTrace());
21466            } else {
21467                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21468            }
21469        }
21470    }
21471
21472    @Override
21473    public void makePackageIdle(String packageName, int userId) {
21474        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
21475                != PackageManager.PERMISSION_GRANTED) {
21476            String msg = "Permission Denial: makePackageIdle() from pid="
21477                    + Binder.getCallingPid()
21478                    + ", uid=" + Binder.getCallingUid()
21479                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
21480            Slog.w(TAG, msg);
21481            throw new SecurityException(msg);
21482        }
21483        final int callingPid = Binder.getCallingPid();
21484        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
21485                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
21486        long callingId = Binder.clearCallingIdentity();
21487        synchronized(this) {
21488            try {
21489                IPackageManager pm = AppGlobals.getPackageManager();
21490                int pkgUid = -1;
21491                try {
21492                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
21493                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
21494                } catch (RemoteException e) {
21495                }
21496                if (pkgUid == -1) {
21497                    throw new IllegalArgumentException("Unknown package name " + packageName);
21498                }
21499
21500                if (mLocalPowerManager != null) {
21501                    mLocalPowerManager.startUidChanges();
21502                }
21503                final int appId = UserHandle.getAppId(pkgUid);
21504                final int N = mActiveUids.size();
21505                for (int i=N-1; i>=0; i--) {
21506                    final UidRecord uidRec = mActiveUids.valueAt(i);
21507                    final long bgTime = uidRec.lastBackgroundTime;
21508                    if (bgTime > 0 && !uidRec.idle) {
21509                        if (UserHandle.getAppId(uidRec.uid) == appId) {
21510                            if (userId == UserHandle.USER_ALL ||
21511                                    userId == UserHandle.getUserId(uidRec.uid)) {
21512                                uidRec.idle = true;
21513                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
21514                                        + " from package " + packageName + " user " + userId);
21515                                doStopUidLocked(uidRec.uid, uidRec);
21516                            }
21517                        }
21518                    }
21519                }
21520            } finally {
21521                if (mLocalPowerManager != null) {
21522                    mLocalPowerManager.finishUidChanges();
21523                }
21524                Binder.restoreCallingIdentity(callingId);
21525            }
21526        }
21527    }
21528
21529    final void idleUids() {
21530        synchronized (this) {
21531            final int N = mActiveUids.size();
21532            if (N <= 0) {
21533                return;
21534            }
21535            final long nowElapsed = SystemClock.elapsedRealtime();
21536            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21537            long nextTime = 0;
21538            if (mLocalPowerManager != null) {
21539                mLocalPowerManager.startUidChanges();
21540            }
21541            for (int i=N-1; i>=0; i--) {
21542                final UidRecord uidRec = mActiveUids.valueAt(i);
21543                final long bgTime = uidRec.lastBackgroundTime;
21544                if (bgTime > 0 && !uidRec.idle) {
21545                    if (bgTime <= maxBgTime) {
21546                        uidRec.idle = true;
21547                        doStopUidLocked(uidRec.uid, uidRec);
21548                    } else {
21549                        if (nextTime == 0 || nextTime > bgTime) {
21550                            nextTime = bgTime;
21551                        }
21552                    }
21553                }
21554            }
21555            if (mLocalPowerManager != null) {
21556                mLocalPowerManager.finishUidChanges();
21557            }
21558            if (nextTime > 0) {
21559                mHandler.removeMessages(IDLE_UIDS_MSG);
21560                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21561                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21562            }
21563        }
21564    }
21565
21566    final void runInBackgroundDisabled(int uid) {
21567        synchronized (this) {
21568            UidRecord uidRec = mActiveUids.get(uid);
21569            if (uidRec != null) {
21570                // This uid is actually running...  should it be considered background now?
21571                if (uidRec.idle) {
21572                    doStopUidLocked(uidRec.uid, uidRec);
21573                }
21574            } else {
21575                // This uid isn't actually running...  still send a report about it being "stopped".
21576                doStopUidLocked(uid, null);
21577            }
21578        }
21579    }
21580
21581    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21582        mServices.stopInBackgroundLocked(uid);
21583        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21584    }
21585
21586    final void trimApplications() {
21587        synchronized (this) {
21588            int i;
21589
21590            // First remove any unused application processes whose package
21591            // has been removed.
21592            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21593                final ProcessRecord app = mRemovedProcesses.get(i);
21594                if (app.activities.size() == 0
21595                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
21596                    Slog.i(
21597                        TAG, "Exiting empty application process "
21598                        + app.toShortString() + " ("
21599                        + (app.thread != null ? app.thread.asBinder() : null)
21600                        + ")\n");
21601                    if (app.pid > 0 && app.pid != MY_PID) {
21602                        app.kill("empty", false);
21603                    } else {
21604                        try {
21605                            app.thread.scheduleExit();
21606                        } catch (Exception e) {
21607                            // Ignore exceptions.
21608                        }
21609                    }
21610                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21611                    mRemovedProcesses.remove(i);
21612
21613                    if (app.persistent) {
21614                        addAppLocked(app.info, false, null /* ABI override */);
21615                    }
21616                }
21617            }
21618
21619            // Now update the oom adj for all processes.
21620            updateOomAdjLocked();
21621        }
21622    }
21623
21624    /** This method sends the specified signal to each of the persistent apps */
21625    public void signalPersistentProcesses(int sig) throws RemoteException {
21626        if (sig != Process.SIGNAL_USR1) {
21627            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21628        }
21629
21630        synchronized (this) {
21631            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21632                    != PackageManager.PERMISSION_GRANTED) {
21633                throw new SecurityException("Requires permission "
21634                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21635            }
21636
21637            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21638                ProcessRecord r = mLruProcesses.get(i);
21639                if (r.thread != null && r.persistent) {
21640                    Process.sendSignal(r.pid, sig);
21641                }
21642            }
21643        }
21644    }
21645
21646    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21647        if (proc == null || proc == mProfileProc) {
21648            proc = mProfileProc;
21649            profileType = mProfileType;
21650            clearProfilerLocked();
21651        }
21652        if (proc == null) {
21653            return;
21654        }
21655        try {
21656            proc.thread.profilerControl(false, null, profileType);
21657        } catch (RemoteException e) {
21658            throw new IllegalStateException("Process disappeared");
21659        }
21660    }
21661
21662    private void clearProfilerLocked() {
21663        if (mProfileFd != null) {
21664            try {
21665                mProfileFd.close();
21666            } catch (IOException e) {
21667            }
21668        }
21669        mProfileApp = null;
21670        mProfileProc = null;
21671        mProfileFile = null;
21672        mProfileType = 0;
21673        mAutoStopProfiler = false;
21674        mSamplingInterval = 0;
21675    }
21676
21677    public boolean profileControl(String process, int userId, boolean start,
21678            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21679
21680        try {
21681            synchronized (this) {
21682                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21683                // its own permission.
21684                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21685                        != PackageManager.PERMISSION_GRANTED) {
21686                    throw new SecurityException("Requires permission "
21687                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21688                }
21689
21690                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21691                    throw new IllegalArgumentException("null profile info or fd");
21692                }
21693
21694                ProcessRecord proc = null;
21695                if (process != null) {
21696                    proc = findProcessLocked(process, userId, "profileControl");
21697                }
21698
21699                if (start && (proc == null || proc.thread == null)) {
21700                    throw new IllegalArgumentException("Unknown process: " + process);
21701                }
21702
21703                if (start) {
21704                    stopProfilerLocked(null, 0);
21705                    setProfileApp(proc.info, proc.processName, profilerInfo);
21706                    mProfileProc = proc;
21707                    mProfileType = profileType;
21708                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21709                    try {
21710                        fd = fd.dup();
21711                    } catch (IOException e) {
21712                        fd = null;
21713                    }
21714                    profilerInfo.profileFd = fd;
21715                    proc.thread.profilerControl(start, profilerInfo, profileType);
21716                    fd = null;
21717                    mProfileFd = null;
21718                } else {
21719                    stopProfilerLocked(proc, profileType);
21720                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21721                        try {
21722                            profilerInfo.profileFd.close();
21723                        } catch (IOException e) {
21724                        }
21725                    }
21726                }
21727
21728                return true;
21729            }
21730        } catch (RemoteException e) {
21731            throw new IllegalStateException("Process disappeared");
21732        } finally {
21733            if (profilerInfo != null && profilerInfo.profileFd != null) {
21734                try {
21735                    profilerInfo.profileFd.close();
21736                } catch (IOException e) {
21737                }
21738            }
21739        }
21740    }
21741
21742    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21743        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21744                userId, true, ALLOW_FULL_ONLY, callName, null);
21745        ProcessRecord proc = null;
21746        try {
21747            int pid = Integer.parseInt(process);
21748            synchronized (mPidsSelfLocked) {
21749                proc = mPidsSelfLocked.get(pid);
21750            }
21751        } catch (NumberFormatException e) {
21752        }
21753
21754        if (proc == null) {
21755            ArrayMap<String, SparseArray<ProcessRecord>> all
21756                    = mProcessNames.getMap();
21757            SparseArray<ProcessRecord> procs = all.get(process);
21758            if (procs != null && procs.size() > 0) {
21759                proc = procs.valueAt(0);
21760                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21761                    for (int i=1; i<procs.size(); i++) {
21762                        ProcessRecord thisProc = procs.valueAt(i);
21763                        if (thisProc.userId == userId) {
21764                            proc = thisProc;
21765                            break;
21766                        }
21767                    }
21768                }
21769            }
21770        }
21771
21772        return proc;
21773    }
21774
21775    public boolean dumpHeap(String process, int userId, boolean managed,
21776            String path, ParcelFileDescriptor fd) throws RemoteException {
21777
21778        try {
21779            synchronized (this) {
21780                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21781                // its own permission (same as profileControl).
21782                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21783                        != PackageManager.PERMISSION_GRANTED) {
21784                    throw new SecurityException("Requires permission "
21785                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21786                }
21787
21788                if (fd == null) {
21789                    throw new IllegalArgumentException("null fd");
21790                }
21791
21792                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21793                if (proc == null || proc.thread == null) {
21794                    throw new IllegalArgumentException("Unknown process: " + process);
21795                }
21796
21797                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21798                if (!isDebuggable) {
21799                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21800                        throw new SecurityException("Process not debuggable: " + proc);
21801                    }
21802                }
21803
21804                proc.thread.dumpHeap(managed, path, fd);
21805                fd = null;
21806                return true;
21807            }
21808        } catch (RemoteException e) {
21809            throw new IllegalStateException("Process disappeared");
21810        } finally {
21811            if (fd != null) {
21812                try {
21813                    fd.close();
21814                } catch (IOException e) {
21815                }
21816            }
21817        }
21818    }
21819
21820    @Override
21821    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21822            String reportPackage) {
21823        if (processName != null) {
21824            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21825                    "setDumpHeapDebugLimit()");
21826        } else {
21827            synchronized (mPidsSelfLocked) {
21828                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21829                if (proc == null) {
21830                    throw new SecurityException("No process found for calling pid "
21831                            + Binder.getCallingPid());
21832                }
21833                if (!Build.IS_DEBUGGABLE
21834                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21835                    throw new SecurityException("Not running a debuggable build");
21836                }
21837                processName = proc.processName;
21838                uid = proc.uid;
21839                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21840                    throw new SecurityException("Package " + reportPackage + " is not running in "
21841                            + proc);
21842                }
21843            }
21844        }
21845        synchronized (this) {
21846            if (maxMemSize > 0) {
21847                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21848            } else {
21849                if (uid != 0) {
21850                    mMemWatchProcesses.remove(processName, uid);
21851                } else {
21852                    mMemWatchProcesses.getMap().remove(processName);
21853                }
21854            }
21855        }
21856    }
21857
21858    @Override
21859    public void dumpHeapFinished(String path) {
21860        synchronized (this) {
21861            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21862                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21863                        + " does not match last pid " + mMemWatchDumpPid);
21864                return;
21865            }
21866            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21867                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21868                        + " does not match last path " + mMemWatchDumpFile);
21869                return;
21870            }
21871            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21872            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21873        }
21874    }
21875
21876    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21877    public void monitor() {
21878        synchronized (this) { }
21879    }
21880
21881    void onCoreSettingsChange(Bundle settings) {
21882        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21883            ProcessRecord processRecord = mLruProcesses.get(i);
21884            try {
21885                if (processRecord.thread != null) {
21886                    processRecord.thread.setCoreSettings(settings);
21887                }
21888            } catch (RemoteException re) {
21889                /* ignore */
21890            }
21891        }
21892    }
21893
21894    // Multi-user methods
21895
21896    /**
21897     * Start user, if its not already running, but don't bring it to foreground.
21898     */
21899    @Override
21900    public boolean startUserInBackground(final int userId) {
21901        return mUserController.startUser(userId, /* foreground */ false);
21902    }
21903
21904    @Override
21905    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21906        return mUserController.unlockUser(userId, token, secret, listener);
21907    }
21908
21909    @Override
21910    public boolean switchUser(final int targetUserId) {
21911        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21912        int currentUserId;
21913        UserInfo targetUserInfo;
21914        synchronized (this) {
21915            currentUserId = mUserController.getCurrentUserIdLocked();
21916            targetUserInfo = mUserController.getUserInfo(targetUserId);
21917            if (targetUserId == currentUserId) {
21918                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
21919                return true;
21920            }
21921            if (targetUserInfo == null) {
21922                Slog.w(TAG, "No user info for user #" + targetUserId);
21923                return false;
21924            }
21925            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21926                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21927                        + " when device is in demo mode");
21928                return false;
21929            }
21930            if (!targetUserInfo.supportsSwitchTo()) {
21931                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21932                return false;
21933            }
21934            if (targetUserInfo.isManagedProfile()) {
21935                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21936                return false;
21937            }
21938            mUserController.setTargetUserIdLocked(targetUserId);
21939        }
21940        if (mUserController.mUserSwitchUiEnabled) {
21941            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
21942            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21943            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21944            mUiHandler.sendMessage(mHandler.obtainMessage(
21945                    START_USER_SWITCH_UI_MSG, userNames));
21946        } else {
21947            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
21948            mHandler.sendMessage(mHandler.obtainMessage(
21949                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
21950        }
21951        return true;
21952    }
21953
21954    void scheduleStartProfilesLocked() {
21955        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21956            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21957                    DateUtils.SECOND_IN_MILLIS);
21958        }
21959    }
21960
21961    @Override
21962    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21963        return mUserController.stopUser(userId, force, callback);
21964    }
21965
21966    @Override
21967    public UserInfo getCurrentUser() {
21968        return mUserController.getCurrentUser();
21969    }
21970
21971    String getStartedUserState(int userId) {
21972        synchronized (this) {
21973            final UserState userState = mUserController.getStartedUserStateLocked(userId);
21974            return UserState.stateToString(userState.state);
21975        }
21976    }
21977
21978    @Override
21979    public boolean isUserRunning(int userId, int flags) {
21980        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21981                && checkCallingPermission(INTERACT_ACROSS_USERS)
21982                    != PackageManager.PERMISSION_GRANTED) {
21983            String msg = "Permission Denial: isUserRunning() from pid="
21984                    + Binder.getCallingPid()
21985                    + ", uid=" + Binder.getCallingUid()
21986                    + " requires " + INTERACT_ACROSS_USERS;
21987            Slog.w(TAG, msg);
21988            throw new SecurityException(msg);
21989        }
21990        synchronized (this) {
21991            return mUserController.isUserRunningLocked(userId, flags);
21992        }
21993    }
21994
21995    @Override
21996    public int[] getRunningUserIds() {
21997        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21998                != PackageManager.PERMISSION_GRANTED) {
21999            String msg = "Permission Denial: isUserRunning() from pid="
22000                    + Binder.getCallingPid()
22001                    + ", uid=" + Binder.getCallingUid()
22002                    + " requires " + INTERACT_ACROSS_USERS;
22003            Slog.w(TAG, msg);
22004            throw new SecurityException(msg);
22005        }
22006        synchronized (this) {
22007            return mUserController.getStartedUserArrayLocked();
22008        }
22009    }
22010
22011    @Override
22012    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
22013        mUserController.registerUserSwitchObserver(observer, name);
22014    }
22015
22016    @Override
22017    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
22018        mUserController.unregisterUserSwitchObserver(observer);
22019    }
22020
22021    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
22022        if (info == null) return null;
22023        ApplicationInfo newInfo = new ApplicationInfo(info);
22024        newInfo.initForUser(userId);
22025        return newInfo;
22026    }
22027
22028    public boolean isUserStopped(int userId) {
22029        synchronized (this) {
22030            return mUserController.getStartedUserStateLocked(userId) == null;
22031        }
22032    }
22033
22034    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
22035        if (aInfo == null
22036                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
22037            return aInfo;
22038        }
22039
22040        ActivityInfo info = new ActivityInfo(aInfo);
22041        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
22042        return info;
22043    }
22044
22045    private boolean processSanityChecksLocked(ProcessRecord process) {
22046        if (process == null || process.thread == null) {
22047            return false;
22048        }
22049
22050        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22051        if (!isDebuggable) {
22052            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22053                return false;
22054            }
22055        }
22056
22057        return true;
22058    }
22059
22060    public boolean startBinderTracking() throws RemoteException {
22061        synchronized (this) {
22062            mBinderTransactionTrackingEnabled = true;
22063            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
22064            // permission (same as profileControl).
22065            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22066                    != PackageManager.PERMISSION_GRANTED) {
22067                throw new SecurityException("Requires permission "
22068                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22069            }
22070
22071            for (int i = 0; i < mLruProcesses.size(); i++) {
22072                ProcessRecord process = mLruProcesses.get(i);
22073                if (!processSanityChecksLocked(process)) {
22074                    continue;
22075                }
22076                try {
22077                    process.thread.startBinderTracking();
22078                } catch (RemoteException e) {
22079                    Log.v(TAG, "Process disappared");
22080                }
22081            }
22082            return true;
22083        }
22084    }
22085
22086    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
22087        try {
22088            synchronized (this) {
22089                mBinderTransactionTrackingEnabled = false;
22090                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
22091                // permission (same as profileControl).
22092                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22093                        != PackageManager.PERMISSION_GRANTED) {
22094                    throw new SecurityException("Requires permission "
22095                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22096                }
22097
22098                if (fd == null) {
22099                    throw new IllegalArgumentException("null fd");
22100                }
22101
22102                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
22103                pw.println("Binder transaction traces for all processes.\n");
22104                for (ProcessRecord process : mLruProcesses) {
22105                    if (!processSanityChecksLocked(process)) {
22106                        continue;
22107                    }
22108
22109                    pw.println("Traces for process: " + process.processName);
22110                    pw.flush();
22111                    try {
22112                        TransferPipe tp = new TransferPipe();
22113                        try {
22114                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
22115                            tp.go(fd.getFileDescriptor());
22116                        } finally {
22117                            tp.kill();
22118                        }
22119                    } catch (IOException e) {
22120                        pw.println("Failure while dumping IPC traces from " + process +
22121                                ".  Exception: " + e);
22122                        pw.flush();
22123                    } catch (RemoteException e) {
22124                        pw.println("Got a RemoteException while dumping IPC traces from " +
22125                                process + ".  Exception: " + e);
22126                        pw.flush();
22127                    }
22128                }
22129                fd = null;
22130                return true;
22131            }
22132        } finally {
22133            if (fd != null) {
22134                try {
22135                    fd.close();
22136                } catch (IOException e) {
22137                }
22138            }
22139        }
22140    }
22141
22142    private final class LocalService extends ActivityManagerInternal {
22143        @Override
22144        public String checkContentProviderAccess(String authority, int userId) {
22145            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
22146        }
22147
22148        @Override
22149        public void onWakefulnessChanged(int wakefulness) {
22150            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
22151        }
22152
22153        @Override
22154        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
22155                String processName, String abiOverride, int uid, Runnable crashHandler) {
22156            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
22157                    processName, abiOverride, uid, crashHandler);
22158        }
22159
22160        @Override
22161        public SleepToken acquireSleepToken(String tag) {
22162            Preconditions.checkNotNull(tag);
22163
22164            ComponentName requestedVrService = null;
22165            ComponentName callingVrActivity = null;
22166            int userId = -1;
22167            synchronized (ActivityManagerService.this) {
22168                final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
22169                if (resumedActivity != null) {
22170                    requestedVrService = resumedActivity.requestedVrComponent;
22171                    callingVrActivity = resumedActivity.info.getComponentName();
22172                    userId = resumedActivity.userId;
22173                }
22174            }
22175
22176            if (requestedVrService != null) {
22177                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
22178            }
22179
22180            synchronized (ActivityManagerService.this) {
22181                SleepTokenImpl token = new SleepTokenImpl(tag);
22182                mSleepTokens.add(token);
22183                updateSleepIfNeededLocked();
22184                return token;
22185            }
22186        }
22187
22188        @Override
22189        public ComponentName getHomeActivityForUser(int userId) {
22190            synchronized (ActivityManagerService.this) {
22191                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
22192                return homeActivity == null ? null : homeActivity.realActivity;
22193            }
22194        }
22195
22196        @Override
22197        public void onUserRemoved(int userId) {
22198            synchronized (ActivityManagerService.this) {
22199                ActivityManagerService.this.onUserStoppedLocked(userId);
22200            }
22201        }
22202
22203        @Override
22204        public void onLocalVoiceInteractionStarted(IBinder activity,
22205                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
22206            synchronized (ActivityManagerService.this) {
22207                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
22208                        voiceSession, voiceInteractor);
22209            }
22210        }
22211
22212        @Override
22213        public void notifyStartingWindowDrawn() {
22214            synchronized (ActivityManagerService.this) {
22215                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22216            }
22217        }
22218
22219        @Override
22220        public void notifyAppTransitionStarting(int reason) {
22221            synchronized (ActivityManagerService.this) {
22222                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22223            }
22224        }
22225
22226        @Override
22227        public void notifyAppTransitionFinished() {
22228            synchronized (ActivityManagerService.this) {
22229                mStackSupervisor.notifyAppTransitionDone();
22230            }
22231        }
22232
22233        @Override
22234        public void notifyAppTransitionCancelled() {
22235            synchronized (ActivityManagerService.this) {
22236                mStackSupervisor.notifyAppTransitionDone();
22237            }
22238        }
22239
22240        @Override
22241        public List<IBinder> getTopVisibleActivities() {
22242            synchronized (ActivityManagerService.this) {
22243                return mStackSupervisor.getTopVisibleActivities();
22244            }
22245        }
22246
22247        @Override
22248        public void notifyDockedStackMinimizedChanged(boolean minimized) {
22249            synchronized (ActivityManagerService.this) {
22250                mStackSupervisor.setDockedStackMinimized(minimized);
22251            }
22252        }
22253
22254        @Override
22255        public void killForegroundAppsForUser(int userHandle) {
22256            synchronized (ActivityManagerService.this) {
22257                final ArrayList<ProcessRecord> procs = new ArrayList<>();
22258                final int NP = mProcessNames.getMap().size();
22259                for (int ip = 0; ip < NP; ip++) {
22260                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22261                    final int NA = apps.size();
22262                    for (int ia = 0; ia < NA; ia++) {
22263                        final ProcessRecord app = apps.valueAt(ia);
22264                        if (app.persistent) {
22265                            // We don't kill persistent processes.
22266                            continue;
22267                        }
22268                        if (app.removed) {
22269                            procs.add(app);
22270                        } else if (app.userId == userHandle && app.foregroundActivities) {
22271                            app.removed = true;
22272                            procs.add(app);
22273                        }
22274                    }
22275                }
22276
22277                final int N = procs.size();
22278                for (int i = 0; i < N; i++) {
22279                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
22280                }
22281            }
22282        }
22283
22284        @Override
22285        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22286            if (!(target instanceof PendingIntentRecord)) {
22287                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22288                return;
22289            }
22290            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22291        }
22292
22293        @Override
22294        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22295                int userId) {
22296            Preconditions.checkNotNull(values, "Configuration must not be null");
22297            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22298            synchronized (ActivityManagerService.this) {
22299                updateConfigurationLocked(values, null, false, true, userId,
22300                        false /* deferResume */);
22301            }
22302        }
22303
22304        @Override
22305        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22306                Bundle bOptions) {
22307            Preconditions.checkNotNull(intents, "intents");
22308            final String[] resolvedTypes = new String[intents.length];
22309            for (int i = 0; i < intents.length; i++) {
22310                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22311            }
22312
22313            // UID of the package on user userId.
22314            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22315            // packageUid may not be initialized.
22316            int packageUid = 0;
22317            try {
22318                packageUid = AppGlobals.getPackageManager().getPackageUid(
22319                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22320            } catch (RemoteException e) {
22321                // Shouldn't happen.
22322            }
22323
22324            synchronized (ActivityManagerService.this) {
22325                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22326                        /*resultTo*/ null, bOptions, userId);
22327            }
22328        }
22329
22330        @Override
22331        public int getUidProcessState(int uid) {
22332            return getUidState(uid);
22333        }
22334
22335        @Override
22336        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
22337            synchronized (ActivityManagerService.this) {
22338
22339                // We might change the visibilities here, so prepare an empty app transition which
22340                // might be overridden later if we actually change visibilities.
22341                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
22342                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
22343                mWindowManager.executeAppTransition();
22344            }
22345            if (callback != null) {
22346                callback.run();
22347            }
22348        }
22349
22350        @Override
22351        public boolean isSystemReady() {
22352            // no need to synchronize(this) just to read & return the value
22353            return mSystemReady;
22354        }
22355
22356        @Override
22357        public void notifyKeyguardTrustedChanged() {
22358            synchronized (ActivityManagerService.this) {
22359                if (mKeyguardController.isKeyguardShowing()) {
22360                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
22361                }
22362            }
22363        }
22364    }
22365
22366    private final class SleepTokenImpl extends SleepToken {
22367        private final String mTag;
22368        private final long mAcquireTime;
22369
22370        public SleepTokenImpl(String tag) {
22371            mTag = tag;
22372            mAcquireTime = SystemClock.uptimeMillis();
22373        }
22374
22375        @Override
22376        public void release() {
22377            synchronized (ActivityManagerService.this) {
22378                if (mSleepTokens.remove(this)) {
22379                    updateSleepIfNeededLocked();
22380                }
22381            }
22382        }
22383
22384        @Override
22385        public String toString() {
22386            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22387        }
22388    }
22389
22390    /**
22391     * An implementation of IAppTask, that allows an app to manage its own tasks via
22392     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22393     * only the process that calls getAppTasks() can call the AppTask methods.
22394     */
22395    class AppTaskImpl extends IAppTask.Stub {
22396        private int mTaskId;
22397        private int mCallingUid;
22398
22399        public AppTaskImpl(int taskId, int callingUid) {
22400            mTaskId = taskId;
22401            mCallingUid = callingUid;
22402        }
22403
22404        private void checkCaller() {
22405            if (mCallingUid != Binder.getCallingUid()) {
22406                throw new SecurityException("Caller " + mCallingUid
22407                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22408            }
22409        }
22410
22411        @Override
22412        public void finishAndRemoveTask() {
22413            checkCaller();
22414
22415            synchronized (ActivityManagerService.this) {
22416                long origId = Binder.clearCallingIdentity();
22417                try {
22418                    // We remove the task from recents to preserve backwards
22419                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22420                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22421                    }
22422                } finally {
22423                    Binder.restoreCallingIdentity(origId);
22424                }
22425            }
22426        }
22427
22428        @Override
22429        public ActivityManager.RecentTaskInfo getTaskInfo() {
22430            checkCaller();
22431
22432            synchronized (ActivityManagerService.this) {
22433                long origId = Binder.clearCallingIdentity();
22434                try {
22435                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22436                    if (tr == null) {
22437                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22438                    }
22439                    return createRecentTaskInfoFromTaskRecord(tr);
22440                } finally {
22441                    Binder.restoreCallingIdentity(origId);
22442                }
22443            }
22444        }
22445
22446        @Override
22447        public void moveToFront() {
22448            checkCaller();
22449            // Will bring task to front if it already has a root activity.
22450            final long origId = Binder.clearCallingIdentity();
22451            try {
22452                synchronized (this) {
22453                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22454                }
22455            } finally {
22456                Binder.restoreCallingIdentity(origId);
22457            }
22458        }
22459
22460        @Override
22461        public int startActivity(IBinder whoThread, String callingPackage,
22462                Intent intent, String resolvedType, Bundle bOptions) {
22463            checkCaller();
22464
22465            int callingUser = UserHandle.getCallingUserId();
22466            TaskRecord tr;
22467            IApplicationThread appThread;
22468            synchronized (ActivityManagerService.this) {
22469                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22470                if (tr == null) {
22471                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22472                }
22473                appThread = IApplicationThread.Stub.asInterface(whoThread);
22474                if (appThread == null) {
22475                    throw new IllegalArgumentException("Bad app thread " + appThread);
22476                }
22477            }
22478            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22479                    resolvedType, null, null, null, null, 0, 0, null, null,
22480                    null, bOptions, false, callingUser, null, tr);
22481        }
22482
22483        @Override
22484        public void setExcludeFromRecents(boolean exclude) {
22485            checkCaller();
22486
22487            synchronized (ActivityManagerService.this) {
22488                long origId = Binder.clearCallingIdentity();
22489                try {
22490                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22491                    if (tr == null) {
22492                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22493                    }
22494                    Intent intent = tr.getBaseIntent();
22495                    if (exclude) {
22496                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22497                    } else {
22498                        intent.setFlags(intent.getFlags()
22499                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22500                    }
22501                } finally {
22502                    Binder.restoreCallingIdentity(origId);
22503                }
22504            }
22505        }
22506    }
22507
22508    /**
22509     * Kill processes for the user with id userId and that depend on the package named packageName
22510     */
22511    @Override
22512    public void killPackageDependents(String packageName, int userId) {
22513        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22514        if (packageName == null) {
22515            throw new NullPointerException(
22516                    "Cannot kill the dependents of a package without its name.");
22517        }
22518
22519        long callingId = Binder.clearCallingIdentity();
22520        IPackageManager pm = AppGlobals.getPackageManager();
22521        int pkgUid = -1;
22522        try {
22523            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22524        } catch (RemoteException e) {
22525        }
22526        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22527            throw new IllegalArgumentException(
22528                    "Cannot kill dependents of non-existing package " + packageName);
22529        }
22530        try {
22531            synchronized(this) {
22532                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22533                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22534                        "dep: " + packageName);
22535            }
22536        } finally {
22537            Binder.restoreCallingIdentity(callingId);
22538        }
22539    }
22540
22541    @Override
22542    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22543        final int userId = intent.getCreatorUserHandle().getIdentifier();
22544        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22545            return false;
22546        }
22547        IIntentSender target = intent.getTarget();
22548        if (!(target instanceof PendingIntentRecord)) {
22549            return false;
22550        }
22551        final PendingIntentRecord record = (PendingIntentRecord) target;
22552        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22553                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22554        // For direct boot aware activities, they can be shown without triggering a work challenge
22555        // before the profile user is unlocked.
22556        return rInfo != null && rInfo.activityInfo != null;
22557    }
22558
22559    @Override
22560    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
22561            throws RemoteException {
22562        final long callingId = Binder.clearCallingIdentity();
22563        try {
22564            mKeyguardController.dismissKeyguard(token, callback);
22565        } finally {
22566            Binder.restoreCallingIdentity(callingId);
22567        }
22568    }
22569
22570    /**
22571     * Attach an agent to the specified process (proces name or PID)
22572     */
22573    public void attachAgent(String process, String path) {
22574        try {
22575            synchronized (this) {
22576                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
22577                if (proc == null || proc.thread == null) {
22578                    throw new IllegalArgumentException("Unknown process: " + process);
22579                }
22580
22581                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22582                if (!isDebuggable) {
22583                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22584                        throw new SecurityException("Process not debuggable: " + proc);
22585                    }
22586                }
22587
22588                proc.thread.attachAgent(path);
22589            }
22590        } catch (RemoteException e) {
22591            throw new IllegalStateException("Process disappeared");
22592        }
22593    }
22594}
22595