ActivityManagerService.java revision 4b34000a21e5d3e3eb75c69e9d2e511a814aff13
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 static android.Manifest.permission.CHANGE_CONFIGURATION;
20import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21import static android.Manifest.permission.INTERACT_ACROSS_USERS;
22import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
23import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
24import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
25import static android.Manifest.permission.READ_FRAME_BUFFER;
26import static android.Manifest.permission.REMOVE_TASKS;
27import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
28import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
29import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
30import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
31import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
32import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
33import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
34import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
35import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
36import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
37import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
38import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
39import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
40import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
41import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
42import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
43import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
44import static android.content.pm.PackageManager.GET_PROVIDERS;
45import static android.content.pm.PackageManager.MATCH_ANY_USER;
46import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
47import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
48import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
49import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
50import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
51import static android.content.pm.PackageManager.PERMISSION_GRANTED;
52import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
53import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
54import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
55import static android.os.Build.VERSION_CODES.N;
56import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
57import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
58import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
59import static android.os.IServiceManager.DUMP_FLAG_PROTO;
60import static android.os.Process.BLUETOOTH_UID;
61import static android.os.Process.FIRST_APPLICATION_UID;
62import static android.os.Process.FIRST_ISOLATED_UID;
63import static android.os.Process.LAST_ISOLATED_UID;
64import static android.os.Process.NFC_UID;
65import static android.os.Process.PHONE_UID;
66import static android.os.Process.PROC_CHAR;
67import static android.os.Process.PROC_OUT_LONG;
68import static android.os.Process.PROC_PARENS;
69import static android.os.Process.PROC_SPACE_TERM;
70import static android.os.Process.ProcessStartResult;
71import static android.os.Process.ROOT_UID;
72import static android.os.Process.SCHED_FIFO;
73import static android.os.Process.SCHED_OTHER;
74import static android.os.Process.SCHED_RESET_ON_FORK;
75import static android.os.Process.SHELL_UID;
76import static android.os.Process.SIGNAL_QUIT;
77import static android.os.Process.SIGNAL_USR1;
78import static android.os.Process.SYSTEM_UID;
79import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
80import static android.os.Process.THREAD_GROUP_DEFAULT;
81import static android.os.Process.THREAD_GROUP_TOP_APP;
82import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
83import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
84import static android.os.Process.getFreeMemory;
85import static android.os.Process.getTotalMemory;
86import static android.os.Process.isThreadInProcess;
87import static android.os.Process.killProcess;
88import static android.os.Process.killProcessQuiet;
89import static android.os.Process.myPid;
90import static android.os.Process.myUid;
91import static android.os.Process.readProcFile;
92import static android.os.Process.removeAllProcessGroups;
93import static android.os.Process.sendSignal;
94import static android.os.Process.setProcessGroup;
95import static android.os.Process.setThreadPriority;
96import static android.os.Process.setThreadScheduler;
97import static android.os.Process.startWebView;
98import static android.os.Process.zygoteProcess;
99import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
100import static android.provider.Settings.Global.DEBUG_APP;
101import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
102import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
103import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
104import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
105import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
106import static android.provider.Settings.System.FONT_SCALE;
107import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
108import static android.text.format.DateUtils.DAY_IN_MILLIS;
109import static android.view.Display.DEFAULT_DISPLAY;
110import static android.view.Display.INVALID_DISPLAY;
111import static com.android.internal.util.XmlUtils.readBooleanAttribute;
112import static com.android.internal.util.XmlUtils.readIntAttribute;
113import static com.android.internal.util.XmlUtils.readLongAttribute;
114import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
115import static com.android.internal.util.XmlUtils.writeIntAttribute;
116import static com.android.internal.util.XmlUtils.writeLongAttribute;
117import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
118import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
119import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
120import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
121import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
122import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
123import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
124import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
125import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
126import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
127import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
128import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
141import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
142import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
143import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
144import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
145import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
146import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
147import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
148import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
149import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
150import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
151import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
152import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
153import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
154import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
155import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
156import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
157import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
158import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
159import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
160import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
161import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
162import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
163import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
164import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
165import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
166import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
167import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
168import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
169import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
170import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
171import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
172import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
173import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
174import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
175import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
176import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
177import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
178import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
179import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
180import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
181import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
182import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
183import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
184import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
185import static com.android.server.wm.AppTransition.TRANSIT_NONE;
186import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
187import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
188import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
189import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
190import static org.xmlpull.v1.XmlPullParser.START_TAG;
191
192import android.Manifest;
193import android.Manifest.permission;
194import android.annotation.NonNull;
195import android.annotation.Nullable;
196import android.annotation.UserIdInt;
197import android.app.Activity;
198import android.app.ActivityManager;
199import android.app.ActivityManager.RunningTaskInfo;
200import android.app.ActivityManager.StackInfo;
201import android.app.ActivityManager.TaskSnapshot;
202import android.app.ActivityManagerInternal;
203import android.app.ActivityManagerInternal.SleepToken;
204import android.app.ActivityOptions;
205import android.app.ActivityThread;
206import android.app.AlertDialog;
207import android.app.AppGlobals;
208import android.app.AppOpsManager;
209import android.app.ApplicationErrorReport;
210import android.app.ApplicationThreadConstants;
211import android.app.BroadcastOptions;
212import android.app.ContentProviderHolder;
213import android.app.Dialog;
214import android.app.IActivityController;
215import android.app.IActivityManager;
216import android.app.IApplicationThread;
217import android.app.IInstrumentationWatcher;
218import android.app.INotificationManager;
219import android.app.IProcessObserver;
220import android.app.IServiceConnection;
221import android.app.IStopUserCallback;
222import android.app.ITaskStackListener;
223import android.app.IUiAutomationConnection;
224import android.app.IUidObserver;
225import android.app.IUserSwitchObserver;
226import android.app.Instrumentation;
227import android.app.Notification;
228import android.app.NotificationManager;
229import android.app.PendingIntent;
230import android.app.PictureInPictureParams;
231import android.app.ProfilerInfo;
232import android.app.RemoteAction;
233import android.app.WaitResult;
234import android.app.WindowConfiguration.ActivityType;
235import android.app.WindowConfiguration.WindowingMode;
236import android.app.admin.DevicePolicyManager;
237import android.app.assist.AssistContent;
238import android.app.assist.AssistStructure;
239import android.app.backup.IBackupManager;
240import android.app.usage.UsageEvents;
241import android.app.usage.UsageStatsManagerInternal;
242import android.appwidget.AppWidgetManager;
243import android.content.ActivityNotFoundException;
244import android.content.BroadcastReceiver;
245import android.content.ClipData;
246import android.content.ComponentCallbacks2;
247import android.content.ComponentName;
248import android.content.ContentProvider;
249import android.content.ContentResolver;
250import android.content.Context;
251import android.content.DialogInterface;
252import android.content.IContentProvider;
253import android.content.IIntentReceiver;
254import android.content.IIntentSender;
255import android.content.Intent;
256import android.content.IntentFilter;
257import android.content.pm.ActivityInfo;
258import android.content.pm.ApplicationInfo;
259import android.content.pm.ConfigurationInfo;
260import android.content.pm.IPackageDataObserver;
261import android.content.pm.IPackageManager;
262import android.content.pm.InstrumentationInfo;
263import android.content.pm.PackageInfo;
264import android.content.pm.PackageManager;
265import android.content.pm.PackageManagerInternal;
266import android.content.pm.PackageManager.NameNotFoundException;
267import android.content.pm.ParceledListSlice;
268import android.content.pm.PathPermission;
269import android.content.pm.PermissionInfo;
270import android.content.pm.ProviderInfo;
271import android.content.pm.ResolveInfo;
272import android.content.pm.SELinuxUtil;
273import android.content.pm.ServiceInfo;
274import android.content.pm.UserInfo;
275import android.content.res.CompatibilityInfo;
276import android.content.res.Configuration;
277import android.content.res.Resources;
278import android.database.ContentObserver;
279import android.graphics.Bitmap;
280import android.graphics.Point;
281import android.graphics.Rect;
282import android.location.LocationManager;
283import android.media.audiofx.AudioEffect;
284import android.metrics.LogMaker;
285import android.net.Proxy;
286import android.net.ProxyInfo;
287import android.net.Uri;
288import android.os.BatteryStats;
289import android.os.Binder;
290import android.os.Build;
291import android.os.Bundle;
292import android.os.Debug;
293import android.os.DropBoxManager;
294import android.os.Environment;
295import android.os.FactoryTest;
296import android.os.FileObserver;
297import android.os.FileUtils;
298import android.os.Handler;
299import android.os.IBinder;
300import android.os.IDeviceIdentifiersPolicyService;
301import android.os.IPermissionController;
302import android.os.IProcessInfoService;
303import android.os.IProgressListener;
304import android.os.LocaleList;
305import android.os.Looper;
306import android.os.Message;
307import android.os.Parcel;
308import android.os.ParcelFileDescriptor;
309import android.os.PersistableBundle;
310import android.os.PowerManager;
311import android.os.PowerManagerInternal;
312import android.os.Process;
313import android.os.RemoteCallbackList;
314import android.os.RemoteException;
315import android.os.ResultReceiver;
316import android.os.ServiceManager;
317import android.os.ShellCallback;
318import android.os.StrictMode;
319import android.os.SystemClock;
320import android.os.SystemProperties;
321import android.os.Trace;
322import android.os.TransactionTooLargeException;
323import android.os.UpdateLock;
324import android.os.UserHandle;
325import android.os.UserManager;
326import android.os.WorkSource;
327import android.os.storage.IStorageManager;
328import android.os.storage.StorageManager;
329import android.os.storage.StorageManagerInternal;
330import android.provider.Downloads;
331import android.provider.Settings;
332import android.service.voice.IVoiceInteractionSession;
333import android.service.voice.VoiceInteractionManagerInternal;
334import android.service.voice.VoiceInteractionSession;
335import android.telecom.TelecomManager;
336import android.text.TextUtils;
337import android.text.format.DateUtils;
338import android.text.format.Time;
339import android.text.style.SuggestionSpan;
340import android.util.ArrayMap;
341import android.util.ArraySet;
342import android.util.AtomicFile;
343import android.util.StatsLog;
344import android.util.TimingsTraceLog;
345import android.util.DebugUtils;
346import android.util.DisplayMetrics;
347import android.util.EventLog;
348import android.util.Log;
349import android.util.Pair;
350import android.util.PrintWriterPrinter;
351import android.util.Slog;
352import android.util.SparseArray;
353import android.util.SparseIntArray;
354import android.util.TimeUtils;
355import android.util.Xml;
356import android.util.proto.ProtoOutputStream;
357import android.view.Gravity;
358import android.view.LayoutInflater;
359import android.view.View;
360import android.view.WindowManager;
361
362import com.android.internal.R;
363import com.android.internal.annotations.GuardedBy;
364import com.android.internal.annotations.VisibleForTesting;
365import com.android.internal.app.AssistUtils;
366import com.android.internal.app.DumpHeapActivity;
367import com.android.internal.app.IAppOpsCallback;
368import com.android.internal.app.IAppOpsService;
369import com.android.internal.app.IVoiceInteractor;
370import com.android.internal.app.ProcessMap;
371import com.android.internal.app.SystemUserHomeActivity;
372import com.android.internal.app.procstats.ProcessStats;
373import com.android.internal.logging.MetricsLogger;
374import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
375import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
376import com.android.internal.notification.SystemNotificationChannels;
377import com.android.internal.os.BackgroundThread;
378import com.android.internal.os.BatteryStatsImpl;
379import com.android.internal.os.BinderInternal;
380import com.android.internal.os.IResultReceiver;
381import com.android.internal.os.ProcessCpuTracker;
382import com.android.internal.os.TransferPipe;
383import com.android.internal.os.Zygote;
384import com.android.internal.policy.IKeyguardDismissCallback;
385import com.android.internal.telephony.TelephonyIntents;
386import com.android.internal.util.ArrayUtils;
387import com.android.internal.util.DumpUtils;
388import com.android.internal.util.FastPrintWriter;
389import com.android.internal.util.FastXmlSerializer;
390import com.android.internal.util.MemInfoReader;
391import com.android.internal.util.Preconditions;
392import com.android.server.AppOpsService;
393import com.android.server.AttributeCache;
394import com.android.server.DeviceIdleController;
395import com.android.server.IntentResolver;
396import com.android.server.LocalServices;
397import com.android.server.LockGuard;
398import com.android.server.NetworkManagementInternal;
399import com.android.server.RescueParty;
400import com.android.server.ServiceThread;
401import com.android.server.SystemConfig;
402import com.android.server.SystemService;
403import com.android.server.SystemServiceManager;
404import com.android.server.ThreadPriorityBooster;
405import com.android.server.Watchdog;
406import com.android.server.am.ActivityStack.ActivityState;
407import com.android.server.am.proto.ActivityManagerServiceProto;
408import com.android.server.am.proto.BroadcastProto;
409import com.android.server.am.proto.StickyBroadcastProto;
410import com.android.server.firewall.IntentFirewall;
411import com.android.server.job.JobSchedulerInternal;
412import com.android.server.pm.Installer;
413import com.android.server.pm.Installer.InstallerException;
414import com.android.server.utils.PriorityDump;
415import com.android.server.vr.VrManagerInternal;
416import com.android.server.wm.PinnedStackWindowController;
417import com.android.server.wm.WindowManagerService;
418import com.google.android.collect.Lists;
419import com.google.android.collect.Maps;
420
421import org.xmlpull.v1.XmlPullParser;
422import org.xmlpull.v1.XmlPullParserException;
423import org.xmlpull.v1.XmlSerializer;
424
425import java.io.File;
426import java.io.FileDescriptor;
427import java.io.FileInputStream;
428import java.io.FileNotFoundException;
429import java.io.FileOutputStream;
430import java.io.IOException;
431import java.io.InputStreamReader;
432import java.io.PrintWriter;
433import java.io.StringWriter;
434import java.io.UnsupportedEncodingException;
435import java.lang.ref.WeakReference;
436import java.nio.charset.StandardCharsets;
437import java.text.DateFormat;
438import java.text.SimpleDateFormat;
439import java.util.ArrayList;
440import java.util.Arrays;
441import java.util.Collections;
442import java.util.Comparator;
443import java.util.Date;
444import java.util.HashMap;
445import java.util.HashSet;
446import java.util.Iterator;
447import java.util.List;
448import java.util.Locale;
449import java.util.Map;
450import java.util.Objects;
451import java.util.Set;
452import java.util.concurrent.CountDownLatch;
453import java.util.concurrent.atomic.AtomicBoolean;
454import java.util.concurrent.atomic.AtomicLong;
455
456import dalvik.system.VMRuntime;
457import libcore.io.IoUtils;
458import libcore.util.EmptyArray;
459
460public class ActivityManagerService extends IActivityManager.Stub
461        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
462
463    /**
464     * Priority we boost main thread and RT of top app to.
465     */
466    public static final int TOP_APP_PRIORITY_BOOST = -10;
467
468    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
469    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
470    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
471    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
472    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
473    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
474    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
475    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
476    private static final String TAG_LRU = TAG + POSTFIX_LRU;
477    private static final String TAG_MU = TAG + POSTFIX_MU;
478    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
479    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
480    private static final String TAG_POWER = TAG + POSTFIX_POWER;
481    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
482    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
483    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
484    private static final String TAG_PSS = TAG + POSTFIX_PSS;
485    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
486    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
487    private static final String TAG_STACK = TAG + POSTFIX_STACK;
488    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
489    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
490    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
491    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
492
493    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
494    // here so that while the job scheduler can depend on AMS, the other way around
495    // need not be the case.
496    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
497
498    /** Control over CPU and battery monitoring */
499    // write battery stats every 30 minutes.
500    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
501    static final boolean MONITOR_CPU_USAGE = true;
502    // don't sample cpu less than every 5 seconds.
503    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
504    // wait possibly forever for next cpu sample.
505    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
506    static final boolean MONITOR_THREAD_CPU_USAGE = false;
507
508    // The flags that are set for all calls we make to the package manager.
509    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
510
511    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
512
513    // Amount of time after a call to stopAppSwitches() during which we will
514    // prevent further untrusted switches from happening.
515    static final long APP_SWITCH_DELAY_TIME = 5*1000;
516
517    // How long we wait for a launched process to attach to the activity manager
518    // before we decide it's never going to come up for real.
519    static final int PROC_START_TIMEOUT = 10*1000;
520    // How long we wait for an attached process to publish its content providers
521    // before we decide it must be hung.
522    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
523
524    // How long we wait for a launched process to attach to the activity manager
525    // before we decide it's never going to come up for real, when the process was
526    // started with a wrapper for instrumentation (such as Valgrind) because it
527    // could take much longer than usual.
528    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
529
530    // How long we allow a receiver to run before giving up on it.
531    static final int BROADCAST_FG_TIMEOUT = 10*1000;
532    static final int BROADCAST_BG_TIMEOUT = 60*1000;
533
534    // How long we wait until we timeout on key dispatching.
535    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
536
537    // How long we wait until we timeout on key dispatching during instrumentation.
538    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
539
540    // How long to wait in getAssistContextExtras for the activity and foreground services
541    // to respond with the result.
542    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
543
544    // How long top wait when going through the modern assist (which doesn't need to block
545    // on getting this result before starting to launch its UI).
546    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
547
548    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
549    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
550
551    // Maximum number of persisted Uri grants a package is allowed
552    static final int MAX_PERSISTED_URI_GRANTS = 128;
553
554    static final int MY_PID = myPid();
555
556    static final String[] EMPTY_STRING_ARRAY = new String[0];
557
558    // How many bytes to write into the dropbox log before truncating
559    static final int DROPBOX_MAX_SIZE = 192 * 1024;
560    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
561    // as one line, but close enough for now.
562    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
563
564    // Access modes for handleIncomingUser.
565    static final int ALLOW_NON_FULL = 0;
566    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
567    static final int ALLOW_FULL_ONLY = 2;
568
569    // Necessary ApplicationInfo flags to mark an app as persistent
570    private static final int PERSISTENT_MASK =
571            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
572
573    // Intent sent when remote bugreport collection has been completed
574    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
575            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
576
577    // Used to indicate that an app transition should be animated.
578    static final boolean ANIMATE = true;
579
580    // Determines whether to take full screen screenshots
581    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
582
583    /**
584     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
585     */
586    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
587
588    /**
589     * State indicating that there is no need for any blocking for network.
590     */
591    @VisibleForTesting
592    static final int NETWORK_STATE_NO_CHANGE = 0;
593
594    /**
595     * State indicating that the main thread needs to be informed about the network wait.
596     */
597    @VisibleForTesting
598    static final int NETWORK_STATE_BLOCK = 1;
599
600    /**
601     * State indicating that any threads waiting for network state to get updated can be unblocked.
602     */
603    @VisibleForTesting
604    static final int NETWORK_STATE_UNBLOCK = 2;
605
606    // Max character limit for a notification title. If the notification title is larger than this
607    // the notification will not be legible to the user.
608    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
609
610    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
611
612    /** All system services */
613    SystemServiceManager mSystemServiceManager;
614    AssistUtils mAssistUtils;
615
616    private Installer mInstaller;
617
618    /** Run all ActivityStacks through this */
619    final ActivityStackSupervisor mStackSupervisor;
620    private final KeyguardController mKeyguardController;
621
622    final ActivityStarter mActivityStarter;
623
624    final TaskChangeNotificationController mTaskChangeNotificationController;
625
626    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
627
628    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
629
630    public final IntentFirewall mIntentFirewall;
631
632    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
633    // default action automatically.  Important for devices without direct input
634    // devices.
635    private boolean mShowDialogs = true;
636
637    private final VrController mVrController;
638
639    // VR Vr2d Display Id.
640    int mVr2dDisplayId = INVALID_DISPLAY;
641
642    // Whether we should use SCHED_FIFO for UI and RenderThreads.
643    private boolean mUseFifoUiScheduling = false;
644
645    BroadcastQueue mFgBroadcastQueue;
646    BroadcastQueue mBgBroadcastQueue;
647    // Convenient for easy iteration over the queues. Foreground is first
648    // so that dispatch of foreground broadcasts gets precedence.
649    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
650
651    BroadcastStats mLastBroadcastStats;
652    BroadcastStats mCurBroadcastStats;
653
654    BroadcastQueue broadcastQueueForIntent(Intent intent) {
655        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
656        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
657                "Broadcast intent " + intent + " on "
658                + (isFg ? "foreground" : "background") + " queue");
659        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
660    }
661
662    /**
663     * The last resumed activity. This is identical to the current resumed activity most
664     * of the time but could be different when we're pausing one activity before we resume
665     * another activity.
666     */
667    private ActivityRecord mLastResumedActivity;
668
669    /**
670     * If non-null, we are tracking the time the user spends in the currently focused app.
671     */
672    private AppTimeTracker mCurAppTimeTracker;
673
674    /**
675     * List of intents that were used to start the most recent tasks.
676     */
677    private final RecentTasks mRecentTasks;
678
679    /**
680     * For addAppTask: cached of the last activity component that was added.
681     */
682    ComponentName mLastAddedTaskComponent;
683
684    /**
685     * For addAppTask: cached of the last activity uid that was added.
686     */
687    int mLastAddedTaskUid;
688
689    /**
690     * For addAppTask: cached of the last ActivityInfo that was added.
691     */
692    ActivityInfo mLastAddedTaskActivity;
693
694    /**
695     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
696     */
697    String mDeviceOwnerName;
698
699    /**
700     * The controller for all operations related to locktask.
701     */
702    final LockTaskController mLockTaskController;
703
704    final UserController mUserController;
705
706    final AppErrors mAppErrors;
707
708    /**
709     * Dump of the activity state at the time of the last ANR. Cleared after
710     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
711     */
712    String mLastANRState;
713
714    /**
715     * Indicates the maximum time spent waiting for the network rules to get updated.
716     */
717    @VisibleForTesting
718    long mWaitForNetworkTimeoutMs;
719
720    /**
721     * Helper class which parses out priority arguments and dumps sections according to their
722     * priority. If priority arguments are omitted, function calls the legacy dump command.
723     */
724    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
725        @Override
726        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
727                boolean asProto) {
728            if (asProto) return;
729            doDump(fd, pw, new String[]{"activities"}, asProto);
730        }
731
732        @Override
733        public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
734            if (asProto) {
735                doDump(fd, pw, new String[0], asProto);
736            } else {
737                doDump(fd, pw, new String[]{"settings"}, asProto);
738                doDump(fd, pw, new String[]{"intents"}, asProto);
739                doDump(fd, pw, new String[]{"broadcasts"}, asProto);
740                doDump(fd, pw, new String[]{"providers"}, asProto);
741                doDump(fd, pw, new String[]{"permissions"}, asProto);
742                doDump(fd, pw, new String[]{"services"}, asProto);
743                doDump(fd, pw, new String[]{"recents"}, asProto);
744                doDump(fd, pw, new String[]{"lastanr"}, asProto);
745                doDump(fd, pw, new String[]{"starter"}, asProto);
746                if (mAssociations.size() > 0) {
747                    doDump(fd, pw, new String[]{"associations"}, asProto);
748                }
749                doDump(fd, pw, new String[]{"processes"}, asProto);
750            }
751        }
752
753        @Override
754        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
755            doDump(fd, pw, args, asProto);
756        }
757    };
758
759    public boolean canShowErrorDialogs() {
760        return mShowDialogs && !mSleeping && !mShuttingDown
761                && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
762                && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
763                        mUserController.getCurrentUserId())
764                && !(UserManager.isDeviceInDemoMode(mContext)
765                        && mUserController.getCurrentUser().isDemo());
766    }
767
768    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
769            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
770
771    static void boostPriorityForLockedSection() {
772        sThreadPriorityBooster.boost();
773    }
774
775    static void resetPriorityAfterLockedSection() {
776        sThreadPriorityBooster.reset();
777    }
778
779    public class PendingAssistExtras extends Binder implements Runnable {
780        public final ActivityRecord activity;
781        public boolean isHome;
782        public final Bundle extras;
783        public final Intent intent;
784        public final String hint;
785        public final IResultReceiver receiver;
786        public final int userHandle;
787        public boolean haveResult = false;
788        public Bundle result = null;
789        public AssistStructure structure = null;
790        public AssistContent content = null;
791        public Bundle receiverExtras;
792
793        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
794                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
795            activity = _activity;
796            extras = _extras;
797            intent = _intent;
798            hint = _hint;
799            receiver = _receiver;
800            receiverExtras = _receiverExtras;
801            userHandle = _userHandle;
802        }
803
804        @Override
805        public void run() {
806            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
807            synchronized (this) {
808                haveResult = true;
809                notifyAll();
810            }
811            pendingAssistExtrasTimedOut(this);
812        }
813    }
814
815    final ArrayList<PendingAssistExtras> mPendingAssistExtras
816            = new ArrayList<PendingAssistExtras>();
817
818    /**
819     * Process management.
820     */
821    final ProcessList mProcessList = new ProcessList();
822
823    /**
824     * All of the applications we currently have running organized by name.
825     * The keys are strings of the application package name (as
826     * returned by the package manager), and the keys are ApplicationRecord
827     * objects.
828     */
829    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
830
831    /**
832     * Tracking long-term execution of processes to look for abuse and other
833     * bad app behavior.
834     */
835    final ProcessStatsService mProcessStats;
836
837    /**
838     * The currently running isolated processes.
839     */
840    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
841
842    /**
843     * Counter for assigning isolated process uids, to avoid frequently reusing the
844     * same ones.
845     */
846    int mNextIsolatedProcessUid = 0;
847
848    /**
849     * The currently running heavy-weight process, if any.
850     */
851    ProcessRecord mHeavyWeightProcess = null;
852
853    /**
854     * Non-persistent appId whitelist for background restrictions
855     */
856    int[] mBackgroundAppIdWhitelist = new int[] {
857            BLUETOOTH_UID
858    };
859
860    /**
861     * Broadcast actions that will always be deliverable to unlaunched/background apps
862     */
863    ArraySet<String> mBackgroundLaunchBroadcasts;
864
865    /**
866     * All of the processes we currently have running organized by pid.
867     * The keys are the pid running the application.
868     *
869     * <p>NOTE: This object is protected by its own lock, NOT the global
870     * activity manager lock!
871     */
872    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
873
874    /**
875     * All of the processes that have been forced to be important.  The key
876     * is the pid of the caller who requested it (we hold a death
877     * link on it).
878     */
879    abstract class ImportanceToken implements IBinder.DeathRecipient {
880        final int pid;
881        final IBinder token;
882        final String reason;
883
884        ImportanceToken(int _pid, IBinder _token, String _reason) {
885            pid = _pid;
886            token = _token;
887            reason = _reason;
888        }
889
890        @Override
891        public String toString() {
892            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
893                    + " " + reason + " " + pid + " " + token + " }";
894        }
895    }
896    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
897
898    /**
899     * List of records for processes that someone had tried to start before the
900     * system was ready.  We don't start them at that point, but ensure they
901     * are started by the time booting is complete.
902     */
903    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
904
905    /**
906     * List of persistent applications that are in the process
907     * of being started.
908     */
909    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
910
911    /**
912     * Processes that are being forcibly torn down.
913     */
914    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
915
916    /**
917     * List of running applications, sorted by recent usage.
918     * The first entry in the list is the least recently used.
919     */
920    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
921
922    /**
923     * Where in mLruProcesses that the processes hosting activities start.
924     */
925    int mLruProcessActivityStart = 0;
926
927    /**
928     * Where in mLruProcesses that the processes hosting services start.
929     * This is after (lower index) than mLruProcessesActivityStart.
930     */
931    int mLruProcessServiceStart = 0;
932
933    /**
934     * List of processes that should gc as soon as things are idle.
935     */
936    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
937
938    /**
939     * Processes we want to collect PSS data from.
940     */
941    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
942
943    private boolean mBinderTransactionTrackingEnabled = false;
944
945    /**
946     * Last time we requested PSS data of all processes.
947     */
948    long mLastFullPssTime = SystemClock.uptimeMillis();
949
950    /**
951     * If set, the next time we collect PSS data we should do a full collection
952     * with data from native processes and the kernel.
953     */
954    boolean mFullPssPending = false;
955
956    /**
957     * This is the process holding what we currently consider to be
958     * the "home" activity.
959     */
960    ProcessRecord mHomeProcess;
961
962    /**
963     * This is the process holding the activity the user last visited that
964     * is in a different process from the one they are currently in.
965     */
966    ProcessRecord mPreviousProcess;
967
968    /**
969     * The time at which the previous process was last visible.
970     */
971    long mPreviousProcessVisibleTime;
972
973    /**
974     * Track all uids that have actively running processes.
975     */
976    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
977
978    /**
979     * This is for verifying the UID report flow.
980     */
981    static final boolean VALIDATE_UID_STATES = true;
982    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
983
984    /**
985     * Packages that the user has asked to have run in screen size
986     * compatibility mode instead of filling the screen.
987     */
988    final CompatModePackages mCompatModePackages;
989
990    /**
991     * Set of IntentSenderRecord objects that are currently active.
992     */
993    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
994            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
995
996    /**
997     * Fingerprints (hashCode()) of stack traces that we've
998     * already logged DropBox entries for.  Guarded by itself.  If
999     * something (rogue user app) forces this over
1000     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1001     */
1002    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1003    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1004
1005    /**
1006     * Strict Mode background batched logging state.
1007     *
1008     * The string buffer is guarded by itself, and its lock is also
1009     * used to determine if another batched write is already
1010     * in-flight.
1011     */
1012    private final StringBuilder mStrictModeBuffer = new StringBuilder();
1013
1014    /**
1015     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1016     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1017     */
1018    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1019
1020    /**
1021     * Resolver for broadcast intents to registered receivers.
1022     * Holds BroadcastFilter (subclass of IntentFilter).
1023     */
1024    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1025            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1026        @Override
1027        protected boolean allowFilterResult(
1028                BroadcastFilter filter, List<BroadcastFilter> dest) {
1029            IBinder target = filter.receiverList.receiver.asBinder();
1030            for (int i = dest.size() - 1; i >= 0; i--) {
1031                if (dest.get(i).receiverList.receiver.asBinder() == target) {
1032                    return false;
1033                }
1034            }
1035            return true;
1036        }
1037
1038        @Override
1039        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1040            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1041                    || userId == filter.owningUserId) {
1042                return super.newResult(filter, match, userId);
1043            }
1044            return null;
1045        }
1046
1047        @Override
1048        protected BroadcastFilter[] newArray(int size) {
1049            return new BroadcastFilter[size];
1050        }
1051
1052        @Override
1053        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1054            return packageName.equals(filter.packageName);
1055        }
1056    };
1057
1058    /**
1059     * State of all active sticky broadcasts per user.  Keys are the action of the
1060     * sticky Intent, values are an ArrayList of all broadcasted intents with
1061     * that action (which should usually be one).  The SparseArray is keyed
1062     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1063     * for stickies that are sent to all users.
1064     */
1065    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1066            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1067
1068    final ActiveServices mServices;
1069
1070    final static class Association {
1071        final int mSourceUid;
1072        final String mSourceProcess;
1073        final int mTargetUid;
1074        final ComponentName mTargetComponent;
1075        final String mTargetProcess;
1076
1077        int mCount;
1078        long mTime;
1079
1080        int mNesting;
1081        long mStartTime;
1082
1083        // states of the source process when the bind occurred.
1084        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1085        long mLastStateUptime;
1086        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1087                - ActivityManager.MIN_PROCESS_STATE+1];
1088
1089        Association(int sourceUid, String sourceProcess, int targetUid,
1090                ComponentName targetComponent, String targetProcess) {
1091            mSourceUid = sourceUid;
1092            mSourceProcess = sourceProcess;
1093            mTargetUid = targetUid;
1094            mTargetComponent = targetComponent;
1095            mTargetProcess = targetProcess;
1096        }
1097    }
1098
1099    /**
1100     * When service association tracking is enabled, this is all of the associations we
1101     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1102     * -> association data.
1103     */
1104    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1105            mAssociations = new SparseArray<>();
1106    boolean mTrackingAssociations;
1107
1108    /**
1109     * Backup/restore process management
1110     */
1111    String mBackupAppName = null;
1112    BackupRecord mBackupTarget = null;
1113
1114    final ProviderMap mProviderMap;
1115
1116    /**
1117     * List of content providers who have clients waiting for them.  The
1118     * application is currently being launched and the provider will be
1119     * removed from this list once it is published.
1120     */
1121    final ArrayList<ContentProviderRecord> mLaunchingProviders
1122            = new ArrayList<ContentProviderRecord>();
1123
1124    /**
1125     * File storing persisted {@link #mGrantedUriPermissions}.
1126     */
1127    private final AtomicFile mGrantFile;
1128
1129    /** XML constants used in {@link #mGrantFile} */
1130    private static final String TAG_URI_GRANTS = "uri-grants";
1131    private static final String TAG_URI_GRANT = "uri-grant";
1132    private static final String ATTR_USER_HANDLE = "userHandle";
1133    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1134    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1135    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1136    private static final String ATTR_TARGET_PKG = "targetPkg";
1137    private static final String ATTR_URI = "uri";
1138    private static final String ATTR_MODE_FLAGS = "modeFlags";
1139    private static final String ATTR_CREATED_TIME = "createdTime";
1140    private static final String ATTR_PREFIX = "prefix";
1141
1142    /**
1143     * Global set of specific {@link Uri} permissions that have been granted.
1144     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1145     * to {@link UriPermission#uri} to {@link UriPermission}.
1146     */
1147    @GuardedBy("this")
1148    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1149            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1150
1151    public static class GrantUri {
1152        public final int sourceUserId;
1153        public final Uri uri;
1154        public boolean prefix;
1155
1156        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1157            this.sourceUserId = sourceUserId;
1158            this.uri = uri;
1159            this.prefix = prefix;
1160        }
1161
1162        @Override
1163        public int hashCode() {
1164            int hashCode = 1;
1165            hashCode = 31 * hashCode + sourceUserId;
1166            hashCode = 31 * hashCode + uri.hashCode();
1167            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1168            return hashCode;
1169        }
1170
1171        @Override
1172        public boolean equals(Object o) {
1173            if (o instanceof GrantUri) {
1174                GrantUri other = (GrantUri) o;
1175                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1176                        && prefix == other.prefix;
1177            }
1178            return false;
1179        }
1180
1181        @Override
1182        public String toString() {
1183            String result = uri.toString() + " [user " + sourceUserId + "]";
1184            if (prefix) result += " [prefix]";
1185            return result;
1186        }
1187
1188        public String toSafeString() {
1189            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1190            if (prefix) result += " [prefix]";
1191            return result;
1192        }
1193
1194        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1195            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1196                    ContentProvider.getUriWithoutUserId(uri), false);
1197        }
1198    }
1199
1200    CoreSettingsObserver mCoreSettingsObserver;
1201
1202    FontScaleSettingObserver mFontScaleSettingObserver;
1203
1204    private final class FontScaleSettingObserver extends ContentObserver {
1205        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1206
1207        public FontScaleSettingObserver() {
1208            super(mHandler);
1209            ContentResolver resolver = mContext.getContentResolver();
1210            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1211        }
1212
1213        @Override
1214        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1215            if (mFontScaleUri.equals(uri)) {
1216                updateFontScaleIfNeeded(userId);
1217            }
1218        }
1219    }
1220
1221    /**
1222     * Thread-local storage used to carry caller permissions over through
1223     * indirect content-provider access.
1224     */
1225    private class Identity {
1226        public final IBinder token;
1227        public final int pid;
1228        public final int uid;
1229
1230        Identity(IBinder _token, int _pid, int _uid) {
1231            token = _token;
1232            pid = _pid;
1233            uid = _uid;
1234        }
1235    }
1236
1237    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1238
1239    /**
1240     * All information we have collected about the runtime performance of
1241     * any user id that can impact battery performance.
1242     */
1243    final BatteryStatsService mBatteryStatsService;
1244
1245    /**
1246     * Information about component usage
1247     */
1248    UsageStatsManagerInternal mUsageStatsService;
1249
1250    /**
1251     * Access to DeviceIdleController service.
1252     */
1253    DeviceIdleController.LocalService mLocalDeviceIdleController;
1254
1255    /**
1256     * Set of app ids that are whitelisted for device idle and thus background check.
1257     */
1258    int[] mDeviceIdleWhitelist = new int[0];
1259
1260    /**
1261     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1262     */
1263    int[] mDeviceIdleTempWhitelist = new int[0];
1264
1265    static final class PendingTempWhitelist {
1266        final int targetUid;
1267        final long duration;
1268        final String tag;
1269
1270        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1271            targetUid = _targetUid;
1272            duration = _duration;
1273            tag = _tag;
1274        }
1275    }
1276
1277    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1278
1279    /**
1280     * Information about and control over application operations
1281     */
1282    final AppOpsService mAppOpsService;
1283
1284    /** Current sequencing integer of the configuration, for skipping old configurations. */
1285    private int mConfigurationSeq;
1286
1287    /**
1288     * Temp object used when global and/or display override configuration is updated. It is also
1289     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1290     * anyone...
1291     */
1292    private Configuration mTempConfig = new Configuration();
1293
1294    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1295            new UpdateConfigurationResult();
1296    private static final class UpdateConfigurationResult {
1297        // Configuration changes that were updated.
1298        int changes;
1299        // If the activity was relaunched to match the new configuration.
1300        boolean activityRelaunched;
1301
1302        void reset() {
1303            changes = 0;
1304            activityRelaunched = false;
1305        }
1306    }
1307
1308    boolean mSuppressResizeConfigChanges;
1309
1310    /**
1311     * Hardware-reported OpenGLES version.
1312     */
1313    final int GL_ES_VERSION;
1314
1315    /**
1316     * List of initialization arguments to pass to all processes when binding applications to them.
1317     * For example, references to the commonly used services.
1318     */
1319    HashMap<String, IBinder> mAppBindArgs;
1320    HashMap<String, IBinder> mIsolatedAppBindArgs;
1321
1322    /**
1323     * Temporary to avoid allocations.  Protected by main lock.
1324     */
1325    final StringBuilder mStringBuilder = new StringBuilder(256);
1326
1327    /**
1328     * Used to control how we initialize the service.
1329     */
1330    ComponentName mTopComponent;
1331    String mTopAction = Intent.ACTION_MAIN;
1332    String mTopData;
1333
1334    volatile boolean mProcessesReady = false;
1335    volatile boolean mSystemReady = false;
1336    volatile boolean mOnBattery = false;
1337    volatile int mFactoryTest;
1338
1339    @GuardedBy("this") boolean mBooting = false;
1340    @GuardedBy("this") boolean mCallFinishBooting = false;
1341    @GuardedBy("this") boolean mBootAnimationComplete = false;
1342    @GuardedBy("this") boolean mLaunchWarningShown = false;
1343    @GuardedBy("this") boolean mCheckedForSetup = false;
1344
1345    final Context mContext;
1346
1347    /**
1348     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1349     * change at runtime. Use mContext for non-UI purposes.
1350     */
1351    final Context mUiContext;
1352
1353    /**
1354     * The time at which we will allow normal application switches again,
1355     * after a call to {@link #stopAppSwitches()}.
1356     */
1357    long mAppSwitchesAllowedTime;
1358
1359    /**
1360     * This is set to true after the first switch after mAppSwitchesAllowedTime
1361     * is set; any switches after that will clear the time.
1362     */
1363    boolean mDidAppSwitch;
1364
1365    /**
1366     * Last time (in uptime) at which we checked for power usage.
1367     */
1368    long mLastPowerCheckUptime;
1369
1370    /**
1371     * Set while we are wanting to sleep, to prevent any
1372     * activities from being started/resumed.
1373     *
1374     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1375     *
1376     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1377     * while in the sleep state until there is a pending transition out of sleep, in which case
1378     * mSleeping is set to false, and remains false while awake.
1379     *
1380     * Whether mSleeping can quickly toggled between true/false without the device actually
1381     * display changing states is undefined.
1382     */
1383    private boolean mSleeping = false;
1384
1385    /**
1386     * The process state used for processes that are running the top activities.
1387     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1388     */
1389    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1390
1391    /**
1392     * Set while we are running a voice interaction.  This overrides
1393     * sleeping while it is active.
1394     */
1395    IVoiceInteractionSession mRunningVoice;
1396
1397    /**
1398     * For some direct access we need to power manager.
1399     */
1400    PowerManagerInternal mLocalPowerManager;
1401
1402    /**
1403     * We want to hold a wake lock while running a voice interaction session, since
1404     * this may happen with the screen off and we need to keep the CPU running to
1405     * be able to continue to interact with the user.
1406     */
1407    PowerManager.WakeLock mVoiceWakeLock;
1408
1409    /**
1410     * State of external calls telling us if the device is awake or asleep.
1411     */
1412    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1413
1414    /**
1415     * Set if we are shutting down the system, similar to sleeping.
1416     */
1417    boolean mShuttingDown = false;
1418
1419    /**
1420     * Current sequence id for oom_adj computation traversal.
1421     */
1422    int mAdjSeq = 0;
1423
1424    /**
1425     * Current sequence id for process LRU updating.
1426     */
1427    int mLruSeq = 0;
1428
1429    /**
1430     * Keep track of the non-cached/empty process we last found, to help
1431     * determine how to distribute cached/empty processes next time.
1432     */
1433    int mNumNonCachedProcs = 0;
1434
1435    /**
1436     * Keep track of the number of cached hidden procs, to balance oom adj
1437     * distribution between those and empty procs.
1438     */
1439    int mNumCachedHiddenProcs = 0;
1440
1441    /**
1442     * Keep track of the number of service processes we last found, to
1443     * determine on the next iteration which should be B services.
1444     */
1445    int mNumServiceProcs = 0;
1446    int mNewNumAServiceProcs = 0;
1447    int mNewNumServiceProcs = 0;
1448
1449    /**
1450     * Allow the current computed overall memory level of the system to go down?
1451     * This is set to false when we are killing processes for reasons other than
1452     * memory management, so that the now smaller process list will not be taken as
1453     * an indication that memory is tighter.
1454     */
1455    boolean mAllowLowerMemLevel = false;
1456
1457    /**
1458     * The last computed memory level, for holding when we are in a state that
1459     * processes are going away for other reasons.
1460     */
1461    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1462
1463    /**
1464     * The last total number of process we have, to determine if changes actually look
1465     * like a shrinking number of process due to lower RAM.
1466     */
1467    int mLastNumProcesses;
1468
1469    /**
1470     * The uptime of the last time we performed idle maintenance.
1471     */
1472    long mLastIdleTime = SystemClock.uptimeMillis();
1473
1474    /**
1475     * Total time spent with RAM that has been added in the past since the last idle time.
1476     */
1477    long mLowRamTimeSinceLastIdle = 0;
1478
1479    /**
1480     * If RAM is currently low, when that horrible situation started.
1481     */
1482    long mLowRamStartTime = 0;
1483
1484    /**
1485     * For reporting to battery stats the current top application.
1486     */
1487    private String mCurResumedPackage = null;
1488    private int mCurResumedUid = -1;
1489
1490    /**
1491     * For reporting to battery stats the apps currently running foreground
1492     * service.  The ProcessMap is package/uid tuples; each of these contain
1493     * an array of the currently foreground processes.
1494     */
1495    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1496            = new ProcessMap<ArrayList<ProcessRecord>>();
1497
1498    /**
1499     * Set if the systemServer made a call to enterSafeMode.
1500     */
1501    boolean mSafeMode;
1502
1503    /**
1504     * If true, we are running under a test environment so will sample PSS from processes
1505     * much more rapidly to try to collect better data when the tests are rapidly
1506     * running through apps.
1507     */
1508    boolean mTestPssMode = false;
1509
1510    String mDebugApp = null;
1511    boolean mWaitForDebugger = false;
1512    boolean mDebugTransient = false;
1513    String mOrigDebugApp = null;
1514    boolean mOrigWaitForDebugger = false;
1515    boolean mAlwaysFinishActivities = false;
1516    boolean mForceResizableActivities;
1517    /**
1518     * Flag that indicates if multi-window is enabled.
1519     *
1520     * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1521     * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1522     * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1523     * At least one of the forms of multi-window must be enabled in order for this flag to be
1524     * initialized to 'true'.
1525     *
1526     * @see #mSupportsSplitScreenMultiWindow
1527     * @see #mSupportsFreeformWindowManagement
1528     * @see #mSupportsPictureInPicture
1529     * @see #mSupportsMultiDisplay
1530     */
1531    boolean mSupportsMultiWindow;
1532    boolean mSupportsSplitScreenMultiWindow;
1533    boolean mSupportsFreeformWindowManagement;
1534    boolean mSupportsPictureInPicture;
1535    boolean mSupportsMultiDisplay;
1536    boolean mSupportsLeanbackOnly;
1537    IActivityController mController = null;
1538    boolean mControllerIsAMonkey = false;
1539    String mProfileApp = null;
1540    ProcessRecord mProfileProc = null;
1541    ProfilerInfo mProfilerInfo = null;
1542    int mProfileType = 0;
1543    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1544    String mMemWatchDumpProcName;
1545    String mMemWatchDumpFile;
1546    int mMemWatchDumpPid;
1547    int mMemWatchDumpUid;
1548    String mTrackAllocationApp = null;
1549    String mNativeDebuggingApp = null;
1550
1551    final long[] mTmpLong = new long[2];
1552
1553    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1554
1555    /**
1556     * A global counter for generating sequence numbers.
1557     * This value will be used when incrementing sequence numbers in individual uidRecords.
1558     *
1559     * Having a global counter ensures that seq numbers are monotonically increasing for a
1560     * particular uid even when the uidRecord is re-created.
1561     */
1562    @GuardedBy("this")
1563    @VisibleForTesting
1564    long mProcStateSeqCounter = 0;
1565
1566    private final Injector mInjector;
1567
1568    static final class ProcessChangeItem {
1569        static final int CHANGE_ACTIVITIES = 1<<0;
1570        int changes;
1571        int uid;
1572        int pid;
1573        int processState;
1574        boolean foregroundActivities;
1575    }
1576
1577    static final class UidObserverRegistration {
1578        final int uid;
1579        final String pkg;
1580        final int which;
1581        final int cutpoint;
1582
1583        final SparseIntArray lastProcStates;
1584
1585        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1586            uid = _uid;
1587            pkg = _pkg;
1588            which = _which;
1589            cutpoint = _cutpoint;
1590            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1591                lastProcStates = new SparseIntArray();
1592            } else {
1593                lastProcStates = null;
1594            }
1595        }
1596    }
1597
1598    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1599    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1600
1601    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1602    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1603
1604    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1605    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1606
1607    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1608    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1609
1610    OomAdjObserver mCurOomAdjObserver;
1611    int mCurOomAdjUid;
1612
1613    interface OomAdjObserver {
1614        void onOomAdjMessage(String msg);
1615    }
1616
1617    /**
1618     * Runtime CPU use collection thread.  This object's lock is used to
1619     * perform synchronization with the thread (notifying it to run).
1620     */
1621    final Thread mProcessCpuThread;
1622
1623    /**
1624     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1625     * Must acquire this object's lock when accessing it.
1626     * NOTE: this lock will be held while doing long operations (trawling
1627     * through all processes in /proc), so it should never be acquired by
1628     * any critical paths such as when holding the main activity manager lock.
1629     */
1630    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1631            MONITOR_THREAD_CPU_USAGE);
1632    final AtomicLong mLastCpuTime = new AtomicLong(0);
1633    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1634    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1635
1636    long mLastWriteTime = 0;
1637
1638    /**
1639     * Used to retain an update lock when the foreground activity is in
1640     * immersive mode.
1641     */
1642    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1643
1644    /**
1645     * Set to true after the system has finished booting.
1646     */
1647    boolean mBooted = false;
1648
1649    WindowManagerService mWindowManager;
1650    final ActivityThread mSystemThread;
1651
1652    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1653        final ProcessRecord mApp;
1654        final int mPid;
1655        final IApplicationThread mAppThread;
1656
1657        AppDeathRecipient(ProcessRecord app, int pid,
1658                IApplicationThread thread) {
1659            if (DEBUG_ALL) Slog.v(
1660                TAG, "New death recipient " + this
1661                + " for thread " + thread.asBinder());
1662            mApp = app;
1663            mPid = pid;
1664            mAppThread = thread;
1665        }
1666
1667        @Override
1668        public void binderDied() {
1669            if (DEBUG_ALL) Slog.v(
1670                TAG, "Death received in " + this
1671                + " for thread " + mAppThread.asBinder());
1672            synchronized(ActivityManagerService.this) {
1673                appDiedLocked(mApp, mPid, mAppThread, true);
1674            }
1675        }
1676    }
1677
1678    static final int SHOW_ERROR_UI_MSG = 1;
1679    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1680    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1681    static final int UPDATE_CONFIGURATION_MSG = 4;
1682    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1683    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1684    static final int SERVICE_TIMEOUT_MSG = 12;
1685    static final int UPDATE_TIME_ZONE = 13;
1686    static final int SHOW_UID_ERROR_UI_MSG = 14;
1687    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1688    static final int PROC_START_TIMEOUT_MSG = 20;
1689    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1690    static final int KILL_APPLICATION_MSG = 22;
1691    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1692    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1693    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1694    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1695    static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1696    static final int CLEAR_DNS_CACHE_MSG = 28;
1697    static final int UPDATE_HTTP_PROXY_MSG = 29;
1698    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1699    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1700    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1701    static final int REPORT_MEM_USAGE_MSG = 33;
1702    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1703    static final int PERSIST_URI_GRANTS_MSG = 38;
1704    static final int REQUEST_ALL_PSS_MSG = 39;
1705    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1706    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1707    static final int FINISH_BOOTING_MSG = 45;
1708    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1709    static final int DISMISS_DIALOG_UI_MSG = 48;
1710    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1711    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1712    static final int DELETE_DUMPHEAP_MSG = 51;
1713    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1714    static final int REPORT_TIME_TRACKER_MSG = 54;
1715    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1716    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1717    static final int IDLE_UIDS_MSG = 58;
1718    static final int LOG_STACK_STATE = 60;
1719    static final int VR_MODE_CHANGE_MSG = 61;
1720    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1721    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1722    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1723    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1724    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1725    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1726    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1727    static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1728    static final int NOTIFY_VR_KEYGUARD_MSG = 74;
1729
1730    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1731    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1732    static final int FIRST_COMPAT_MODE_MSG = 300;
1733    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1734
1735    static ServiceThread sKillThread = null;
1736    static KillHandler sKillHandler = null;
1737
1738    CompatModeDialog mCompatModeDialog;
1739    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1740    long mLastMemUsageReportTime = 0;
1741
1742    /**
1743     * Flag whether the current user is a "monkey", i.e. whether
1744     * the UI is driven by a UI automation tool.
1745     */
1746    private boolean mUserIsMonkey;
1747
1748    /** The dimensions of the thumbnails in the Recents UI. */
1749    int mThumbnailWidth;
1750    int mThumbnailHeight;
1751    float mFullscreenThumbnailScale;
1752
1753    final ServiceThread mHandlerThread;
1754    final MainHandler mHandler;
1755    final Handler mUiHandler;
1756
1757    final ActivityManagerConstants mConstants;
1758
1759    PackageManagerInternal mPackageManagerInt;
1760
1761    // VoiceInteraction session ID that changes for each new request except when
1762    // being called for multiwindow assist in a single session.
1763    private int mViSessionId = 1000;
1764
1765    final boolean mPermissionReviewRequired;
1766
1767    private static String sTheRealBuildSerial = Build.UNKNOWN;
1768
1769    /**
1770     * Current global configuration information. Contains general settings for the entire system,
1771     * also corresponds to the merged configuration of the default display.
1772     */
1773    Configuration getGlobalConfiguration() {
1774        return mStackSupervisor.getConfiguration();
1775    }
1776
1777    final class KillHandler extends Handler {
1778        static final int KILL_PROCESS_GROUP_MSG = 4000;
1779
1780        public KillHandler(Looper looper) {
1781            super(looper, null, true);
1782        }
1783
1784        @Override
1785        public void handleMessage(Message msg) {
1786            switch (msg.what) {
1787                case KILL_PROCESS_GROUP_MSG:
1788                {
1789                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1790                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1791                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1792                }
1793                break;
1794
1795                default:
1796                    super.handleMessage(msg);
1797            }
1798        }
1799    }
1800
1801    final class UiHandler extends Handler {
1802        public UiHandler() {
1803            super(com.android.server.UiThread.get().getLooper(), null, true);
1804        }
1805
1806        @Override
1807        public void handleMessage(Message msg) {
1808            switch (msg.what) {
1809            case SHOW_ERROR_UI_MSG: {
1810                mAppErrors.handleShowAppErrorUi(msg);
1811                ensureBootCompleted();
1812            } break;
1813            case SHOW_NOT_RESPONDING_UI_MSG: {
1814                mAppErrors.handleShowAnrUi(msg);
1815                ensureBootCompleted();
1816            } break;
1817            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1818                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1819                synchronized (ActivityManagerService.this) {
1820                    ProcessRecord proc = (ProcessRecord) data.get("app");
1821                    if (proc == null) {
1822                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1823                        break;
1824                    }
1825                    if (proc.crashDialog != null) {
1826                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1827                        return;
1828                    }
1829                    AppErrorResult res = (AppErrorResult) data.get("result");
1830                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1831                        Dialog d = new StrictModeViolationDialog(mUiContext,
1832                                ActivityManagerService.this, res, proc);
1833                        d.show();
1834                        proc.crashDialog = d;
1835                    } else {
1836                        // The device is asleep, so just pretend that the user
1837                        // saw a crash dialog and hit "force quit".
1838                        res.set(0);
1839                    }
1840                }
1841                ensureBootCompleted();
1842            } break;
1843            case SHOW_FACTORY_ERROR_UI_MSG: {
1844                Dialog d = new FactoryErrorDialog(
1845                        mUiContext, msg.getData().getCharSequence("msg"));
1846                d.show();
1847                ensureBootCompleted();
1848            } break;
1849            case WAIT_FOR_DEBUGGER_UI_MSG: {
1850                synchronized (ActivityManagerService.this) {
1851                    ProcessRecord app = (ProcessRecord)msg.obj;
1852                    if (msg.arg1 != 0) {
1853                        if (!app.waitedForDebugger) {
1854                            Dialog d = new AppWaitingForDebuggerDialog(
1855                                    ActivityManagerService.this,
1856                                    mUiContext, app);
1857                            app.waitDialog = d;
1858                            app.waitedForDebugger = true;
1859                            d.show();
1860                        }
1861                    } else {
1862                        if (app.waitDialog != null) {
1863                            app.waitDialog.dismiss();
1864                            app.waitDialog = null;
1865                        }
1866                    }
1867                }
1868            } break;
1869            case SHOW_UID_ERROR_UI_MSG: {
1870                if (mShowDialogs) {
1871                    AlertDialog d = new BaseErrorDialog(mUiContext);
1872                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1873                    d.setCancelable(false);
1874                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1875                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1876                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1877                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1878                    d.show();
1879                }
1880            } break;
1881            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1882                if (mShowDialogs) {
1883                    AlertDialog d = new BaseErrorDialog(mUiContext);
1884                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1885                    d.setCancelable(false);
1886                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1887                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1888                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1889                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1890                    d.show();
1891                }
1892            } break;
1893            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1894                synchronized (ActivityManagerService.this) {
1895                    ActivityRecord ar = (ActivityRecord) msg.obj;
1896                    if (mCompatModeDialog != null) {
1897                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1898                                ar.info.applicationInfo.packageName)) {
1899                            return;
1900                        }
1901                        mCompatModeDialog.dismiss();
1902                        mCompatModeDialog = null;
1903                    }
1904                    if (ar != null && false) {
1905                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1906                                ar.packageName)) {
1907                            int mode = mCompatModePackages.computeCompatModeLocked(
1908                                    ar.info.applicationInfo);
1909                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1910                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1911                                mCompatModeDialog = new CompatModeDialog(
1912                                        ActivityManagerService.this, mUiContext,
1913                                        ar.info.applicationInfo);
1914                                mCompatModeDialog.show();
1915                            }
1916                        }
1917                    }
1918                }
1919                break;
1920            }
1921            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1922                synchronized (ActivityManagerService.this) {
1923                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1924                    if (mUnsupportedDisplaySizeDialog != null) {
1925                        mUnsupportedDisplaySizeDialog.dismiss();
1926                        mUnsupportedDisplaySizeDialog = null;
1927                    }
1928                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1929                            ar.packageName)) {
1930                        // TODO(multi-display): Show dialog on appropriate display.
1931                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1932                                ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1933                        mUnsupportedDisplaySizeDialog.show();
1934                    }
1935                }
1936                break;
1937            }
1938            case DISMISS_DIALOG_UI_MSG: {
1939                final Dialog d = (Dialog) msg.obj;
1940                d.dismiss();
1941                break;
1942            }
1943            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1944                dispatchProcessesChanged();
1945                break;
1946            }
1947            case DISPATCH_PROCESS_DIED_UI_MSG: {
1948                final int pid = msg.arg1;
1949                final int uid = msg.arg2;
1950                dispatchProcessDied(pid, uid);
1951                break;
1952            }
1953            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1954                dispatchUidsChanged();
1955            } break;
1956            case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1957                dispatchOomAdjObserver((String)msg.obj);
1958            } break;
1959            case PUSH_TEMP_WHITELIST_UI_MSG: {
1960                pushTempWhitelist();
1961            } break;
1962            }
1963        }
1964    }
1965
1966    final class MainHandler extends Handler {
1967        public MainHandler(Looper looper) {
1968            super(looper, null, true);
1969        }
1970
1971        @Override
1972        public void handleMessage(Message msg) {
1973            switch (msg.what) {
1974            case UPDATE_CONFIGURATION_MSG: {
1975                final ContentResolver resolver = mContext.getContentResolver();
1976                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1977                        msg.arg1);
1978            } break;
1979            case GC_BACKGROUND_PROCESSES_MSG: {
1980                synchronized (ActivityManagerService.this) {
1981                    performAppGcsIfAppropriateLocked();
1982                }
1983            } break;
1984            case SERVICE_TIMEOUT_MSG: {
1985                mServices.serviceTimeout((ProcessRecord)msg.obj);
1986            } break;
1987            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1988                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1989            } break;
1990            case SERVICE_FOREGROUND_CRASH_MSG: {
1991                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1992            } break;
1993            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1994                RemoteCallbackList<IResultReceiver> callbacks
1995                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
1996                int N = callbacks.beginBroadcast();
1997                for (int i = 0; i < N; i++) {
1998                    try {
1999                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
2000                    } catch (RemoteException e) {
2001                    }
2002                }
2003                callbacks.finishBroadcast();
2004            } break;
2005            case UPDATE_TIME_ZONE: {
2006                synchronized (ActivityManagerService.this) {
2007                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2008                        ProcessRecord r = mLruProcesses.get(i);
2009                        if (r.thread != null) {
2010                            try {
2011                                r.thread.updateTimeZone();
2012                            } catch (RemoteException ex) {
2013                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2014                            }
2015                        }
2016                    }
2017                }
2018            } break;
2019            case CLEAR_DNS_CACHE_MSG: {
2020                synchronized (ActivityManagerService.this) {
2021                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2022                        ProcessRecord r = mLruProcesses.get(i);
2023                        if (r.thread != null) {
2024                            try {
2025                                r.thread.clearDnsCache();
2026                            } catch (RemoteException ex) {
2027                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2028                            }
2029                        }
2030                    }
2031                }
2032            } break;
2033            case UPDATE_HTTP_PROXY_MSG: {
2034                ProxyInfo proxy = (ProxyInfo)msg.obj;
2035                String host = "";
2036                String port = "";
2037                String exclList = "";
2038                Uri pacFileUrl = Uri.EMPTY;
2039                if (proxy != null) {
2040                    host = proxy.getHost();
2041                    port = Integer.toString(proxy.getPort());
2042                    exclList = proxy.getExclusionListAsString();
2043                    pacFileUrl = proxy.getPacFileUrl();
2044                }
2045                synchronized (ActivityManagerService.this) {
2046                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2047                        ProcessRecord r = mLruProcesses.get(i);
2048                        // Don't dispatch to isolated processes as they can't access
2049                        // ConnectivityManager and don't have network privileges anyway.
2050                        if (r.thread != null && !r.isolated) {
2051                            try {
2052                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2053                            } catch (RemoteException ex) {
2054                                Slog.w(TAG, "Failed to update http proxy for: " +
2055                                        r.info.processName);
2056                            }
2057                        }
2058                    }
2059                }
2060            } break;
2061            case PROC_START_TIMEOUT_MSG: {
2062                ProcessRecord app = (ProcessRecord)msg.obj;
2063                synchronized (ActivityManagerService.this) {
2064                    processStartTimedOutLocked(app);
2065                }
2066            } break;
2067            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2068                ProcessRecord app = (ProcessRecord)msg.obj;
2069                synchronized (ActivityManagerService.this) {
2070                    processContentProviderPublishTimedOutLocked(app);
2071                }
2072            } break;
2073            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2074                synchronized (ActivityManagerService.this) {
2075                    mActivityStarter.doPendingActivityLaunchesLocked(true);
2076                }
2077            } break;
2078            case KILL_APPLICATION_MSG: {
2079                synchronized (ActivityManagerService.this) {
2080                    final int appId = msg.arg1;
2081                    final int userId = msg.arg2;
2082                    Bundle bundle = (Bundle)msg.obj;
2083                    String pkg = bundle.getString("pkg");
2084                    String reason = bundle.getString("reason");
2085                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2086                            false, userId, reason);
2087                }
2088            } break;
2089            case FINALIZE_PENDING_INTENT_MSG: {
2090                ((PendingIntentRecord)msg.obj).completeFinalize();
2091            } break;
2092            case POST_HEAVY_NOTIFICATION_MSG: {
2093                INotificationManager inm = NotificationManager.getService();
2094                if (inm == null) {
2095                    return;
2096                }
2097
2098                ActivityRecord root = (ActivityRecord)msg.obj;
2099                ProcessRecord process = root.app;
2100                if (process == null) {
2101                    return;
2102                }
2103
2104                try {
2105                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2106                    String text = mContext.getString(R.string.heavy_weight_notification,
2107                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2108                    Notification notification =
2109                            new Notification.Builder(context,
2110                                    SystemNotificationChannels.HEAVY_WEIGHT_APP)
2111                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2112                            .setWhen(0)
2113                            .setOngoing(true)
2114                            .setTicker(text)
2115                            .setColor(mContext.getColor(
2116                                    com.android.internal.R.color.system_notification_accent_color))
2117                            .setContentTitle(text)
2118                            .setContentText(
2119                                    mContext.getText(R.string.heavy_weight_notification_detail))
2120                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2121                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2122                                    new UserHandle(root.userId)))
2123                            .build();
2124                    try {
2125                        inm.enqueueNotificationWithTag("android", "android", null,
2126                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2127                                notification, root.userId);
2128                    } catch (RuntimeException e) {
2129                        Slog.w(ActivityManagerService.TAG,
2130                                "Error showing notification for heavy-weight app", e);
2131                    } catch (RemoteException e) {
2132                    }
2133                } catch (NameNotFoundException e) {
2134                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2135                }
2136            } break;
2137            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2138                INotificationManager inm = NotificationManager.getService();
2139                if (inm == null) {
2140                    return;
2141                }
2142                try {
2143                    inm.cancelNotificationWithTag("android", null,
2144                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2145                } catch (RuntimeException e) {
2146                    Slog.w(ActivityManagerService.TAG,
2147                            "Error canceling notification for service", e);
2148                } catch (RemoteException e) {
2149                }
2150            } break;
2151            case CHECK_EXCESSIVE_POWER_USE_MSG: {
2152                synchronized (ActivityManagerService.this) {
2153                    checkExcessivePowerUsageLocked();
2154                    removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2155                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2156                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2157                }
2158            } break;
2159            case REPORT_MEM_USAGE_MSG: {
2160                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2161                Thread thread = new Thread() {
2162                    @Override public void run() {
2163                        reportMemUsage(memInfos);
2164                    }
2165                };
2166                thread.start();
2167                break;
2168            }
2169            case IMMERSIVE_MODE_LOCK_MSG: {
2170                final boolean nextState = (msg.arg1 != 0);
2171                if (mUpdateLock.isHeld() != nextState) {
2172                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2173                            "Applying new update lock state '" + nextState
2174                            + "' for " + (ActivityRecord)msg.obj);
2175                    if (nextState) {
2176                        mUpdateLock.acquire();
2177                    } else {
2178                        mUpdateLock.release();
2179                    }
2180                }
2181                break;
2182            }
2183            case PERSIST_URI_GRANTS_MSG: {
2184                writeGrantedUriPermissions();
2185                break;
2186            }
2187            case REQUEST_ALL_PSS_MSG: {
2188                synchronized (ActivityManagerService.this) {
2189                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2190                }
2191                break;
2192            }
2193            case UPDATE_TIME_PREFERENCE_MSG: {
2194                // The user's time format preference might have changed.
2195                // For convenience we re-use the Intent extra values.
2196                synchronized (ActivityManagerService.this) {
2197                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2198                        ProcessRecord r = mLruProcesses.get(i);
2199                        if (r.thread != null) {
2200                            try {
2201                                r.thread.updateTimePrefs(msg.arg1);
2202                            } catch (RemoteException ex) {
2203                                Slog.w(TAG, "Failed to update preferences for: "
2204                                        + r.info.processName);
2205                            }
2206                        }
2207                    }
2208                }
2209                break;
2210            }
2211            case ENTER_ANIMATION_COMPLETE_MSG: {
2212                synchronized (ActivityManagerService.this) {
2213                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2214                    if (r != null && r.app != null && r.app.thread != null) {
2215                        try {
2216                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2217                        } catch (RemoteException e) {
2218                        }
2219                    }
2220                }
2221                break;
2222            }
2223            case FINISH_BOOTING_MSG: {
2224                if (msg.arg1 != 0) {
2225                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2226                    finishBooting();
2227                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2228                }
2229                if (msg.arg2 != 0) {
2230                    enableScreenAfterBoot();
2231                }
2232                break;
2233            }
2234            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2235                try {
2236                    Locale l = (Locale) msg.obj;
2237                    IBinder service = ServiceManager.getService("mount");
2238                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2239                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2240                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2241                } catch (RemoteException e) {
2242                    Log.e(TAG, "Error storing locale for decryption UI", e);
2243                }
2244                break;
2245            }
2246            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2247                final int uid = msg.arg1;
2248                final byte[] firstPacket = (byte[]) msg.obj;
2249
2250                synchronized (mPidsSelfLocked) {
2251                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2252                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2253                        if (p.uid == uid) {
2254                            try {
2255                                p.thread.notifyCleartextNetwork(firstPacket);
2256                            } catch (RemoteException ignored) {
2257                            }
2258                        }
2259                    }
2260                }
2261                break;
2262            }
2263            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2264                final String procName;
2265                final int uid;
2266                final long memLimit;
2267                final String reportPackage;
2268                synchronized (ActivityManagerService.this) {
2269                    procName = mMemWatchDumpProcName;
2270                    uid = mMemWatchDumpUid;
2271                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2272                    if (val == null) {
2273                        val = mMemWatchProcesses.get(procName, 0);
2274                    }
2275                    if (val != null) {
2276                        memLimit = val.first;
2277                        reportPackage = val.second;
2278                    } else {
2279                        memLimit = 0;
2280                        reportPackage = null;
2281                    }
2282                }
2283                if (procName == null) {
2284                    return;
2285                }
2286
2287                if (DEBUG_PSS) Slog.d(TAG_PSS,
2288                        "Showing dump heap notification from " + procName + "/" + uid);
2289
2290                INotificationManager inm = NotificationManager.getService();
2291                if (inm == null) {
2292                    return;
2293                }
2294
2295                String text = mContext.getString(R.string.dump_heap_notification, procName);
2296
2297
2298                Intent deleteIntent = new Intent();
2299                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2300                Intent intent = new Intent();
2301                intent.setClassName("android", DumpHeapActivity.class.getName());
2302                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2303                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2304                if (reportPackage != null) {
2305                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2306                }
2307                int userId = UserHandle.getUserId(uid);
2308                Notification notification =
2309                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2310                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2311                        .setWhen(0)
2312                        .setOngoing(true)
2313                        .setAutoCancel(true)
2314                        .setTicker(text)
2315                        .setColor(mContext.getColor(
2316                                com.android.internal.R.color.system_notification_accent_color))
2317                        .setContentTitle(text)
2318                        .setContentText(
2319                                mContext.getText(R.string.dump_heap_notification_detail))
2320                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2321                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2322                                new UserHandle(userId)))
2323                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2324                                deleteIntent, 0, UserHandle.SYSTEM))
2325                        .build();
2326
2327                try {
2328                    inm.enqueueNotificationWithTag("android", "android", null,
2329                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2330                            notification, userId);
2331                } catch (RuntimeException e) {
2332                    Slog.w(ActivityManagerService.TAG,
2333                            "Error showing notification for dump heap", e);
2334                } catch (RemoteException e) {
2335                }
2336            } break;
2337            case DELETE_DUMPHEAP_MSG: {
2338                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2339                        null, DumpHeapActivity.JAVA_URI,
2340                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2341                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2342                        UserHandle.myUserId());
2343                synchronized (ActivityManagerService.this) {
2344                    mMemWatchDumpFile = null;
2345                    mMemWatchDumpProcName = null;
2346                    mMemWatchDumpPid = -1;
2347                    mMemWatchDumpUid = -1;
2348                }
2349            } break;
2350            case REPORT_TIME_TRACKER_MSG: {
2351                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2352                tracker.deliverResult(mContext);
2353            } break;
2354            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2355                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2356                try {
2357                    connection.shutdown();
2358                } catch (RemoteException e) {
2359                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2360                }
2361                // Only a UiAutomation can set this flag and now that
2362                // it is finished we make sure it is reset to its default.
2363                mUserIsMonkey = false;
2364            } break;
2365            case IDLE_UIDS_MSG: {
2366                idleUids();
2367            } break;
2368            case VR_MODE_CHANGE_MSG: {
2369                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2370                    return;
2371                }
2372                synchronized (ActivityManagerService.this) {
2373                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2374                    mWindowManager.disableNonVrUi(disableNonVrUi);
2375                    if (disableNonVrUi) {
2376                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2377                        // then remove the pinned stack.
2378                        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2379                    }
2380                }
2381            } break;
2382            case NOTIFY_VR_SLEEPING_MSG: {
2383                notifyVrManagerOfSleepState(msg.arg1 != 0);
2384            } break;
2385            case NOTIFY_VR_KEYGUARD_MSG: {
2386                notifyVrManagerOfKeyguardState(msg.arg1 != 0);
2387            } break;
2388            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2389                synchronized (ActivityManagerService.this) {
2390                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2391                        ProcessRecord r = mLruProcesses.get(i);
2392                        if (r.thread != null) {
2393                            try {
2394                                r.thread.handleTrustStorageUpdate();
2395                            } catch (RemoteException ex) {
2396                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2397                                        r.info.processName);
2398                            }
2399                        }
2400                    }
2401                }
2402            } break;
2403            }
2404        }
2405    };
2406
2407    static final int COLLECT_PSS_BG_MSG = 1;
2408
2409    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2410        @Override
2411        public void handleMessage(Message msg) {
2412            switch (msg.what) {
2413            case COLLECT_PSS_BG_MSG: {
2414                long start = SystemClock.uptimeMillis();
2415                MemInfoReader memInfo = null;
2416                synchronized (ActivityManagerService.this) {
2417                    if (mFullPssPending) {
2418                        mFullPssPending = false;
2419                        memInfo = new MemInfoReader();
2420                    }
2421                }
2422                if (memInfo != null) {
2423                    updateCpuStatsNow();
2424                    long nativeTotalPss = 0;
2425                    final List<ProcessCpuTracker.Stats> stats;
2426                    synchronized (mProcessCpuTracker) {
2427                        stats = mProcessCpuTracker.getStats( (st)-> {
2428                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2429                        });
2430                    }
2431                    final int N = stats.size();
2432                    for (int j = 0; j < N; j++) {
2433                        synchronized (mPidsSelfLocked) {
2434                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2435                                // This is one of our own processes; skip it.
2436                                continue;
2437                            }
2438                        }
2439                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2440                    }
2441                    memInfo.readMemInfo();
2442                    synchronized (ActivityManagerService.this) {
2443                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2444                                + (SystemClock.uptimeMillis()-start) + "ms");
2445                        final long cachedKb = memInfo.getCachedSizeKb();
2446                        final long freeKb = memInfo.getFreeSizeKb();
2447                        final long zramKb = memInfo.getZramTotalSizeKb();
2448                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2449                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2450                                kernelKb*1024, nativeTotalPss*1024);
2451                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2452                                nativeTotalPss);
2453                    }
2454                }
2455
2456                int num = 0;
2457                long[] tmp = new long[2];
2458                do {
2459                    ProcessRecord proc;
2460                    int procState;
2461                    int pid;
2462                    long lastPssTime;
2463                    synchronized (ActivityManagerService.this) {
2464                        if (mPendingPssProcesses.size() <= 0) {
2465                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2466                                    "Collected PSS of " + num + " processes in "
2467                                    + (SystemClock.uptimeMillis() - start) + "ms");
2468                            mPendingPssProcesses.clear();
2469                            return;
2470                        }
2471                        proc = mPendingPssProcesses.remove(0);
2472                        procState = proc.pssProcState;
2473                        lastPssTime = proc.lastPssTime;
2474                        if (proc.thread != null && procState == proc.setProcState
2475                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2476                                        < SystemClock.uptimeMillis()) {
2477                            pid = proc.pid;
2478                        } else {
2479                            proc = null;
2480                            pid = 0;
2481                        }
2482                    }
2483                    if (proc != null) {
2484                        long pss = Debug.getPss(pid, tmp, null);
2485                        synchronized (ActivityManagerService.this) {
2486                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2487                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2488                                num++;
2489                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2490                                        SystemClock.uptimeMillis());
2491                            }
2492                        }
2493                    }
2494                } while (true);
2495            }
2496            }
2497        }
2498    };
2499
2500    public void setSystemProcess() {
2501        try {
2502            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
2503                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
2504            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2505            ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
2506                    DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
2507            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2508            ServiceManager.addService("dbinfo", new DbBinder(this));
2509            if (MONITOR_CPU_USAGE) {
2510                ServiceManager.addService("cpuinfo", new CpuBinder(this),
2511                        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
2512            }
2513            ServiceManager.addService("permission", new PermissionController(this));
2514            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2515
2516            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2517                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2518            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2519
2520            synchronized (this) {
2521                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2522                app.persistent = true;
2523                app.pid = MY_PID;
2524                app.maxAdj = ProcessList.SYSTEM_ADJ;
2525                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2526                synchronized (mPidsSelfLocked) {
2527                    mPidsSelfLocked.put(app.pid, app);
2528                }
2529                updateLruProcessLocked(app, false, null);
2530                updateOomAdjLocked();
2531            }
2532        } catch (PackageManager.NameNotFoundException e) {
2533            throw new RuntimeException(
2534                    "Unable to find android system package", e);
2535        }
2536    }
2537
2538    public void setWindowManager(WindowManagerService wm) {
2539        synchronized (this) {
2540            mWindowManager = wm;
2541            mStackSupervisor.setWindowManager(wm);
2542            mLockTaskController.setWindowManager(wm);
2543        }
2544    }
2545
2546    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2547        mUsageStatsService = usageStatsManager;
2548    }
2549
2550    public void startObservingNativeCrashes() {
2551        final NativeCrashListener ncl = new NativeCrashListener(this);
2552        ncl.start();
2553    }
2554
2555    public IAppOpsService getAppOpsService() {
2556        return mAppOpsService;
2557    }
2558
2559    static class MemBinder extends Binder {
2560        ActivityManagerService mActivityManagerService;
2561        private final PriorityDump.PriorityDumper mPriorityDumper =
2562                new PriorityDump.PriorityDumper() {
2563            @Override
2564            public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args,
2565                    boolean asProto) {
2566                if (asProto) return;
2567                mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2568            }
2569        };
2570
2571        MemBinder(ActivityManagerService activityManagerService) {
2572            mActivityManagerService = activityManagerService;
2573        }
2574
2575        @Override
2576        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2577            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2578                    "meminfo", pw)) return;
2579            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2580        }
2581    }
2582
2583    static class GraphicsBinder extends Binder {
2584        ActivityManagerService mActivityManagerService;
2585        GraphicsBinder(ActivityManagerService activityManagerService) {
2586            mActivityManagerService = activityManagerService;
2587        }
2588
2589        @Override
2590        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2591            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2592                    "gfxinfo", pw)) return;
2593            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2594        }
2595    }
2596
2597    static class DbBinder extends Binder {
2598        ActivityManagerService mActivityManagerService;
2599        DbBinder(ActivityManagerService activityManagerService) {
2600            mActivityManagerService = activityManagerService;
2601        }
2602
2603        @Override
2604        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2605            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2606                    "dbinfo", pw)) return;
2607            mActivityManagerService.dumpDbInfo(fd, pw, args);
2608        }
2609    }
2610
2611    static class CpuBinder extends Binder {
2612        ActivityManagerService mActivityManagerService;
2613        private final PriorityDump.PriorityDumper mPriorityDumper =
2614                new PriorityDump.PriorityDumper() {
2615            @Override
2616            public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
2617                    boolean asProto) {
2618                if (asProto) return;
2619                if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2620                        "cpuinfo", pw)) return;
2621                synchronized (mActivityManagerService.mProcessCpuTracker) {
2622                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2623                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2624                            SystemClock.uptimeMillis()));
2625                }
2626            }
2627        };
2628
2629        CpuBinder(ActivityManagerService activityManagerService) {
2630            mActivityManagerService = activityManagerService;
2631        }
2632
2633        @Override
2634        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2635            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2636        }
2637    }
2638
2639    public static final class Lifecycle extends SystemService {
2640        private final ActivityManagerService mService;
2641
2642        public Lifecycle(Context context) {
2643            super(context);
2644            mService = new ActivityManagerService(context);
2645        }
2646
2647        @Override
2648        public void onStart() {
2649            mService.start();
2650        }
2651
2652        @Override
2653        public void onCleanupUser(int userId) {
2654            mService.mBatteryStatsService.onCleanupUser(userId);
2655        }
2656
2657        public ActivityManagerService getService() {
2658            return mService;
2659        }
2660    }
2661
2662    @VisibleForTesting
2663    public ActivityManagerService(Injector injector) {
2664        mInjector = injector;
2665        mContext = mInjector.getContext();
2666        mUiContext = null;
2667        GL_ES_VERSION = 0;
2668        mActivityStarter = null;
2669        mAppErrors = null;
2670        mAppOpsService = mInjector.getAppOpsService(null, null);
2671        mBatteryStatsService = null;
2672        mCompatModePackages = null;
2673        mConstants = null;
2674        mGrantFile = null;
2675        mHandler = null;
2676        mHandlerThread = null;
2677        mIntentFirewall = null;
2678        mKeyguardController = null;
2679        mPermissionReviewRequired = false;
2680        mProcessCpuThread = null;
2681        mProcessStats = null;
2682        mProviderMap = null;
2683        mRecentTasks = null;
2684        mServices = null;
2685        mStackSupervisor = null;
2686        mSystemThread = null;
2687        mTaskChangeNotificationController = null;
2688        mUiHandler = injector.getUiHandler(null);
2689        mUserController = null;
2690        mVrController = null;
2691        mLockTaskController = null;
2692    }
2693
2694    // Note: This method is invoked on the main thread but may need to attach various
2695    // handlers to other threads.  So take care to be explicit about the looper.
2696    public ActivityManagerService(Context systemContext) {
2697        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2698        mInjector = new Injector();
2699        mContext = systemContext;
2700
2701        mFactoryTest = FactoryTest.getMode();
2702        mSystemThread = ActivityThread.currentActivityThread();
2703        mUiContext = mSystemThread.getSystemUiContext();
2704
2705        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2706
2707        mPermissionReviewRequired = mContext.getResources().getBoolean(
2708                com.android.internal.R.bool.config_permissionReviewRequired);
2709
2710        mHandlerThread = new ServiceThread(TAG,
2711                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2712        mHandlerThread.start();
2713        mHandler = new MainHandler(mHandlerThread.getLooper());
2714        mUiHandler = mInjector.getUiHandler(this);
2715
2716        mConstants = new ActivityManagerConstants(this, mHandler);
2717
2718        /* static; one-time init here */
2719        if (sKillHandler == null) {
2720            sKillThread = new ServiceThread(TAG + ":kill",
2721                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2722            sKillThread.start();
2723            sKillHandler = new KillHandler(sKillThread.getLooper());
2724        }
2725
2726        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2727                "foreground", BROADCAST_FG_TIMEOUT, false);
2728        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2729                "background", BROADCAST_BG_TIMEOUT, true);
2730        mBroadcastQueues[0] = mFgBroadcastQueue;
2731        mBroadcastQueues[1] = mBgBroadcastQueue;
2732
2733        mServices = new ActiveServices(this);
2734        mProviderMap = new ProviderMap(this);
2735        mAppErrors = new AppErrors(mUiContext, this);
2736
2737        // TODO: Move creation of battery stats service outside of activity manager service.
2738        File dataDir = Environment.getDataDirectory();
2739        File systemDir = new File(dataDir, "system");
2740        systemDir.mkdirs();
2741        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2742        mBatteryStatsService.getActiveStatistics().readLocked();
2743        mBatteryStatsService.scheduleWriteToDisk();
2744        mOnBattery = DEBUG_POWER ? true
2745                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2746        mBatteryStatsService.getActiveStatistics().setCallback(this);
2747
2748        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2749
2750        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2751        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2752                new IAppOpsCallback.Stub() {
2753                    @Override public void opChanged(int op, int uid, String packageName) {
2754                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2755                            if (mAppOpsService.checkOperation(op, uid, packageName)
2756                                    != AppOpsManager.MODE_ALLOWED) {
2757                                runInBackgroundDisabled(uid);
2758                            }
2759                        }
2760                    }
2761                });
2762
2763        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2764
2765        mUserController = new UserController(this);
2766
2767        mVrController = new VrController(this);
2768
2769        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2770            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2771
2772        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2773            mUseFifoUiScheduling = true;
2774        }
2775
2776        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2777        mTempConfig.setToDefaults();
2778        mTempConfig.setLocales(LocaleList.getDefault());
2779        mConfigurationSeq = mTempConfig.seq = 1;
2780        mStackSupervisor = createStackSupervisor();
2781        mStackSupervisor.onConfigurationChanged(mTempConfig);
2782        mKeyguardController = mStackSupervisor.mKeyguardController;
2783        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2784        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2785        mTaskChangeNotificationController =
2786                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2787        mActivityStarter = new ActivityStarter(this);
2788        mRecentTasks = createRecentTasks();
2789        mStackSupervisor.setRecentTasks(mRecentTasks);
2790        mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
2791
2792        mProcessCpuThread = new Thread("CpuTracker") {
2793            @Override
2794            public void run() {
2795                synchronized (mProcessCpuTracker) {
2796                    mProcessCpuInitLatch.countDown();
2797                    mProcessCpuTracker.init();
2798                }
2799                while (true) {
2800                    try {
2801                        try {
2802                            synchronized(this) {
2803                                final long now = SystemClock.uptimeMillis();
2804                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2805                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2806                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2807                                //        + ", write delay=" + nextWriteDelay);
2808                                if (nextWriteDelay < nextCpuDelay) {
2809                                    nextCpuDelay = nextWriteDelay;
2810                                }
2811                                if (nextCpuDelay > 0) {
2812                                    mProcessCpuMutexFree.set(true);
2813                                    this.wait(nextCpuDelay);
2814                                }
2815                            }
2816                        } catch (InterruptedException e) {
2817                        }
2818                        updateCpuStatsNow();
2819                    } catch (Exception e) {
2820                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2821                    }
2822                }
2823            }
2824        };
2825
2826        Watchdog.getInstance().addMonitor(this);
2827        Watchdog.getInstance().addThread(mHandler);
2828    }
2829
2830    protected ActivityStackSupervisor createStackSupervisor() {
2831        return new ActivityStackSupervisor(this, mHandler.getLooper());
2832    }
2833
2834    protected RecentTasks createRecentTasks() {
2835        return new RecentTasks(this, mStackSupervisor);
2836    }
2837
2838    RecentTasks getRecentTasks() {
2839        return mRecentTasks;
2840    }
2841
2842    public void setSystemServiceManager(SystemServiceManager mgr) {
2843        mSystemServiceManager = mgr;
2844    }
2845
2846    public void setInstaller(Installer installer) {
2847        mInstaller = installer;
2848    }
2849
2850    private void start() {
2851        removeAllProcessGroups();
2852        mProcessCpuThread.start();
2853
2854        mBatteryStatsService.publish();
2855        mAppOpsService.publish(mContext);
2856        Slog.d("AppOps", "AppOpsService published");
2857        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2858        // Wait for the synchronized block started in mProcessCpuThread,
2859        // so that any other acccess to mProcessCpuTracker from main thread
2860        // will be blocked during mProcessCpuTracker initialization.
2861        try {
2862            mProcessCpuInitLatch.await();
2863        } catch (InterruptedException e) {
2864            Slog.wtf(TAG, "Interrupted wait during start", e);
2865            Thread.currentThread().interrupt();
2866            throw new IllegalStateException("Interrupted wait during start");
2867        }
2868    }
2869
2870    void onUserStoppedLocked(int userId) {
2871        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2872    }
2873
2874    public void initPowerManagement() {
2875        mStackSupervisor.initPowerManagement();
2876        mBatteryStatsService.initPowerManagement();
2877        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2878        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2879        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2880        mVoiceWakeLock.setReferenceCounted(false);
2881    }
2882
2883    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2884        if (mBackgroundLaunchBroadcasts == null) {
2885            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2886        }
2887        return mBackgroundLaunchBroadcasts;
2888    }
2889
2890    @Override
2891    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2892            throws RemoteException {
2893        if (code == SYSPROPS_TRANSACTION) {
2894            // We need to tell all apps about the system property change.
2895            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2896            synchronized(this) {
2897                final int NP = mProcessNames.getMap().size();
2898                for (int ip=0; ip<NP; ip++) {
2899                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2900                    final int NA = apps.size();
2901                    for (int ia=0; ia<NA; ia++) {
2902                        ProcessRecord app = apps.valueAt(ia);
2903                        if (app.thread != null) {
2904                            procs.add(app.thread.asBinder());
2905                        }
2906                    }
2907                }
2908            }
2909
2910            int N = procs.size();
2911            for (int i=0; i<N; i++) {
2912                Parcel data2 = Parcel.obtain();
2913                try {
2914                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2915                            Binder.FLAG_ONEWAY);
2916                } catch (RemoteException e) {
2917                }
2918                data2.recycle();
2919            }
2920        }
2921        try {
2922            return super.onTransact(code, data, reply, flags);
2923        } catch (RuntimeException e) {
2924            // The activity manager only throws security exceptions, so let's
2925            // log all others.
2926            if (!(e instanceof SecurityException)) {
2927                Slog.wtf(TAG, "Activity Manager Crash."
2928                        + " UID:" + Binder.getCallingUid()
2929                        + " PID:" + Binder.getCallingPid()
2930                        + " TRANS:" + code, e);
2931            }
2932            throw e;
2933        }
2934    }
2935
2936    void updateCpuStats() {
2937        final long now = SystemClock.uptimeMillis();
2938        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2939            return;
2940        }
2941        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2942            synchronized (mProcessCpuThread) {
2943                mProcessCpuThread.notify();
2944            }
2945        }
2946    }
2947
2948    void updateCpuStatsNow() {
2949        synchronized (mProcessCpuTracker) {
2950            mProcessCpuMutexFree.set(false);
2951            final long now = SystemClock.uptimeMillis();
2952            boolean haveNewCpuStats = false;
2953
2954            if (MONITOR_CPU_USAGE &&
2955                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2956                mLastCpuTime.set(now);
2957                mProcessCpuTracker.update();
2958                if (mProcessCpuTracker.hasGoodLastStats()) {
2959                    haveNewCpuStats = true;
2960                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2961                    //Slog.i(TAG, "Total CPU usage: "
2962                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2963
2964                    // Slog the cpu usage if the property is set.
2965                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2966                        int user = mProcessCpuTracker.getLastUserTime();
2967                        int system = mProcessCpuTracker.getLastSystemTime();
2968                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2969                        int irq = mProcessCpuTracker.getLastIrqTime();
2970                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2971                        int idle = mProcessCpuTracker.getLastIdleTime();
2972
2973                        int total = user + system + iowait + irq + softIrq + idle;
2974                        if (total == 0) total = 1;
2975
2976                        EventLog.writeEvent(EventLogTags.CPU,
2977                                ((user+system+iowait+irq+softIrq) * 100) / total,
2978                                (user * 100) / total,
2979                                (system * 100) / total,
2980                                (iowait * 100) / total,
2981                                (irq * 100) / total,
2982                                (softIrq * 100) / total);
2983                    }
2984                }
2985            }
2986
2987            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2988            synchronized(bstats) {
2989                synchronized(mPidsSelfLocked) {
2990                    if (haveNewCpuStats) {
2991                        if (bstats.startAddingCpuLocked()) {
2992                            int totalUTime = 0;
2993                            int totalSTime = 0;
2994                            final int N = mProcessCpuTracker.countStats();
2995                            for (int i=0; i<N; i++) {
2996                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2997                                if (!st.working) {
2998                                    continue;
2999                                }
3000                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3001                                totalUTime += st.rel_utime;
3002                                totalSTime += st.rel_stime;
3003                                if (pr != null) {
3004                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3005                                    if (ps == null || !ps.isActive()) {
3006                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3007                                                pr.info.uid, pr.processName);
3008                                    }
3009                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3010                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3011                                    if (pr.lastCpuTime == 0) {
3012                                        pr.lastCpuTime = pr.curCpuTime;
3013                                    }
3014                                } else {
3015                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3016                                    if (ps == null || !ps.isActive()) {
3017                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3018                                                bstats.mapUid(st.uid), st.name);
3019                                    }
3020                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3021                                }
3022                            }
3023                            final int userTime = mProcessCpuTracker.getLastUserTime();
3024                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3025                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3026                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3027                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3028                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3029                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3030                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3031                        }
3032                    }
3033                }
3034
3035                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3036                    mLastWriteTime = now;
3037                    mBatteryStatsService.scheduleWriteToDisk();
3038                }
3039            }
3040        }
3041    }
3042
3043    @Override
3044    public void batteryNeedsCpuUpdate() {
3045        updateCpuStatsNow();
3046    }
3047
3048    @Override
3049    public void batteryPowerChanged(boolean onBattery) {
3050        // When plugging in, update the CPU stats first before changing
3051        // the plug state.
3052        updateCpuStatsNow();
3053        synchronized (this) {
3054            synchronized(mPidsSelfLocked) {
3055                mOnBattery = DEBUG_POWER ? true : onBattery;
3056            }
3057        }
3058    }
3059
3060    @Override
3061    public void batterySendBroadcast(Intent intent) {
3062        synchronized (this) {
3063            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3064                    AppOpsManager.OP_NONE, null, false, false,
3065                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3066        }
3067    }
3068
3069    /**
3070     * Initialize the application bind args. These are passed to each
3071     * process when the bindApplication() IPC is sent to the process. They're
3072     * lazily setup to make sure the services are running when they're asked for.
3073     */
3074    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3075        // Isolated processes won't get this optimization, so that we don't
3076        // violate the rules about which services they have access to.
3077        if (isolated) {
3078            if (mIsolatedAppBindArgs == null) {
3079                mIsolatedAppBindArgs = new HashMap<>();
3080                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3081            }
3082            return mIsolatedAppBindArgs;
3083        }
3084
3085        if (mAppBindArgs == null) {
3086            mAppBindArgs = new HashMap<>();
3087
3088            // Setup the application init args
3089            mAppBindArgs.put("package", ServiceManager.getService("package"));
3090            mAppBindArgs.put("window", ServiceManager.getService("window"));
3091            mAppBindArgs.put(Context.ALARM_SERVICE,
3092                    ServiceManager.getService(Context.ALARM_SERVICE));
3093        }
3094        return mAppBindArgs;
3095    }
3096
3097    /**
3098     * Update AMS states when an activity is resumed. This should only be called by
3099     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3100     */
3101    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3102        final TaskRecord task = r.getTask();
3103        if (task.isActivityTypeStandard()) {
3104            if (mCurAppTimeTracker != r.appTimeTracker) {
3105                // We are switching app tracking.  Complete the current one.
3106                if (mCurAppTimeTracker != null) {
3107                    mCurAppTimeTracker.stop();
3108                    mHandler.obtainMessage(
3109                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3110                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3111                    mCurAppTimeTracker = null;
3112                }
3113                if (r.appTimeTracker != null) {
3114                    mCurAppTimeTracker = r.appTimeTracker;
3115                    startTimeTrackingFocusedActivityLocked();
3116                }
3117            } else {
3118                startTimeTrackingFocusedActivityLocked();
3119            }
3120        } else {
3121            r.appTimeTracker = null;
3122        }
3123        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3124        // TODO: Probably not, because we don't want to resume voice on switching
3125        // back to this activity
3126        if (task.voiceInteractor != null) {
3127            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3128        } else {
3129            finishRunningVoiceLocked();
3130
3131            if (mLastResumedActivity != null) {
3132                final IVoiceInteractionSession session;
3133
3134                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3135                if (lastResumedActivityTask != null
3136                        && lastResumedActivityTask.voiceSession != null) {
3137                    session = lastResumedActivityTask.voiceSession;
3138                } else {
3139                    session = mLastResumedActivity.voiceSession;
3140                }
3141
3142                if (session != null) {
3143                    // We had been in a voice interaction session, but now focused has
3144                    // move to something different.  Just finish the session, we can't
3145                    // return to it and retain the proper state and synchronization with
3146                    // the voice interaction service.
3147                    finishVoiceTask(session);
3148                }
3149            }
3150        }
3151
3152        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3153            mUserController.sendForegroundProfileChanged(r.userId);
3154        }
3155        mLastResumedActivity = r;
3156
3157        mWindowManager.setFocusedApp(r.appToken, true);
3158
3159        applyUpdateLockStateLocked(r);
3160        applyUpdateVrModeLocked(r);
3161
3162        EventLogTags.writeAmSetResumedActivity(
3163                r == null ? -1 : r.userId,
3164                r == null ? "NULL" : r.shortComponentName,
3165                reason);
3166    }
3167
3168    @Override
3169    public void setFocusedStack(int stackId) {
3170        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3171        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3172        final long callingId = Binder.clearCallingIdentity();
3173        try {
3174            synchronized (this) {
3175                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3176                if (stack == null) {
3177                    Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
3178                    return;
3179                }
3180                final ActivityRecord r = stack.topRunningActivityLocked();
3181                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3182                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3183                }
3184            }
3185        } finally {
3186            Binder.restoreCallingIdentity(callingId);
3187        }
3188    }
3189
3190    @Override
3191    public void setFocusedTask(int taskId) {
3192        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3193        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3194        final long callingId = Binder.clearCallingIdentity();
3195        try {
3196            synchronized (this) {
3197                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3198                if (task == null) {
3199                    return;
3200                }
3201                final ActivityRecord r = task.topRunningActivityLocked();
3202                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3203                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3204                }
3205            }
3206        } finally {
3207            Binder.restoreCallingIdentity(callingId);
3208        }
3209    }
3210
3211    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3212    @Override
3213    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3214        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3215                "registerTaskStackListener()");
3216        mTaskChangeNotificationController.registerTaskStackListener(listener);
3217    }
3218
3219    /**
3220     * Unregister a task stack listener so that it stops receiving callbacks.
3221     */
3222    @Override
3223    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3224        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3225                "unregisterTaskStackListener()");
3226         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3227     }
3228
3229    @Override
3230    public void notifyActivityDrawn(IBinder token) {
3231        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3232        synchronized (this) {
3233            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3234            if (r != null) {
3235                r.getStack().notifyActivityDrawnLocked(r);
3236            }
3237        }
3238    }
3239
3240    final void applyUpdateLockStateLocked(ActivityRecord r) {
3241        // Modifications to the UpdateLock state are done on our handler, outside
3242        // the activity manager's locks.  The new state is determined based on the
3243        // state *now* of the relevant activity record.  The object is passed to
3244        // the handler solely for logging detail, not to be consulted/modified.
3245        final boolean nextState = r != null && r.immersive;
3246        mHandler.sendMessage(
3247                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3248    }
3249
3250    final void applyUpdateVrModeLocked(ActivityRecord r) {
3251        // VR apps are expected to run in a main display. If an app is turning on VR for
3252        // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3253        // fullscreen stack before enabling VR Mode.
3254        // TODO: The goal of this code is to keep the VR app on the main display. When the
3255        // stack implementation changes in the future, keep in mind that the use of the fullscreen
3256        // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3257        // option would be a better choice here.
3258        if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3259            Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3260                    + " to main stack for VR");
3261            final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3262                    WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3263            moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3264        }
3265        mHandler.sendMessage(
3266                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3267    }
3268
3269    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3270        mHandler.sendMessage(
3271                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3272    }
3273
3274    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3275        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3276        if (vrService == null) {
3277            return;
3278        }
3279        vrService.onSleepStateChanged(isSleeping);
3280    }
3281
3282    private void sendNotifyVrManagerOfKeyguardState(boolean isShowing) {
3283        mHandler.sendMessage(
3284                mHandler.obtainMessage(NOTIFY_VR_KEYGUARD_MSG, isShowing ? 1 : 0, 0));
3285    }
3286
3287    private void notifyVrManagerOfKeyguardState(boolean isShowing) {
3288        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3289        if (vrService == null) {
3290            return;
3291        }
3292        vrService.onKeyguardStateChanged(isShowing);
3293    }
3294
3295    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3296        Message msg = Message.obtain();
3297        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3298        msg.obj = r.getTask().askedCompatMode ? null : r;
3299        mUiHandler.sendMessage(msg);
3300    }
3301
3302    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3303        final Configuration globalConfig = getGlobalConfiguration();
3304        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3305                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3306            final Message msg = Message.obtain();
3307            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3308            msg.obj = r;
3309            mUiHandler.sendMessage(msg);
3310        }
3311    }
3312
3313    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3314            String what, Object obj, ProcessRecord srcApp) {
3315        app.lastActivityTime = now;
3316
3317        if (app.activities.size() > 0) {
3318            // Don't want to touch dependent processes that are hosting activities.
3319            return index;
3320        }
3321
3322        int lrui = mLruProcesses.lastIndexOf(app);
3323        if (lrui < 0) {
3324            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3325                    + what + " " + obj + " from " + srcApp);
3326            return index;
3327        }
3328
3329        if (lrui >= index) {
3330            // Don't want to cause this to move dependent processes *back* in the
3331            // list as if they were less frequently used.
3332            return index;
3333        }
3334
3335        if (lrui >= mLruProcessActivityStart) {
3336            // Don't want to touch dependent processes that are hosting activities.
3337            return index;
3338        }
3339
3340        mLruProcesses.remove(lrui);
3341        if (index > 0) {
3342            index--;
3343        }
3344        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3345                + " in LRU list: " + app);
3346        mLruProcesses.add(index, app);
3347        return index;
3348    }
3349
3350    static void killProcessGroup(int uid, int pid) {
3351        if (sKillHandler != null) {
3352            sKillHandler.sendMessage(
3353                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3354        } else {
3355            Slog.w(TAG, "Asked to kill process group before system bringup!");
3356            Process.killProcessGroup(uid, pid);
3357        }
3358    }
3359
3360    final void removeLruProcessLocked(ProcessRecord app) {
3361        int lrui = mLruProcesses.lastIndexOf(app);
3362        if (lrui >= 0) {
3363            if (!app.killed) {
3364                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3365                killProcessQuiet(app.pid);
3366                killProcessGroup(app.uid, app.pid);
3367            }
3368            if (lrui <= mLruProcessActivityStart) {
3369                mLruProcessActivityStart--;
3370            }
3371            if (lrui <= mLruProcessServiceStart) {
3372                mLruProcessServiceStart--;
3373            }
3374            mLruProcesses.remove(lrui);
3375        }
3376    }
3377
3378    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3379            ProcessRecord client) {
3380        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3381                || app.treatLikeActivity;
3382        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3383        if (!activityChange && hasActivity) {
3384            // The process has activities, so we are only allowing activity-based adjustments
3385            // to move it.  It should be kept in the front of the list with other
3386            // processes that have activities, and we don't want those to change their
3387            // order except due to activity operations.
3388            return;
3389        }
3390
3391        mLruSeq++;
3392        final long now = SystemClock.uptimeMillis();
3393        app.lastActivityTime = now;
3394
3395        // First a quick reject: if the app is already at the position we will
3396        // put it, then there is nothing to do.
3397        if (hasActivity) {
3398            final int N = mLruProcesses.size();
3399            if (N > 0 && mLruProcesses.get(N-1) == app) {
3400                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3401                return;
3402            }
3403        } else {
3404            if (mLruProcessServiceStart > 0
3405                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3406                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3407                return;
3408            }
3409        }
3410
3411        int lrui = mLruProcesses.lastIndexOf(app);
3412
3413        if (app.persistent && lrui >= 0) {
3414            // We don't care about the position of persistent processes, as long as
3415            // they are in the list.
3416            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3417            return;
3418        }
3419
3420        /* In progress: compute new position first, so we can avoid doing work
3421           if the process is not actually going to move.  Not yet working.
3422        int addIndex;
3423        int nextIndex;
3424        boolean inActivity = false, inService = false;
3425        if (hasActivity) {
3426            // Process has activities, put it at the very tipsy-top.
3427            addIndex = mLruProcesses.size();
3428            nextIndex = mLruProcessServiceStart;
3429            inActivity = true;
3430        } else if (hasService) {
3431            // Process has services, put it at the top of the service list.
3432            addIndex = mLruProcessActivityStart;
3433            nextIndex = mLruProcessServiceStart;
3434            inActivity = true;
3435            inService = true;
3436        } else  {
3437            // Process not otherwise of interest, it goes to the top of the non-service area.
3438            addIndex = mLruProcessServiceStart;
3439            if (client != null) {
3440                int clientIndex = mLruProcesses.lastIndexOf(client);
3441                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3442                        + app);
3443                if (clientIndex >= 0 && addIndex > clientIndex) {
3444                    addIndex = clientIndex;
3445                }
3446            }
3447            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3448        }
3449
3450        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3451                + mLruProcessActivityStart + "): " + app);
3452        */
3453
3454        if (lrui >= 0) {
3455            if (lrui < mLruProcessActivityStart) {
3456                mLruProcessActivityStart--;
3457            }
3458            if (lrui < mLruProcessServiceStart) {
3459                mLruProcessServiceStart--;
3460            }
3461            /*
3462            if (addIndex > lrui) {
3463                addIndex--;
3464            }
3465            if (nextIndex > lrui) {
3466                nextIndex--;
3467            }
3468            */
3469            mLruProcesses.remove(lrui);
3470        }
3471
3472        /*
3473        mLruProcesses.add(addIndex, app);
3474        if (inActivity) {
3475            mLruProcessActivityStart++;
3476        }
3477        if (inService) {
3478            mLruProcessActivityStart++;
3479        }
3480        */
3481
3482        int nextIndex;
3483        if (hasActivity) {
3484            final int N = mLruProcesses.size();
3485            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3486                // Process doesn't have activities, but has clients with
3487                // activities...  move it up, but one below the top (the top
3488                // should always have a real activity).
3489                if (DEBUG_LRU) Slog.d(TAG_LRU,
3490                        "Adding to second-top of LRU activity list: " + app);
3491                mLruProcesses.add(N - 1, app);
3492                // To keep it from spamming the LRU list (by making a bunch of clients),
3493                // we will push down any other entries owned by the app.
3494                final int uid = app.info.uid;
3495                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3496                    ProcessRecord subProc = mLruProcesses.get(i);
3497                    if (subProc.info.uid == uid) {
3498                        // We want to push this one down the list.  If the process after
3499                        // it is for the same uid, however, don't do so, because we don't
3500                        // want them internally to be re-ordered.
3501                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3502                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3503                                    "Pushing uid " + uid + " swapping at " + i + ": "
3504                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3505                            ProcessRecord tmp = mLruProcesses.get(i);
3506                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3507                            mLruProcesses.set(i - 1, tmp);
3508                            i--;
3509                        }
3510                    } else {
3511                        // A gap, we can stop here.
3512                        break;
3513                    }
3514                }
3515            } else {
3516                // Process has activities, put it at the very tipsy-top.
3517                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3518                mLruProcesses.add(app);
3519            }
3520            nextIndex = mLruProcessServiceStart;
3521        } else if (hasService) {
3522            // Process has services, put it at the top of the service list.
3523            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3524            mLruProcesses.add(mLruProcessActivityStart, app);
3525            nextIndex = mLruProcessServiceStart;
3526            mLruProcessActivityStart++;
3527        } else  {
3528            // Process not otherwise of interest, it goes to the top of the non-service area.
3529            int index = mLruProcessServiceStart;
3530            if (client != null) {
3531                // If there is a client, don't allow the process to be moved up higher
3532                // in the list than that client.
3533                int clientIndex = mLruProcesses.lastIndexOf(client);
3534                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3535                        + " when updating " + app);
3536                if (clientIndex <= lrui) {
3537                    // Don't allow the client index restriction to push it down farther in the
3538                    // list than it already is.
3539                    clientIndex = lrui;
3540                }
3541                if (clientIndex >= 0 && index > clientIndex) {
3542                    index = clientIndex;
3543                }
3544            }
3545            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3546            mLruProcesses.add(index, app);
3547            nextIndex = index-1;
3548            mLruProcessActivityStart++;
3549            mLruProcessServiceStart++;
3550        }
3551
3552        // If the app is currently using a content provider or service,
3553        // bump those processes as well.
3554        for (int j=app.connections.size()-1; j>=0; j--) {
3555            ConnectionRecord cr = app.connections.valueAt(j);
3556            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3557                    && cr.binding.service.app != null
3558                    && cr.binding.service.app.lruSeq != mLruSeq
3559                    && !cr.binding.service.app.persistent) {
3560                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3561                        "service connection", cr, app);
3562            }
3563        }
3564        for (int j=app.conProviders.size()-1; j>=0; j--) {
3565            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3566            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3567                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3568                        "provider reference", cpr, app);
3569            }
3570        }
3571    }
3572
3573    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3574        if (uid == SYSTEM_UID) {
3575            // The system gets to run in any process.  If there are multiple
3576            // processes with the same uid, just pick the first (this
3577            // should never happen).
3578            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3579            if (procs == null) return null;
3580            final int procCount = procs.size();
3581            for (int i = 0; i < procCount; i++) {
3582                final int procUid = procs.keyAt(i);
3583                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3584                    // Don't use an app process or different user process for system component.
3585                    continue;
3586                }
3587                return procs.valueAt(i);
3588            }
3589        }
3590        ProcessRecord proc = mProcessNames.get(processName, uid);
3591        if (false && proc != null && !keepIfLarge
3592                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3593                && proc.lastCachedPss >= 4000) {
3594            // Turn this condition on to cause killing to happen regularly, for testing.
3595            if (proc.baseProcessTracker != null) {
3596                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3597            }
3598            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3599        } else if (proc != null && !keepIfLarge
3600                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3601                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3602            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3603            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3604                if (proc.baseProcessTracker != null) {
3605                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3606                }
3607                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3608            }
3609        }
3610        return proc;
3611    }
3612
3613    void notifyPackageUse(String packageName, int reason) {
3614        synchronized(this) {
3615            getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3616        }
3617    }
3618
3619    boolean isNextTransitionForward() {
3620        int transit = mWindowManager.getPendingAppTransition();
3621        return transit == TRANSIT_ACTIVITY_OPEN
3622                || transit == TRANSIT_TASK_OPEN
3623                || transit == TRANSIT_TASK_TO_FRONT;
3624    }
3625
3626    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3627            String processName, String abiOverride, int uid, Runnable crashHandler) {
3628        synchronized(this) {
3629            ApplicationInfo info = new ApplicationInfo();
3630            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3631            // For isolated processes, the former contains the parent's uid and the latter the
3632            // actual uid of the isolated process.
3633            // In the special case introduced by this method (which is, starting an isolated
3634            // process directly from the SystemServer without an actual parent app process) the
3635            // closest thing to a parent's uid is SYSTEM_UID.
3636            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3637            // the |isolated| logic in the ProcessRecord constructor.
3638            info.uid = SYSTEM_UID;
3639            info.processName = processName;
3640            info.className = entryPoint;
3641            info.packageName = "android";
3642            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3643            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3644                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3645                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3646                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3647                    crashHandler);
3648            return proc != null ? proc.pid : 0;
3649        }
3650    }
3651
3652    final ProcessRecord startProcessLocked(String processName,
3653            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3654            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3655            boolean isolated, boolean keepIfLarge) {
3656        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3657                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3658                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3659                null /* crashHandler */);
3660    }
3661
3662    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3663            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3664            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3665            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3666        long startTime = SystemClock.elapsedRealtime();
3667        ProcessRecord app;
3668        if (!isolated) {
3669            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3670            checkTime(startTime, "startProcess: after getProcessRecord");
3671
3672            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3673                // If we are in the background, then check to see if this process
3674                // is bad.  If so, we will just silently fail.
3675                if (mAppErrors.isBadProcessLocked(info)) {
3676                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3677                            + "/" + info.processName);
3678                    return null;
3679                }
3680            } else {
3681                // When the user is explicitly starting a process, then clear its
3682                // crash count so that we won't make it bad until they see at
3683                // least one crash dialog again, and make the process good again
3684                // if it had been bad.
3685                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3686                        + "/" + info.processName);
3687                mAppErrors.resetProcessCrashTimeLocked(info);
3688                if (mAppErrors.isBadProcessLocked(info)) {
3689                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3690                            UserHandle.getUserId(info.uid), info.uid,
3691                            info.processName);
3692                    mAppErrors.clearBadProcessLocked(info);
3693                    if (app != null) {
3694                        app.bad = false;
3695                    }
3696                }
3697            }
3698        } else {
3699            // If this is an isolated process, it can't re-use an existing process.
3700            app = null;
3701        }
3702
3703        // We don't have to do anything more if:
3704        // (1) There is an existing application record; and
3705        // (2) The caller doesn't think it is dead, OR there is no thread
3706        //     object attached to it so we know it couldn't have crashed; and
3707        // (3) There is a pid assigned to it, so it is either starting or
3708        //     already running.
3709        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3710                + " app=" + app + " knownToBeDead=" + knownToBeDead
3711                + " thread=" + (app != null ? app.thread : null)
3712                + " pid=" + (app != null ? app.pid : -1));
3713        if (app != null && app.pid > 0) {
3714            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3715                // We already have the app running, or are waiting for it to
3716                // come up (we have a pid but not yet its thread), so keep it.
3717                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3718                // If this is a new package in the process, add the package to the list
3719                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3720                checkTime(startTime, "startProcess: done, added package to proc");
3721                return app;
3722            }
3723
3724            // An application record is attached to a previous process,
3725            // clean it up now.
3726            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3727            checkTime(startTime, "startProcess: bad proc running, killing");
3728            killProcessGroup(app.uid, app.pid);
3729            handleAppDiedLocked(app, true, true);
3730            checkTime(startTime, "startProcess: done killing old proc");
3731        }
3732
3733        String hostingNameStr = hostingName != null
3734                ? hostingName.flattenToShortString() : null;
3735
3736        if (app == null) {
3737            checkTime(startTime, "startProcess: creating new process record");
3738            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3739            if (app == null) {
3740                Slog.w(TAG, "Failed making new process record for "
3741                        + processName + "/" + info.uid + " isolated=" + isolated);
3742                return null;
3743            }
3744            app.crashHandler = crashHandler;
3745            app.isolatedEntryPoint = entryPoint;
3746            app.isolatedEntryPointArgs = entryPointArgs;
3747            checkTime(startTime, "startProcess: done creating new process record");
3748        } else {
3749            // If this is a new package in the process, add the package to the list
3750            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3751            checkTime(startTime, "startProcess: added package to existing proc");
3752        }
3753
3754        // If the system is not ready yet, then hold off on starting this
3755        // process until it is.
3756        if (!mProcessesReady
3757                && !isAllowedWhileBooting(info)
3758                && !allowWhileBooting) {
3759            if (!mProcessesOnHold.contains(app)) {
3760                mProcessesOnHold.add(app);
3761            }
3762            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3763                    "System not ready, putting on hold: " + app);
3764            checkTime(startTime, "startProcess: returning with proc on hold");
3765            return app;
3766        }
3767
3768        checkTime(startTime, "startProcess: stepping in to startProcess");
3769        startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
3770        checkTime(startTime, "startProcess: done starting proc!");
3771        return (app.pid != 0) ? app : null;
3772    }
3773
3774    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3775        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3776    }
3777
3778    private final void startProcessLocked(ProcessRecord app,
3779            String hostingType, String hostingNameStr) {
3780        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
3781    }
3782
3783    private final void startProcessLocked(ProcessRecord app, String hostingType,
3784            String hostingNameStr, String abiOverride) {
3785        long startTime = SystemClock.elapsedRealtime();
3786        if (app.pid > 0 && app.pid != MY_PID) {
3787            checkTime(startTime, "startProcess: removing from pids map");
3788            synchronized (mPidsSelfLocked) {
3789                mPidsSelfLocked.remove(app.pid);
3790                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3791            }
3792            checkTime(startTime, "startProcess: done removing from pids map");
3793            app.setPid(0);
3794        }
3795
3796        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3797                "startProcessLocked removing on hold: " + app);
3798        mProcessesOnHold.remove(app);
3799
3800        checkTime(startTime, "startProcess: starting to update cpu stats");
3801        updateCpuStats();
3802        checkTime(startTime, "startProcess: done updating cpu stats");
3803
3804        try {
3805            try {
3806                final int userId = UserHandle.getUserId(app.uid);
3807                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3808            } catch (RemoteException e) {
3809                throw e.rethrowAsRuntimeException();
3810            }
3811
3812            int uid = app.uid;
3813            int[] gids = null;
3814            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3815            if (!app.isolated) {
3816                int[] permGids = null;
3817                try {
3818                    checkTime(startTime, "startProcess: getting gids from package manager");
3819                    final IPackageManager pm = AppGlobals.getPackageManager();
3820                    permGids = pm.getPackageGids(app.info.packageName,
3821                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3822                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3823                            StorageManagerInternal.class);
3824                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3825                            app.info.packageName);
3826                } catch (RemoteException e) {
3827                    throw e.rethrowAsRuntimeException();
3828                }
3829
3830                /*
3831                 * Add shared application and profile GIDs so applications can share some
3832                 * resources like shared libraries and access user-wide resources
3833                 */
3834                if (ArrayUtils.isEmpty(permGids)) {
3835                    gids = new int[3];
3836                } else {
3837                    gids = new int[permGids.length + 3];
3838                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3839                }
3840                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3841                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3842                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3843            }
3844            checkTime(startTime, "startProcess: building args");
3845            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3846                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3847                        && mTopComponent != null
3848                        && app.processName.equals(mTopComponent.getPackageName())) {
3849                    uid = 0;
3850                }
3851                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3852                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3853                    uid = 0;
3854                }
3855            }
3856            int runtimeFlags = 0;
3857            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3858                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
3859                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3860                // Also turn on CheckJNI for debuggable apps. It's quite
3861                // awkward to turn on otherwise.
3862                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3863            }
3864            // Run the app in safe mode if its manifest requests so or the
3865            // system is booted in safe mode.
3866            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3867                mSafeMode == true) {
3868                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3869            }
3870            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3871                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3872            }
3873            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3874            if ("true".equals(genDebugInfoProperty)) {
3875                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3876            }
3877            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3878                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3879            }
3880            if ("1".equals(SystemProperties.get("debug.assert"))) {
3881                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3882            }
3883            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3884                // Enable all debug flags required by the native debugger.
3885                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3886                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3887                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3888                mNativeDebuggingApp = null;
3889            }
3890
3891            if (app.info.isPrivilegedApp() &&
3892                    !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
3893                runtimeFlags |= Zygote.DISABLE_VERIFIER;
3894                runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
3895            }
3896
3897            String invokeWith = null;
3898            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3899                // Debuggable apps may include a wrapper script with their library directory.
3900                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3901                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3902                try {
3903                    if (new File(wrapperFileName).exists()) {
3904                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3905                    }
3906                } finally {
3907                    StrictMode.setThreadPolicy(oldPolicy);
3908                }
3909            }
3910
3911            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3912            if (requiredAbi == null) {
3913                requiredAbi = Build.SUPPORTED_ABIS[0];
3914            }
3915
3916            String instructionSet = null;
3917            if (app.info.primaryCpuAbi != null) {
3918                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3919            }
3920
3921            app.gids = gids;
3922            app.requiredAbi = requiredAbi;
3923            app.instructionSet = instructionSet;
3924
3925            // the per-user SELinux context must be set
3926            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3927                Slog.wtf(TAG, "SELinux tag not defined",
3928                        new IllegalStateException("SELinux tag not defined for "
3929                        + app.info.packageName + " (uid " + app.uid + ")"));
3930            }
3931            final String seInfo = app.info.seInfo
3932                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3933            // Start the process.  It will either succeed and return a result containing
3934            // the PID of the new process, or else throw a RuntimeException.
3935            final String entryPoint = "android.app.ActivityThread";
3936            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3937                    app.processName);
3938            checkTime(startTime, "startProcess: asking zygote to start proc");
3939            ProcessStartResult startResult;
3940            if (hostingType.equals("webview_service")) {
3941                startResult = startWebView(entryPoint,
3942                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3943                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3944                        app.info.dataDir, null, null);
3945            } else {
3946                startResult = Process.start(entryPoint,
3947                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3948                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3949                        app.info.dataDir, invokeWith, null);
3950            }
3951            checkTime(startTime, "startProcess: returned from zygote!");
3952            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3953
3954            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3955            checkTime(startTime, "startProcess: done updating battery stats");
3956
3957            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3958                    UserHandle.getUserId(uid), startResult.pid, uid,
3959                    app.processName, hostingType,
3960                    hostingNameStr != null ? hostingNameStr : "");
3961
3962            try {
3963                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3964                        seInfo, app.info.sourceDir, startResult.pid);
3965            } catch (RemoteException ex) {
3966                // Ignore
3967            }
3968
3969            if (app.persistent) {
3970                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3971            }
3972
3973            checkTime(startTime, "startProcess: building log message");
3974            StringBuilder buf = mStringBuilder;
3975            buf.setLength(0);
3976            buf.append("Start proc ");
3977            buf.append(startResult.pid);
3978            buf.append(':');
3979            buf.append(app.processName);
3980            buf.append('/');
3981            UserHandle.formatUid(buf, uid);
3982            if (app.isolatedEntryPoint != null) {
3983                buf.append(" [");
3984                buf.append(app.isolatedEntryPoint);
3985                buf.append("]");
3986            }
3987            buf.append(" for ");
3988            buf.append(hostingType);
3989            if (hostingNameStr != null) {
3990                buf.append(" ");
3991                buf.append(hostingNameStr);
3992            }
3993            Slog.i(TAG, buf.toString());
3994            app.setPid(startResult.pid);
3995            app.usingWrapper = startResult.usingWrapper;
3996            app.removed = false;
3997            app.killed = false;
3998            app.killedByAm = false;
3999            checkTime(startTime, "startProcess: starting to update pids map");
4000            ProcessRecord oldApp;
4001            synchronized (mPidsSelfLocked) {
4002                oldApp = mPidsSelfLocked.get(startResult.pid);
4003            }
4004            // If there is already an app occupying that pid that hasn't been cleaned up
4005            if (oldApp != null && !app.isolated) {
4006                // Clean up anything relating to this pid first
4007                Slog.w(TAG, "Reusing pid " + startResult.pid
4008                        + " while app is still mapped to it");
4009                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4010                        true /*replacingPid*/);
4011            }
4012            synchronized (mPidsSelfLocked) {
4013                this.mPidsSelfLocked.put(startResult.pid, app);
4014                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4015                msg.obj = app;
4016                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4017                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4018            }
4019            checkTime(startTime, "startProcess: done updating pids map");
4020        } catch (RuntimeException e) {
4021            Slog.e(TAG, "Failure starting process " + app.processName, e);
4022
4023            // Something went very wrong while trying to start this process; one
4024            // common case is when the package is frozen due to an active
4025            // upgrade. To recover, clean up any active bookkeeping related to
4026            // starting this process. (We already invoked this method once when
4027            // the package was initially frozen through KILL_APPLICATION_MSG, so
4028            // it doesn't hurt to use it again.)
4029            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4030                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4031        }
4032    }
4033
4034    void updateUsageStats(ActivityRecord component, boolean resumed) {
4035        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4036                "updateUsageStats: comp=" + component + "res=" + resumed);
4037        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4038        if (resumed) {
4039            if (mUsageStatsService != null) {
4040                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4041                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4042            }
4043            synchronized (stats) {
4044                stats.noteActivityResumedLocked(component.app.uid);
4045            }
4046        } else {
4047            if (mUsageStatsService != null) {
4048                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4049                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4050            }
4051            synchronized (stats) {
4052                stats.noteActivityPausedLocked(component.app.uid);
4053            }
4054        }
4055    }
4056
4057    Intent getHomeIntent() {
4058        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4059        intent.setComponent(mTopComponent);
4060        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4061        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4062            intent.addCategory(Intent.CATEGORY_HOME);
4063        }
4064        return intent;
4065    }
4066
4067    boolean startHomeActivityLocked(int userId, String reason) {
4068        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4069                && mTopAction == null) {
4070            // We are running in factory test mode, but unable to find
4071            // the factory test app, so just sit around displaying the
4072            // error message and don't try to start anything.
4073            return false;
4074        }
4075        Intent intent = getHomeIntent();
4076        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4077        if (aInfo != null) {
4078            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4079            // Don't do this if the home app is currently being
4080            // instrumented.
4081            aInfo = new ActivityInfo(aInfo);
4082            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4083            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4084                    aInfo.applicationInfo.uid, true);
4085            if (app == null || app.instr == null) {
4086                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4087                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4088                // For ANR debugging to verify if the user activity is the one that actually
4089                // launched.
4090                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4091                mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4092            }
4093        } else {
4094            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4095        }
4096
4097        return true;
4098    }
4099
4100    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4101        ActivityInfo ai = null;
4102        ComponentName comp = intent.getComponent();
4103        try {
4104            if (comp != null) {
4105                // Factory test.
4106                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4107            } else {
4108                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4109                        intent,
4110                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4111                        flags, userId);
4112
4113                if (info != null) {
4114                    ai = info.activityInfo;
4115                }
4116            }
4117        } catch (RemoteException e) {
4118            // ignore
4119        }
4120
4121        return ai;
4122    }
4123
4124    /**
4125     * Starts the "new version setup screen" if appropriate.
4126     */
4127    void startSetupActivityLocked() {
4128        // Only do this once per boot.
4129        if (mCheckedForSetup) {
4130            return;
4131        }
4132
4133        // We will show this screen if the current one is a different
4134        // version than the last one shown, and we are not running in
4135        // low-level factory test mode.
4136        final ContentResolver resolver = mContext.getContentResolver();
4137        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4138                Settings.Global.getInt(resolver,
4139                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4140            mCheckedForSetup = true;
4141
4142            // See if we should be showing the platform update setup UI.
4143            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4144            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4145                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4146            if (!ris.isEmpty()) {
4147                final ResolveInfo ri = ris.get(0);
4148                String vers = ri.activityInfo.metaData != null
4149                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4150                        : null;
4151                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4152                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4153                            Intent.METADATA_SETUP_VERSION);
4154                }
4155                String lastVers = Settings.Secure.getString(
4156                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4157                if (vers != null && !vers.equals(lastVers)) {
4158                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4159                    intent.setComponent(new ComponentName(
4160                            ri.activityInfo.packageName, ri.activityInfo.name));
4161                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4162                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4163                            null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4164                }
4165            }
4166        }
4167    }
4168
4169    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4170        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4171    }
4172
4173    void enforceNotIsolatedCaller(String caller) {
4174        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4175            throw new SecurityException("Isolated process not allowed to call " + caller);
4176        }
4177    }
4178
4179    @Override
4180    public int getFrontActivityScreenCompatMode() {
4181        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4182        synchronized (this) {
4183            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4184        }
4185    }
4186
4187    @Override
4188    public void setFrontActivityScreenCompatMode(int mode) {
4189        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4190                "setFrontActivityScreenCompatMode");
4191        synchronized (this) {
4192            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4193        }
4194    }
4195
4196    @Override
4197    public int getPackageScreenCompatMode(String packageName) {
4198        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4199        synchronized (this) {
4200            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4201        }
4202    }
4203
4204    @Override
4205    public void setPackageScreenCompatMode(String packageName, int mode) {
4206        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4207                "setPackageScreenCompatMode");
4208        synchronized (this) {
4209            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4210        }
4211    }
4212
4213    @Override
4214    public boolean getPackageAskScreenCompat(String packageName) {
4215        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4216        synchronized (this) {
4217            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4218        }
4219    }
4220
4221    @Override
4222    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4223        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4224                "setPackageAskScreenCompat");
4225        synchronized (this) {
4226            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4227        }
4228    }
4229
4230    private boolean hasUsageStatsPermission(String callingPackage) {
4231        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4232                Binder.getCallingUid(), callingPackage);
4233        if (mode == AppOpsManager.MODE_DEFAULT) {
4234            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4235                    == PackageManager.PERMISSION_GRANTED;
4236        }
4237        return mode == AppOpsManager.MODE_ALLOWED;
4238    }
4239
4240    @Override
4241    public int getPackageProcessState(String packageName, String callingPackage) {
4242        if (!hasUsageStatsPermission(callingPackage)) {
4243            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4244                    "getPackageProcessState");
4245        }
4246
4247        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4248        synchronized (this) {
4249            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4250                final ProcessRecord proc = mLruProcesses.get(i);
4251                if (procState > proc.setProcState) {
4252                    if (proc.pkgList.containsKey(packageName) ||
4253                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4254                        procState = proc.setProcState;
4255                    }
4256                }
4257            }
4258        }
4259        return procState;
4260    }
4261
4262    @Override
4263    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4264            throws RemoteException {
4265        synchronized (this) {
4266            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4267            if (app == null) {
4268                throw new IllegalArgumentException("Unknown process: " + process);
4269            }
4270            if (app.thread == null) {
4271                throw new IllegalArgumentException("Process has no app thread");
4272            }
4273            if (app.trimMemoryLevel >= level) {
4274                throw new IllegalArgumentException(
4275                        "Unable to set a higher trim level than current level");
4276            }
4277            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4278                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4279                throw new IllegalArgumentException("Unable to set a background trim level "
4280                    + "on a foreground process");
4281            }
4282            app.thread.scheduleTrimMemory(level);
4283            app.trimMemoryLevel = level;
4284            return true;
4285        }
4286    }
4287
4288    private void dispatchProcessesChanged() {
4289        int N;
4290        synchronized (this) {
4291            N = mPendingProcessChanges.size();
4292            if (mActiveProcessChanges.length < N) {
4293                mActiveProcessChanges = new ProcessChangeItem[N];
4294            }
4295            mPendingProcessChanges.toArray(mActiveProcessChanges);
4296            mPendingProcessChanges.clear();
4297            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4298                    "*** Delivering " + N + " process changes");
4299        }
4300
4301        int i = mProcessObservers.beginBroadcast();
4302        while (i > 0) {
4303            i--;
4304            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4305            if (observer != null) {
4306                try {
4307                    for (int j=0; j<N; j++) {
4308                        ProcessChangeItem item = mActiveProcessChanges[j];
4309                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4310                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4311                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4312                                    + item.uid + ": " + item.foregroundActivities);
4313                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4314                                    item.foregroundActivities);
4315                        }
4316                    }
4317                } catch (RemoteException e) {
4318                }
4319            }
4320        }
4321        mProcessObservers.finishBroadcast();
4322
4323        synchronized (this) {
4324            for (int j=0; j<N; j++) {
4325                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4326            }
4327        }
4328    }
4329
4330    private void dispatchProcessDied(int pid, int uid) {
4331        int i = mProcessObservers.beginBroadcast();
4332        while (i > 0) {
4333            i--;
4334            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4335            if (observer != null) {
4336                try {
4337                    observer.onProcessDied(pid, uid);
4338                } catch (RemoteException e) {
4339                }
4340            }
4341        }
4342        mProcessObservers.finishBroadcast();
4343    }
4344
4345    @VisibleForTesting
4346    void dispatchUidsChanged() {
4347        int N;
4348        synchronized (this) {
4349            N = mPendingUidChanges.size();
4350            if (mActiveUidChanges.length < N) {
4351                mActiveUidChanges = new UidRecord.ChangeItem[N];
4352            }
4353            for (int i=0; i<N; i++) {
4354                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4355                mActiveUidChanges[i] = change;
4356                if (change.uidRecord != null) {
4357                    change.uidRecord.pendingChange = null;
4358                    change.uidRecord = null;
4359                }
4360            }
4361            mPendingUidChanges.clear();
4362            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4363                    "*** Delivering " + N + " uid changes");
4364        }
4365
4366        int i = mUidObservers.beginBroadcast();
4367        while (i > 0) {
4368            i--;
4369            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4370                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4371        }
4372        mUidObservers.finishBroadcast();
4373
4374        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4375            for (int j = 0; j < N; ++j) {
4376                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4377                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4378                    mValidateUids.remove(item.uid);
4379                } else {
4380                    UidRecord validateUid = mValidateUids.get(item.uid);
4381                    if (validateUid == null) {
4382                        validateUid = new UidRecord(item.uid);
4383                        mValidateUids.put(item.uid, validateUid);
4384                    }
4385                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4386                        validateUid.idle = true;
4387                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4388                        validateUid.idle = false;
4389                    }
4390                    validateUid.curProcState = validateUid.setProcState = item.processState;
4391                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4392                }
4393            }
4394        }
4395
4396        synchronized (this) {
4397            for (int j = 0; j < N; j++) {
4398                mAvailUidChanges.add(mActiveUidChanges[j]);
4399            }
4400        }
4401    }
4402
4403    private void dispatchUidsChangedForObserver(IUidObserver observer,
4404            UidObserverRegistration reg, int changesSize) {
4405        if (observer == null) {
4406            return;
4407        }
4408        try {
4409            for (int j = 0; j < changesSize; j++) {
4410                UidRecord.ChangeItem item = mActiveUidChanges[j];
4411                final int change = item.change;
4412                if (change == UidRecord.CHANGE_PROCSTATE &&
4413                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4414                    // No-op common case: no significant change, the observer is not
4415                    // interested in all proc state changes.
4416                    continue;
4417                }
4418                if ((change & UidRecord.CHANGE_IDLE) != 0) {
4419                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4420                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4421                                "UID idle uid=" + item.uid);
4422                        observer.onUidIdle(item.uid, item.ephemeral);
4423                    }
4424                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4425                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4426                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4427                                "UID active uid=" + item.uid);
4428                        observer.onUidActive(item.uid);
4429                    }
4430                }
4431                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4432                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
4433                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4434                                "UID cached uid=" + item.uid);
4435                        observer.onUidCachedChanged(item.uid, true);
4436                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4437                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4438                                "UID active uid=" + item.uid);
4439                        observer.onUidCachedChanged(item.uid, false);
4440                    }
4441                }
4442                if ((change & UidRecord.CHANGE_GONE) != 0) {
4443                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4444                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4445                                "UID gone uid=" + item.uid);
4446                        observer.onUidGone(item.uid, item.ephemeral);
4447                    }
4448                    if (reg.lastProcStates != null) {
4449                        reg.lastProcStates.delete(item.uid);
4450                    }
4451                } else {
4452                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4453                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4454                                "UID CHANGED uid=" + item.uid
4455                                        + ": " + item.processState);
4456                        boolean doReport = true;
4457                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4458                            final int lastState = reg.lastProcStates.get(item.uid,
4459                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4460                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4461                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4462                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4463                                doReport = lastAboveCut != newAboveCut;
4464                            } else {
4465                                doReport = item.processState
4466                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4467                            }
4468                        }
4469                        if (doReport) {
4470                            if (reg.lastProcStates != null) {
4471                                reg.lastProcStates.put(item.uid, item.processState);
4472                            }
4473                            observer.onUidStateChanged(item.uid, item.processState,
4474                                    item.procStateSeq);
4475                        }
4476                    }
4477                }
4478            }
4479        } catch (RemoteException e) {
4480        }
4481    }
4482
4483    void dispatchOomAdjObserver(String msg) {
4484        OomAdjObserver observer;
4485        synchronized (this) {
4486            observer = mCurOomAdjObserver;
4487        }
4488
4489        if (observer != null) {
4490            observer.onOomAdjMessage(msg);
4491        }
4492    }
4493
4494    void setOomAdjObserver(int uid, OomAdjObserver observer) {
4495        synchronized (this) {
4496            mCurOomAdjUid = uid;
4497            mCurOomAdjObserver = observer;
4498        }
4499    }
4500
4501    void clearOomAdjObserver() {
4502        synchronized (this) {
4503            mCurOomAdjUid = -1;
4504            mCurOomAdjObserver = null;
4505        }
4506    }
4507
4508    void reportOomAdjMessageLocked(String tag, String msg) {
4509        Slog.d(tag, msg);
4510        if (mCurOomAdjObserver != null) {
4511            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4512        }
4513    }
4514
4515    @Override
4516    public final int startActivity(IApplicationThread caller, String callingPackage,
4517            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4518            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4519        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4520                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4521                UserHandle.getCallingUserId());
4522    }
4523
4524    @Override
4525    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4526            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4527            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4528        enforceNotIsolatedCaller("startActivity");
4529        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4530                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4531        // TODO: Switch to user app stacks here.
4532        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4533                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4534                profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4535    }
4536
4537    @Override
4538    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4539            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4540            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4541            int userId) {
4542
4543        // This is very dangerous -- it allows you to perform a start activity (including
4544        // permission grants) as any app that may launch one of your own activities.  So
4545        // we will only allow this to be done from activities that are part of the core framework,
4546        // and then only when they are running as the system.
4547        final ActivityRecord sourceRecord;
4548        final int targetUid;
4549        final String targetPackage;
4550        synchronized (this) {
4551            if (resultTo == null) {
4552                throw new SecurityException("Must be called from an activity");
4553            }
4554            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4555            if (sourceRecord == null) {
4556                throw new SecurityException("Called with bad activity token: " + resultTo);
4557            }
4558            if (!sourceRecord.info.packageName.equals("android")) {
4559                throw new SecurityException(
4560                        "Must be called from an activity that is declared in the android package");
4561            }
4562            if (sourceRecord.app == null) {
4563                throw new SecurityException("Called without a process attached to activity");
4564            }
4565            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4566                // This is still okay, as long as this activity is running under the
4567                // uid of the original calling activity.
4568                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4569                    throw new SecurityException(
4570                            "Calling activity in uid " + sourceRecord.app.uid
4571                                    + " must be system uid or original calling uid "
4572                                    + sourceRecord.launchedFromUid);
4573                }
4574            }
4575            if (ignoreTargetSecurity) {
4576                if (intent.getComponent() == null) {
4577                    throw new SecurityException(
4578                            "Component must be specified with ignoreTargetSecurity");
4579                }
4580                if (intent.getSelector() != null) {
4581                    throw new SecurityException(
4582                            "Selector not allowed with ignoreTargetSecurity");
4583                }
4584            }
4585            targetUid = sourceRecord.launchedFromUid;
4586            targetPackage = sourceRecord.launchedFromPackage;
4587        }
4588
4589        if (userId == UserHandle.USER_NULL) {
4590            userId = UserHandle.getUserId(sourceRecord.app.uid);
4591        }
4592
4593        // TODO: Switch to user app stacks here.
4594        try {
4595            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4596                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4597                    null, null, bOptions, ignoreTargetSecurity, userId, null,
4598                    "startActivityAsCaller");
4599            return ret;
4600        } catch (SecurityException e) {
4601            // XXX need to figure out how to propagate to original app.
4602            // A SecurityException here is generally actually a fault of the original
4603            // calling activity (such as a fairly granting permissions), so propagate it
4604            // back to them.
4605            /*
4606            StringBuilder msg = new StringBuilder();
4607            msg.append("While launching");
4608            msg.append(intent.toString());
4609            msg.append(": ");
4610            msg.append(e.getMessage());
4611            */
4612            throw e;
4613        }
4614    }
4615
4616    @Override
4617    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4618            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4619            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4620        enforceNotIsolatedCaller("startActivityAndWait");
4621        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4622                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4623        WaitResult res = new WaitResult();
4624        // TODO: Switch to user app stacks here.
4625        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4626                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4627                bOptions, false, userId, null, "startActivityAndWait");
4628        return res;
4629    }
4630
4631    @Override
4632    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4633            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4634            int startFlags, Configuration config, Bundle bOptions, int userId) {
4635        enforceNotIsolatedCaller("startActivityWithConfig");
4636        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4637                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4638        // TODO: Switch to user app stacks here.
4639        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4640                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4641                null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4642        return ret;
4643    }
4644
4645    @Override
4646    public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4647            IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4648            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4649            throws TransactionTooLargeException {
4650        enforceNotIsolatedCaller("startActivityIntentSender");
4651        // Refuse possible leaked file descriptors
4652        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4653            throw new IllegalArgumentException("File descriptors passed in Intent");
4654        }
4655
4656        if (!(target instanceof PendingIntentRecord)) {
4657            throw new IllegalArgumentException("Bad PendingIntent object");
4658        }
4659
4660        PendingIntentRecord pir = (PendingIntentRecord)target;
4661
4662        synchronized (this) {
4663            // If this is coming from the currently resumed activity, it is
4664            // effectively saying that app switches are allowed at this point.
4665            final ActivityStack stack = getFocusedStack();
4666            if (stack.mResumedActivity != null &&
4667                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4668                mAppSwitchesAllowedTime = 0;
4669            }
4670        }
4671        int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4672                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4673        return ret;
4674    }
4675
4676    @Override
4677    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4678            Intent intent, String resolvedType, IVoiceInteractionSession session,
4679            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4680            Bundle bOptions, int userId) {
4681        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4682                != PackageManager.PERMISSION_GRANTED) {
4683            String msg = "Permission Denial: startVoiceActivity() from pid="
4684                    + Binder.getCallingPid()
4685                    + ", uid=" + Binder.getCallingUid()
4686                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4687            Slog.w(TAG, msg);
4688            throw new SecurityException(msg);
4689        }
4690        if (session == null || interactor == null) {
4691            throw new NullPointerException("null session or interactor");
4692        }
4693        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4694                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4695        // TODO: Switch to user app stacks here.
4696        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4697                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4698                null, bOptions, false, userId, null, "startVoiceActivity");
4699    }
4700
4701    @Override
4702    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4703            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4704        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4705                != PackageManager.PERMISSION_GRANTED) {
4706            final String msg = "Permission Denial: startAssistantActivity() from pid="
4707                    + Binder.getCallingPid()
4708                    + ", uid=" + Binder.getCallingUid()
4709                    + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4710            Slog.w(TAG, msg);
4711            throw new SecurityException(msg);
4712        }
4713        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4714                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4715        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4716                resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4717                userId, null, "startAssistantActivity");
4718    }
4719
4720    @Override
4721    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4722            throws RemoteException {
4723        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4724        synchronized (this) {
4725            ActivityRecord activity = getFocusedStack().topActivity();
4726            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4727                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4728            }
4729            if (mRunningVoice != null || activity.getTask().voiceSession != null
4730                    || activity.voiceSession != null) {
4731                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4732                return;
4733            }
4734            if (activity.pendingVoiceInteractionStart) {
4735                Slog.w(TAG, "Pending start of voice interaction already.");
4736                return;
4737            }
4738            activity.pendingVoiceInteractionStart = true;
4739        }
4740        LocalServices.getService(VoiceInteractionManagerInternal.class)
4741                .startLocalVoiceInteraction(callingActivity, options);
4742    }
4743
4744    @Override
4745    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4746        LocalServices.getService(VoiceInteractionManagerInternal.class)
4747                .stopLocalVoiceInteraction(callingActivity);
4748    }
4749
4750    @Override
4751    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4752        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4753                .supportsLocalVoiceInteraction();
4754    }
4755
4756    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4757            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4758        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4759        if (activityToCallback == null) return;
4760        activityToCallback.setVoiceSessionLocked(voiceSession);
4761
4762        // Inform the activity
4763        try {
4764            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4765                    voiceInteractor);
4766            long token = Binder.clearCallingIdentity();
4767            try {
4768                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4769            } finally {
4770                Binder.restoreCallingIdentity(token);
4771            }
4772            // TODO: VI Should we cache the activity so that it's easier to find later
4773            // rather than scan through all the stacks and activities?
4774        } catch (RemoteException re) {
4775            activityToCallback.clearVoiceSessionLocked();
4776            // TODO: VI Should this terminate the voice session?
4777        }
4778    }
4779
4780    @Override
4781    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4782        synchronized (this) {
4783            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4784                if (keepAwake) {
4785                    mVoiceWakeLock.acquire();
4786                } else {
4787                    mVoiceWakeLock.release();
4788                }
4789            }
4790        }
4791    }
4792
4793    @Override
4794    public boolean startNextMatchingActivity(IBinder callingActivity,
4795            Intent intent, Bundle bOptions) {
4796        // Refuse possible leaked file descriptors
4797        if (intent != null && intent.hasFileDescriptors() == true) {
4798            throw new IllegalArgumentException("File descriptors passed in Intent");
4799        }
4800        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4801
4802        synchronized (this) {
4803            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4804            if (r == null) {
4805                ActivityOptions.abort(options);
4806                return false;
4807            }
4808            if (r.app == null || r.app.thread == null) {
4809                // The caller is not running...  d'oh!
4810                ActivityOptions.abort(options);
4811                return false;
4812            }
4813            intent = new Intent(intent);
4814            // The caller is not allowed to change the data.
4815            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4816            // And we are resetting to find the next component...
4817            intent.setComponent(null);
4818
4819            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4820
4821            ActivityInfo aInfo = null;
4822            try {
4823                List<ResolveInfo> resolves =
4824                    AppGlobals.getPackageManager().queryIntentActivities(
4825                            intent, r.resolvedType,
4826                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4827                            UserHandle.getCallingUserId()).getList();
4828
4829                // Look for the original activity in the list...
4830                final int N = resolves != null ? resolves.size() : 0;
4831                for (int i=0; i<N; i++) {
4832                    ResolveInfo rInfo = resolves.get(i);
4833                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4834                            && rInfo.activityInfo.name.equals(r.info.name)) {
4835                        // We found the current one...  the next matching is
4836                        // after it.
4837                        i++;
4838                        if (i<N) {
4839                            aInfo = resolves.get(i).activityInfo;
4840                        }
4841                        if (debug) {
4842                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4843                                    + "/" + r.info.name);
4844                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4845                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4846                        }
4847                        break;
4848                    }
4849                }
4850            } catch (RemoteException e) {
4851            }
4852
4853            if (aInfo == null) {
4854                // Nobody who is next!
4855                ActivityOptions.abort(options);
4856                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4857                return false;
4858            }
4859
4860            intent.setComponent(new ComponentName(
4861                    aInfo.applicationInfo.packageName, aInfo.name));
4862            intent.setFlags(intent.getFlags()&~(
4863                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4864                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4865                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4866                    Intent.FLAG_ACTIVITY_NEW_TASK));
4867
4868            // Okay now we need to start the new activity, replacing the
4869            // currently running activity.  This is a little tricky because
4870            // we want to start the new one as if the current one is finished,
4871            // but not finish the current one first so that there is no flicker.
4872            // And thus...
4873            final boolean wasFinishing = r.finishing;
4874            r.finishing = true;
4875
4876            // Propagate reply information over to the new activity.
4877            final ActivityRecord resultTo = r.resultTo;
4878            final String resultWho = r.resultWho;
4879            final int requestCode = r.requestCode;
4880            r.resultTo = null;
4881            if (resultTo != null) {
4882                resultTo.removeResultsLocked(r, resultWho, requestCode);
4883            }
4884
4885            final long origId = Binder.clearCallingIdentity();
4886            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4887                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4888                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4889                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4890                    false, false, null, null, "startNextMatchingActivity");
4891            Binder.restoreCallingIdentity(origId);
4892
4893            r.finishing = wasFinishing;
4894            if (res != ActivityManager.START_SUCCESS) {
4895                return false;
4896            }
4897            return true;
4898        }
4899    }
4900
4901    @Override
4902    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4903        enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
4904                "startActivityFromRecents()");
4905
4906        final long origId = Binder.clearCallingIdentity();
4907        try {
4908            synchronized (this) {
4909                return mStackSupervisor.startActivityFromRecents(taskId, bOptions);
4910            }
4911        } finally {
4912            Binder.restoreCallingIdentity(origId);
4913        }
4914    }
4915
4916    final int startActivityInPackage(int uid, String callingPackage,
4917            Intent intent, String resolvedType, IBinder resultTo,
4918            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4919            TaskRecord inTask, String reason) {
4920
4921        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4922                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4923
4924        // TODO: Switch to user app stacks here.
4925        return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4926                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4927                null, null, null, bOptions, false, userId, inTask, reason);
4928    }
4929
4930    @Override
4931    public final int startActivities(IApplicationThread caller, String callingPackage,
4932            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4933            int userId) {
4934        final String reason = "startActivities";
4935        enforceNotIsolatedCaller(reason);
4936        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4937                userId, false, ALLOW_FULL_ONLY, reason, null);
4938        // TODO: Switch to user app stacks here.
4939        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4940                resolvedTypes, resultTo, bOptions, userId, reason);
4941        return ret;
4942    }
4943
4944    final int startActivitiesInPackage(int uid, String callingPackage,
4945            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4946            Bundle bOptions, int userId) {
4947
4948        final String reason = "startActivityInPackage";
4949        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4950                userId, false, ALLOW_FULL_ONLY, reason, null);
4951        // TODO: Switch to user app stacks here.
4952        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4953                resultTo, bOptions, userId, reason);
4954        return ret;
4955    }
4956
4957    @Override
4958    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4959        synchronized (this) {
4960            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4961            if (r == null) {
4962                return;
4963            }
4964            r.reportFullyDrawnLocked(restoredFromBundle);
4965        }
4966    }
4967
4968    @Override
4969    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4970        synchronized (this) {
4971            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4972            if (r == null) {
4973                return;
4974            }
4975            final long origId = Binder.clearCallingIdentity();
4976            try {
4977                r.setRequestedOrientation(requestedOrientation);
4978            } finally {
4979                Binder.restoreCallingIdentity(origId);
4980            }
4981        }
4982    }
4983
4984    @Override
4985    public int getRequestedOrientation(IBinder token) {
4986        synchronized (this) {
4987            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4988            if (r == null) {
4989                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4990            }
4991            return r.getRequestedOrientation();
4992        }
4993    }
4994
4995    @Override
4996    public final void requestActivityRelaunch(IBinder token) {
4997        synchronized(this) {
4998            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4999            if (r == null) {
5000                return;
5001            }
5002            final long origId = Binder.clearCallingIdentity();
5003            try {
5004                r.forceNewConfig = true;
5005                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5006                        true /* preserveWindow */);
5007            } finally {
5008                Binder.restoreCallingIdentity(origId);
5009            }
5010        }
5011    }
5012
5013    /**
5014     * This is the internal entry point for handling Activity.finish().
5015     *
5016     * @param token The Binder token referencing the Activity we want to finish.
5017     * @param resultCode Result code, if any, from this Activity.
5018     * @param resultData Result data (Intent), if any, from this Activity.
5019     * @param finishTask Whether to finish the task associated with this Activity.
5020     *
5021     * @return Returns true if the activity successfully finished, or false if it is still running.
5022     */
5023    @Override
5024    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5025            int finishTask) {
5026        // Refuse possible leaked file descriptors
5027        if (resultData != null && resultData.hasFileDescriptors() == true) {
5028            throw new IllegalArgumentException("File descriptors passed in Intent");
5029        }
5030
5031        synchronized(this) {
5032            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5033            if (r == null) {
5034                return true;
5035            }
5036            // Keep track of the root activity of the task before we finish it
5037            TaskRecord tr = r.getTask();
5038            ActivityRecord rootR = tr.getRootActivity();
5039            if (rootR == null) {
5040                Slog.w(TAG, "Finishing task with all activities already finished");
5041            }
5042            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5043            // finish.
5044            if (mLockTaskController.activityBlockedFromFinish(r)) {
5045                return false;
5046            }
5047
5048            if (mController != null) {
5049                // Find the first activity that is not finishing.
5050                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5051                if (next != null) {
5052                    // ask watcher if this is allowed
5053                    boolean resumeOK = true;
5054                    try {
5055                        resumeOK = mController.activityResuming(next.packageName);
5056                    } catch (RemoteException e) {
5057                        mController = null;
5058                        Watchdog.getInstance().setActivityController(null);
5059                    }
5060
5061                    if (!resumeOK) {
5062                        Slog.i(TAG, "Not finishing activity because controller resumed");
5063                        return false;
5064                    }
5065                }
5066            }
5067            final long origId = Binder.clearCallingIdentity();
5068            try {
5069                boolean res;
5070                final boolean finishWithRootActivity =
5071                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5072                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5073                        || (finishWithRootActivity && r == rootR)) {
5074                    // If requested, remove the task that is associated to this activity only if it
5075                    // was the root activity in the task. The result code and data is ignored
5076                    // because we don't support returning them across task boundaries. Also, to
5077                    // keep backwards compatibility we remove the task from recents when finishing
5078                    // task with root activity.
5079                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5080                    if (!res) {
5081                        Slog.i(TAG, "Removing task failed to finish activity");
5082                    }
5083                } else {
5084                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5085                            resultData, "app-request", true);
5086                    if (!res) {
5087                        Slog.i(TAG, "Failed to finish by app-request");
5088                    }
5089                }
5090                return res;
5091            } finally {
5092                Binder.restoreCallingIdentity(origId);
5093            }
5094        }
5095    }
5096
5097    @Override
5098    public final void finishHeavyWeightApp() {
5099        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5100                != PackageManager.PERMISSION_GRANTED) {
5101            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5102                    + Binder.getCallingPid()
5103                    + ", uid=" + Binder.getCallingUid()
5104                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5105            Slog.w(TAG, msg);
5106            throw new SecurityException(msg);
5107        }
5108
5109        synchronized(this) {
5110            final ProcessRecord proc = mHeavyWeightProcess;
5111            if (proc == null) {
5112                return;
5113            }
5114
5115            ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
5116            for (int i = 0; i < activities.size(); i++) {
5117                ActivityRecord r = activities.get(i);
5118                if (!r.finishing && r.isInStackLocked()) {
5119                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5120                            null, "finish-heavy", true);
5121                }
5122            }
5123
5124            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5125                    proc.userId, 0));
5126            mHeavyWeightProcess = null;
5127        }
5128    }
5129
5130    @Override
5131    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5132            String message) {
5133        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5134                != PackageManager.PERMISSION_GRANTED) {
5135            String msg = "Permission Denial: crashApplication() from pid="
5136                    + Binder.getCallingPid()
5137                    + ", uid=" + Binder.getCallingUid()
5138                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5139            Slog.w(TAG, msg);
5140            throw new SecurityException(msg);
5141        }
5142
5143        synchronized(this) {
5144            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5145        }
5146    }
5147
5148    @Override
5149    public final void finishSubActivity(IBinder token, String resultWho,
5150            int requestCode) {
5151        synchronized(this) {
5152            final long origId = Binder.clearCallingIdentity();
5153            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5154            if (r != null) {
5155                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5156            }
5157            Binder.restoreCallingIdentity(origId);
5158        }
5159    }
5160
5161    @Override
5162    public boolean finishActivityAffinity(IBinder token) {
5163        synchronized(this) {
5164            final long origId = Binder.clearCallingIdentity();
5165            try {
5166                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5167                if (r == null) {
5168                    return false;
5169                }
5170
5171                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5172                // can finish.
5173                final TaskRecord task = r.getTask();
5174                if (mLockTaskController.activityBlockedFromFinish(r)) {
5175                    return false;
5176                }
5177                return task.getStack().finishActivityAffinityLocked(r);
5178            } finally {
5179                Binder.restoreCallingIdentity(origId);
5180            }
5181        }
5182    }
5183
5184    @Override
5185    public void finishVoiceTask(IVoiceInteractionSession session) {
5186        synchronized (this) {
5187            final long origId = Binder.clearCallingIdentity();
5188            try {
5189                // TODO: VI Consider treating local voice interactions and voice tasks
5190                // differently here
5191                mStackSupervisor.finishVoiceTask(session);
5192            } finally {
5193                Binder.restoreCallingIdentity(origId);
5194            }
5195        }
5196
5197    }
5198
5199    @Override
5200    public boolean releaseActivityInstance(IBinder token) {
5201        synchronized(this) {
5202            final long origId = Binder.clearCallingIdentity();
5203            try {
5204                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5205                if (r == null) {
5206                    return false;
5207                }
5208                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5209            } finally {
5210                Binder.restoreCallingIdentity(origId);
5211            }
5212        }
5213    }
5214
5215    @Override
5216    public void releaseSomeActivities(IApplicationThread appInt) {
5217        synchronized(this) {
5218            final long origId = Binder.clearCallingIdentity();
5219            try {
5220                ProcessRecord app = getRecordForAppLocked(appInt);
5221                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5222            } finally {
5223                Binder.restoreCallingIdentity(origId);
5224            }
5225        }
5226    }
5227
5228    @Override
5229    public boolean willActivityBeVisible(IBinder token) {
5230        synchronized(this) {
5231            ActivityStack stack = ActivityRecord.getStackLocked(token);
5232            if (stack != null) {
5233                return stack.willActivityBeVisibleLocked(token);
5234            }
5235            return false;
5236        }
5237    }
5238
5239    @Override
5240    public void overridePendingTransition(IBinder token, String packageName,
5241            int enterAnim, int exitAnim) {
5242        synchronized(this) {
5243            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5244            if (self == null) {
5245                return;
5246            }
5247
5248            final long origId = Binder.clearCallingIdentity();
5249
5250            if (self.state == ActivityState.RESUMED
5251                    || self.state == ActivityState.PAUSING) {
5252                mWindowManager.overridePendingAppTransition(packageName,
5253                        enterAnim, exitAnim, null);
5254            }
5255
5256            Binder.restoreCallingIdentity(origId);
5257        }
5258    }
5259
5260    /**
5261     * Main function for removing an existing process from the activity manager
5262     * as a result of that process going away.  Clears out all connections
5263     * to the process.
5264     */
5265    private final void handleAppDiedLocked(ProcessRecord app,
5266            boolean restarting, boolean allowRestart) {
5267        int pid = app.pid;
5268        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5269                false /*replacingPid*/);
5270        if (!kept && !restarting) {
5271            removeLruProcessLocked(app);
5272            if (pid > 0) {
5273                ProcessList.remove(pid);
5274            }
5275        }
5276
5277        if (mProfileProc == app) {
5278            clearProfilerLocked();
5279        }
5280
5281        // Remove this application's activities from active lists.
5282        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5283
5284        app.activities.clear();
5285
5286        if (app.instr != null) {
5287            Slog.w(TAG, "Crash of app " + app.processName
5288                  + " running instrumentation " + app.instr.mClass);
5289            Bundle info = new Bundle();
5290            info.putString("shortMsg", "Process crashed.");
5291            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5292        }
5293
5294        mWindowManager.deferSurfaceLayout();
5295        try {
5296            if (!restarting && hasVisibleActivities
5297                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5298                // If there was nothing to resume, and we are not already restarting this process, but
5299                // there is a visible activity that is hosted by the process...  then make sure all
5300                // visible activities are running, taking care of restarting this process.
5301                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5302            }
5303        } finally {
5304            mWindowManager.continueSurfaceLayout();
5305        }
5306    }
5307
5308    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5309        final IBinder threadBinder = thread.asBinder();
5310        // Find the application record.
5311        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5312            final ProcessRecord rec = mLruProcesses.get(i);
5313            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5314                return i;
5315            }
5316        }
5317        return -1;
5318    }
5319
5320    final ProcessRecord getRecordForAppLocked(
5321            IApplicationThread thread) {
5322        if (thread == null) {
5323            return null;
5324        }
5325
5326        int appIndex = getLRURecordIndexForAppLocked(thread);
5327        if (appIndex >= 0) {
5328            return mLruProcesses.get(appIndex);
5329        }
5330
5331        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5332        // double-check that.
5333        final IBinder threadBinder = thread.asBinder();
5334        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5335        for (int i = pmap.size()-1; i >= 0; i--) {
5336            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5337            for (int j = procs.size()-1; j >= 0; j--) {
5338                final ProcessRecord proc = procs.valueAt(j);
5339                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5340                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5341                            + proc);
5342                    return proc;
5343                }
5344            }
5345        }
5346
5347        return null;
5348    }
5349
5350    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5351        // If there are no longer any background processes running,
5352        // and the app that died was not running instrumentation,
5353        // then tell everyone we are now low on memory.
5354        boolean haveBg = false;
5355        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5356            ProcessRecord rec = mLruProcesses.get(i);
5357            if (rec.thread != null
5358                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5359                haveBg = true;
5360                break;
5361            }
5362        }
5363
5364        if (!haveBg) {
5365            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5366            if (doReport) {
5367                long now = SystemClock.uptimeMillis();
5368                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5369                    doReport = false;
5370                } else {
5371                    mLastMemUsageReportTime = now;
5372                }
5373            }
5374            final ArrayList<ProcessMemInfo> memInfos
5375                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5376            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5377            long now = SystemClock.uptimeMillis();
5378            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5379                ProcessRecord rec = mLruProcesses.get(i);
5380                if (rec == dyingProc || rec.thread == null) {
5381                    continue;
5382                }
5383                if (doReport) {
5384                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5385                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5386                }
5387                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5388                    // The low memory report is overriding any current
5389                    // state for a GC request.  Make sure to do
5390                    // heavy/important/visible/foreground processes first.
5391                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5392                        rec.lastRequestedGc = 0;
5393                    } else {
5394                        rec.lastRequestedGc = rec.lastLowMemory;
5395                    }
5396                    rec.reportLowMemory = true;
5397                    rec.lastLowMemory = now;
5398                    mProcessesToGc.remove(rec);
5399                    addProcessToGcListLocked(rec);
5400                }
5401            }
5402            if (doReport) {
5403                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5404                mHandler.sendMessage(msg);
5405            }
5406            scheduleAppGcsLocked();
5407        }
5408    }
5409
5410    final void appDiedLocked(ProcessRecord app) {
5411       appDiedLocked(app, app.pid, app.thread, false);
5412    }
5413
5414    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5415            boolean fromBinderDied) {
5416        // First check if this ProcessRecord is actually active for the pid.
5417        synchronized (mPidsSelfLocked) {
5418            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5419            if (curProc != app) {
5420                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5421                return;
5422            }
5423        }
5424
5425        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5426        synchronized (stats) {
5427            stats.noteProcessDiedLocked(app.info.uid, pid);
5428        }
5429
5430        if (!app.killed) {
5431            if (!fromBinderDied) {
5432                killProcessQuiet(pid);
5433            }
5434            killProcessGroup(app.uid, pid);
5435            app.killed = true;
5436        }
5437
5438        // Clean up already done if the process has been re-started.
5439        if (app.pid == pid && app.thread != null &&
5440                app.thread.asBinder() == thread.asBinder()) {
5441            boolean doLowMem = app.instr == null;
5442            boolean doOomAdj = doLowMem;
5443            if (!app.killedByAm) {
5444                Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5445                        + ProcessList.makeOomAdjString(app.setAdj)
5446                        + ProcessList.makeProcStateString(app.setProcState));
5447                mAllowLowerMemLevel = true;
5448            } else {
5449                // Note that we always want to do oom adj to update our state with the
5450                // new number of procs.
5451                mAllowLowerMemLevel = false;
5452                doLowMem = false;
5453            }
5454            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5455                    app.setAdj, app.setProcState);
5456            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5457                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5458            handleAppDiedLocked(app, false, true);
5459
5460            if (doOomAdj) {
5461                updateOomAdjLocked();
5462            }
5463            if (doLowMem) {
5464                doLowMemReportIfNeededLocked(app);
5465            }
5466        } else if (app.pid != pid) {
5467            // A new process has already been started.
5468            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5469                    + ") has died and restarted (pid " + app.pid + ").");
5470            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5471        } else if (DEBUG_PROCESSES) {
5472            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5473                    + thread.asBinder());
5474        }
5475    }
5476
5477    /**
5478     * If a stack trace dump file is configured, dump process stack traces.
5479     * @param clearTraces causes the dump file to be erased prior to the new
5480     *    traces being written, if true; when false, the new traces will be
5481     *    appended to any existing file content.
5482     * @param firstPids of dalvik VM processes to dump stack traces for first
5483     * @param lastPids of dalvik VM processes to dump stack traces for last
5484     * @param nativePids optional list of native pids to dump stack crawls
5485     */
5486    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5487            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5488            ArrayList<Integer> nativePids) {
5489        ArrayList<Integer> extraPids = null;
5490
5491        // Measure CPU usage as soon as we're called in order to get a realistic sampling
5492        // of the top users at the time of the request.
5493        if (processCpuTracker != null) {
5494            processCpuTracker.init();
5495            try {
5496                Thread.sleep(200);
5497            } catch (InterruptedException ignored) {
5498            }
5499
5500            processCpuTracker.update();
5501
5502            // We'll take the stack crawls of just the top apps using CPU.
5503            final int N = processCpuTracker.countWorkingStats();
5504            extraPids = new ArrayList<>();
5505            for (int i = 0; i < N && extraPids.size() < 5; i++) {
5506                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5507                if (lastPids.indexOfKey(stats.pid) >= 0) {
5508                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5509
5510                    extraPids.add(stats.pid);
5511                } else if (DEBUG_ANR) {
5512                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5513                            + stats.pid);
5514                }
5515            }
5516        }
5517
5518        boolean useTombstonedForJavaTraces = false;
5519        File tracesFile;
5520
5521        final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5522        if (tracesDirProp.isEmpty()) {
5523            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5524            // dumping scheme. All traces are written to a global trace file (usually
5525            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5526            // the file if requested.
5527            //
5528            // This mode of operation will be removed in the near future.
5529
5530
5531            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5532            if (globalTracesPath.isEmpty()) {
5533                Slog.w(TAG, "dumpStackTraces: no trace path configured");
5534                return null;
5535            }
5536
5537            tracesFile = new File(globalTracesPath);
5538            try {
5539                if (clearTraces && tracesFile.exists()) {
5540                    tracesFile.delete();
5541                }
5542
5543                tracesFile.createNewFile();
5544                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5545            } catch (IOException e) {
5546                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5547                return null;
5548            }
5549        } else {
5550            File tracesDir = new File(tracesDirProp);
5551            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5552            // Each set of ANR traces is written to a separate file and dumpstate will process
5553            // all such files and add them to a captured bug report if they're recent enough.
5554            maybePruneOldTraces(tracesDir);
5555
5556            // NOTE: We should consider creating the file in native code atomically once we've
5557            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5558            // can be removed.
5559            tracesFile = createAnrDumpFile(tracesDir);
5560            if (tracesFile == null) {
5561                return null;
5562            }
5563
5564            useTombstonedForJavaTraces = true;
5565        }
5566
5567        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5568                useTombstonedForJavaTraces);
5569        return tracesFile;
5570    }
5571
5572    @GuardedBy("ActivityManagerService.class")
5573    private static SimpleDateFormat sAnrFileDateFormat;
5574
5575    private static synchronized File createAnrDumpFile(File tracesDir) {
5576        if (sAnrFileDateFormat == null) {
5577            sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5578        }
5579
5580        final String formattedDate = sAnrFileDateFormat.format(new Date());
5581        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5582
5583        try {
5584            if (anrFile.createNewFile()) {
5585                FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5586                return anrFile;
5587            } else {
5588                Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5589            }
5590        } catch (IOException ioe) {
5591            Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5592        }
5593
5594        return null;
5595    }
5596
5597    /**
5598     * Prune all trace files that are more than a day old.
5599     *
5600     * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5601     * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5602     * since it's the system_server that creates trace files for most ANRs.
5603     */
5604    private static void maybePruneOldTraces(File tracesDir) {
5605        final long now = System.currentTimeMillis();
5606        final File[] traceFiles = tracesDir.listFiles();
5607
5608        if (traceFiles != null) {
5609            for (File file : traceFiles) {
5610                if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
5611                    if (!file.delete()) {
5612                        Slog.w(TAG, "Unable to prune stale trace file: " + file);
5613                    }
5614                }
5615            }
5616        }
5617    }
5618
5619    /**
5620     * Legacy code, do not use. Existing users will be deleted.
5621     *
5622     * @deprecated
5623     */
5624    @Deprecated
5625    public static class DumpStackFileObserver extends FileObserver {
5626        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5627        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5628
5629        private final String mTracesPath;
5630        private boolean mClosed;
5631
5632        public DumpStackFileObserver(String tracesPath) {
5633            super(tracesPath, FileObserver.CLOSE_WRITE);
5634            mTracesPath = tracesPath;
5635        }
5636
5637        @Override
5638        public synchronized void onEvent(int event, String path) {
5639            mClosed = true;
5640            notify();
5641        }
5642
5643        public long dumpWithTimeout(int pid, long timeout) {
5644            sendSignal(pid, SIGNAL_QUIT);
5645            final long start = SystemClock.elapsedRealtime();
5646
5647            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5648            synchronized (this) {
5649                try {
5650                    wait(waitTime); // Wait for traces file to be closed.
5651                } catch (InterruptedException e) {
5652                    Slog.wtf(TAG, e);
5653                }
5654            }
5655
5656            // This avoids a corner case of passing a negative time to the native
5657            // trace in case we've already hit the overall timeout.
5658            final long timeWaited = SystemClock.elapsedRealtime() - start;
5659            if (timeWaited >= timeout) {
5660                return timeWaited;
5661            }
5662
5663            if (!mClosed) {
5664                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5665                       ". Attempting native stack collection.");
5666
5667                final long nativeDumpTimeoutMs = Math.min(
5668                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5669
5670                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5671                        (int) (nativeDumpTimeoutMs / 1000));
5672            }
5673
5674            final long end = SystemClock.elapsedRealtime();
5675            mClosed = false;
5676
5677            return (end - start);
5678        }
5679    }
5680
5681    /**
5682     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5683     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5684     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5685     * attempting to obtain native traces in the case of a failure. Returns the total time spent
5686     * capturing traces.
5687     */
5688    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5689        final long timeStart = SystemClock.elapsedRealtime();
5690        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5691            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5692                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
5693        }
5694
5695        return SystemClock.elapsedRealtime() - timeStart;
5696    }
5697
5698    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5699            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5700            boolean useTombstonedForJavaTraces) {
5701
5702        // We don't need any sort of inotify based monitoring when we're dumping traces via
5703        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5704        // control of all writes to the file in question.
5705        final DumpStackFileObserver observer;
5706        if (useTombstonedForJavaTraces) {
5707            observer = null;
5708        } else {
5709            // Use a FileObserver to detect when traces finish writing.
5710            // The order of traces is considered important to maintain for legibility.
5711            observer = new DumpStackFileObserver(tracesFile);
5712        }
5713
5714        // We must complete all stack dumps within 20 seconds.
5715        long remainingTime = 20 * 1000;
5716        try {
5717            if (observer != null) {
5718                observer.startWatching();
5719            }
5720
5721            // First collect all of the stacks of the most important pids.
5722            if (firstPids != null) {
5723                int num = firstPids.size();
5724                for (int i = 0; i < num; i++) {
5725                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5726                            + firstPids.get(i));
5727                    final long timeTaken;
5728                    if (useTombstonedForJavaTraces) {
5729                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5730                    } else {
5731                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5732                    }
5733
5734                    remainingTime -= timeTaken;
5735                    if (remainingTime <= 0) {
5736                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5737                            "); deadline exceeded.");
5738                        return;
5739                    }
5740
5741                    if (DEBUG_ANR) {
5742                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5743                    }
5744                }
5745            }
5746
5747            // Next collect the stacks of the native pids
5748            if (nativePids != null) {
5749                for (int pid : nativePids) {
5750                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5751                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5752
5753                    final long start = SystemClock.elapsedRealtime();
5754                    Debug.dumpNativeBacktraceToFileTimeout(
5755                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5756                    final long timeTaken = SystemClock.elapsedRealtime() - start;
5757
5758                    remainingTime -= timeTaken;
5759                    if (remainingTime <= 0) {
5760                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5761                            "); deadline exceeded.");
5762                        return;
5763                    }
5764
5765                    if (DEBUG_ANR) {
5766                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5767                    }
5768                }
5769            }
5770
5771            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5772            if (extraPids != null) {
5773                for (int pid : extraPids) {
5774                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5775
5776                    final long timeTaken;
5777                    if (useTombstonedForJavaTraces) {
5778                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5779                    } else {
5780                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5781                    }
5782
5783                    remainingTime -= timeTaken;
5784                    if (remainingTime <= 0) {
5785                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5786                                "); deadline exceeded.");
5787                        return;
5788                    }
5789
5790                    if (DEBUG_ANR) {
5791                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5792                    }
5793                }
5794            }
5795        } finally {
5796            if (observer != null) {
5797                observer.stopWatching();
5798            }
5799        }
5800    }
5801
5802    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5803        if (true || Build.IS_USER) {
5804            return;
5805        }
5806        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5807        if (tracesPath == null || tracesPath.length() == 0) {
5808            return;
5809        }
5810
5811        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5812        StrictMode.allowThreadDiskWrites();
5813        try {
5814            final File tracesFile = new File(tracesPath);
5815            final File tracesDir = tracesFile.getParentFile();
5816            final File tracesTmp = new File(tracesDir, "__tmp__");
5817            try {
5818                if (tracesFile.exists()) {
5819                    tracesTmp.delete();
5820                    tracesFile.renameTo(tracesTmp);
5821                }
5822                StringBuilder sb = new StringBuilder();
5823                Time tobj = new Time();
5824                tobj.set(System.currentTimeMillis());
5825                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5826                sb.append(": ");
5827                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5828                sb.append(" since ");
5829                sb.append(msg);
5830                FileOutputStream fos = new FileOutputStream(tracesFile);
5831                fos.write(sb.toString().getBytes());
5832                if (app == null) {
5833                    fos.write("\n*** No application process!".getBytes());
5834                }
5835                fos.close();
5836                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5837            } catch (IOException e) {
5838                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5839                return;
5840            }
5841
5842            if (app != null) {
5843                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5844                firstPids.add(app.pid);
5845                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5846            }
5847
5848            File lastTracesFile = null;
5849            File curTracesFile = null;
5850            for (int i=9; i>=0; i--) {
5851                String name = String.format(Locale.US, "slow%02d.txt", i);
5852                curTracesFile = new File(tracesDir, name);
5853                if (curTracesFile.exists()) {
5854                    if (lastTracesFile != null) {
5855                        curTracesFile.renameTo(lastTracesFile);
5856                    } else {
5857                        curTracesFile.delete();
5858                    }
5859                }
5860                lastTracesFile = curTracesFile;
5861            }
5862            tracesFile.renameTo(curTracesFile);
5863            if (tracesTmp.exists()) {
5864                tracesTmp.renameTo(tracesFile);
5865            }
5866        } finally {
5867            StrictMode.setThreadPolicy(oldPolicy);
5868        }
5869    }
5870
5871    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5872        if (!mLaunchWarningShown) {
5873            mLaunchWarningShown = true;
5874            mUiHandler.post(new Runnable() {
5875                @Override
5876                public void run() {
5877                    synchronized (ActivityManagerService.this) {
5878                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5879                        d.show();
5880                        mUiHandler.postDelayed(new Runnable() {
5881                            @Override
5882                            public void run() {
5883                                synchronized (ActivityManagerService.this) {
5884                                    d.dismiss();
5885                                    mLaunchWarningShown = false;
5886                                }
5887                            }
5888                        }, 4000);
5889                    }
5890                }
5891            });
5892        }
5893    }
5894
5895    @Override
5896    public boolean clearApplicationUserData(final String packageName,
5897            final IPackageDataObserver observer, int userId) {
5898        enforceNotIsolatedCaller("clearApplicationUserData");
5899        int uid = Binder.getCallingUid();
5900        int pid = Binder.getCallingPid();
5901        final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5902                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5903
5904        final ApplicationInfo appInfo;
5905        final boolean isInstantApp;
5906
5907        long callingId = Binder.clearCallingIdentity();
5908        try {
5909            IPackageManager pm = AppGlobals.getPackageManager();
5910            synchronized(this) {
5911                // Instant packages are not protected
5912                if (getPackageManagerInternalLocked().isPackageDataProtected(
5913                        resolvedUserId, packageName)) {
5914                    throw new SecurityException(
5915                            "Cannot clear data for a protected package: " + packageName);
5916                }
5917
5918                ApplicationInfo applicationInfo = null;
5919                try {
5920                    applicationInfo = pm.getApplicationInfo(packageName,
5921                            MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5922                } catch (RemoteException e) {
5923                    /* ignore */
5924                }
5925                appInfo = applicationInfo;
5926
5927                final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5928
5929                if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5930                        pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5931                    throw new SecurityException("PID " + pid + " does not have permission "
5932                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5933                            + " of package " + packageName);
5934                }
5935
5936                final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5937                        .hasInstantApplicationMetadata(packageName, resolvedUserId);
5938                final boolean isUninstalledAppWithoutInstantMetadata =
5939                        (appInfo == null && !hasInstantMetadata);
5940                isInstantApp = (appInfo != null && appInfo.isInstantApp())
5941                        || hasInstantMetadata;
5942                final boolean canAccessInstantApps = checkComponentPermission(
5943                        permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5944                        == PackageManager.PERMISSION_GRANTED;
5945
5946                if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5947                        && !canAccessInstantApps)) {
5948                    Slog.w(TAG, "Invalid packageName: " + packageName);
5949                    if (observer != null) {
5950                        try {
5951                            observer.onRemoveCompleted(packageName, false);
5952                        } catch (RemoteException e) {
5953                            Slog.i(TAG, "Observer no longer exists.");
5954                        }
5955                    }
5956                    return false;
5957                }
5958
5959                if (appInfo != null) {
5960                    forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5961                    mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
5962                }
5963            }
5964
5965            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5966                @Override
5967                public void onRemoveCompleted(String packageName, boolean succeeded)
5968                        throws RemoteException {
5969                    if (appInfo != null) {
5970                        synchronized (ActivityManagerService.this) {
5971                            finishForceStopPackageLocked(packageName, appInfo.uid);
5972                        }
5973                    }
5974                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5975                            Uri.fromParts("package", packageName, null));
5976                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5977                    intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
5978                    intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
5979                    if (isInstantApp) {
5980                        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
5981                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5982                                null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
5983                                resolvedUserId);
5984                    } else {
5985                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5986                                null, null, null, null, false, false, resolvedUserId);
5987                    }
5988
5989                    if (observer != null) {
5990                        observer.onRemoveCompleted(packageName, succeeded);
5991                    }
5992                }
5993            };
5994
5995            try {
5996                // Clear application user data
5997                pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
5998
5999                if (appInfo != null) {
6000                    synchronized (this) {
6001                        // Remove all permissions granted from/to this package
6002                        removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6003                    }
6004
6005                    // Reset notification settings.
6006                    INotificationManager inm = NotificationManager.getService();
6007                    inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6008                }
6009            } catch (RemoteException e) {
6010            }
6011        } finally {
6012            Binder.restoreCallingIdentity(callingId);
6013        }
6014        return true;
6015    }
6016
6017    @Override
6018    public void killBackgroundProcesses(final String packageName, int userId) {
6019        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6020                != PackageManager.PERMISSION_GRANTED &&
6021                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6022                        != PackageManager.PERMISSION_GRANTED) {
6023            String msg = "Permission Denial: killBackgroundProcesses() from pid="
6024                    + Binder.getCallingPid()
6025                    + ", uid=" + Binder.getCallingUid()
6026                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6027            Slog.w(TAG, msg);
6028            throw new SecurityException(msg);
6029        }
6030
6031        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6032                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6033        long callingId = Binder.clearCallingIdentity();
6034        try {
6035            IPackageManager pm = AppGlobals.getPackageManager();
6036            synchronized(this) {
6037                int appId = -1;
6038                try {
6039                    appId = UserHandle.getAppId(
6040                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6041                } catch (RemoteException e) {
6042                }
6043                if (appId == -1) {
6044                    Slog.w(TAG, "Invalid packageName: " + packageName);
6045                    return;
6046                }
6047                killPackageProcessesLocked(packageName, appId, userId,
6048                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6049            }
6050        } finally {
6051            Binder.restoreCallingIdentity(callingId);
6052        }
6053    }
6054
6055    @Override
6056    public void killAllBackgroundProcesses() {
6057        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6058                != PackageManager.PERMISSION_GRANTED) {
6059            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6060                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6061                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6062            Slog.w(TAG, msg);
6063            throw new SecurityException(msg);
6064        }
6065
6066        final long callingId = Binder.clearCallingIdentity();
6067        try {
6068            synchronized (this) {
6069                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6070                final int NP = mProcessNames.getMap().size();
6071                for (int ip = 0; ip < NP; ip++) {
6072                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6073                    final int NA = apps.size();
6074                    for (int ia = 0; ia < NA; ia++) {
6075                        final ProcessRecord app = apps.valueAt(ia);
6076                        if (app.persistent) {
6077                            // We don't kill persistent processes.
6078                            continue;
6079                        }
6080                        if (app.removed) {
6081                            procs.add(app);
6082                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6083                            app.removed = true;
6084                            procs.add(app);
6085                        }
6086                    }
6087                }
6088
6089                final int N = procs.size();
6090                for (int i = 0; i < N; i++) {
6091                    removeProcessLocked(procs.get(i), false, true, "kill all background");
6092                }
6093
6094                mAllowLowerMemLevel = true;
6095
6096                updateOomAdjLocked();
6097                doLowMemReportIfNeededLocked(null);
6098            }
6099        } finally {
6100            Binder.restoreCallingIdentity(callingId);
6101        }
6102    }
6103
6104    /**
6105     * Kills all background processes, except those matching any of the
6106     * specified properties.
6107     *
6108     * @param minTargetSdk the target SDK version at or above which to preserve
6109     *                     processes, or {@code -1} to ignore the target SDK
6110     * @param maxProcState the process state at or below which to preserve
6111     *                     processes, or {@code -1} to ignore the process state
6112     */
6113    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6114        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6115                != PackageManager.PERMISSION_GRANTED) {
6116            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6117                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6118                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6119            Slog.w(TAG, msg);
6120            throw new SecurityException(msg);
6121        }
6122
6123        final long callingId = Binder.clearCallingIdentity();
6124        try {
6125            synchronized (this) {
6126                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6127                final int NP = mProcessNames.getMap().size();
6128                for (int ip = 0; ip < NP; ip++) {
6129                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6130                    final int NA = apps.size();
6131                    for (int ia = 0; ia < NA; ia++) {
6132                        final ProcessRecord app = apps.valueAt(ia);
6133                        if (app.removed) {
6134                            procs.add(app);
6135                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6136                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
6137                            app.removed = true;
6138                            procs.add(app);
6139                        }
6140                    }
6141                }
6142
6143                final int N = procs.size();
6144                for (int i = 0; i < N; i++) {
6145                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
6146                }
6147            }
6148        } finally {
6149            Binder.restoreCallingIdentity(callingId);
6150        }
6151    }
6152
6153    @Override
6154    public void forceStopPackage(final String packageName, int userId) {
6155        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6156                != PackageManager.PERMISSION_GRANTED) {
6157            String msg = "Permission Denial: forceStopPackage() from pid="
6158                    + Binder.getCallingPid()
6159                    + ", uid=" + Binder.getCallingUid()
6160                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6161            Slog.w(TAG, msg);
6162            throw new SecurityException(msg);
6163        }
6164        final int callingPid = Binder.getCallingPid();
6165        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6166                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6167        long callingId = Binder.clearCallingIdentity();
6168        try {
6169            IPackageManager pm = AppGlobals.getPackageManager();
6170            synchronized(this) {
6171                int[] users = userId == UserHandle.USER_ALL
6172                        ? mUserController.getUsers() : new int[] { userId };
6173                for (int user : users) {
6174                    int pkgUid = -1;
6175                    try {
6176                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6177                                user);
6178                    } catch (RemoteException e) {
6179                    }
6180                    if (pkgUid == -1) {
6181                        Slog.w(TAG, "Invalid packageName: " + packageName);
6182                        continue;
6183                    }
6184                    try {
6185                        pm.setPackageStoppedState(packageName, true, user);
6186                    } catch (RemoteException e) {
6187                    } catch (IllegalArgumentException e) {
6188                        Slog.w(TAG, "Failed trying to unstop package "
6189                                + packageName + ": " + e);
6190                    }
6191                    if (mUserController.isUserRunning(user, 0)) {
6192                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6193                        finishForceStopPackageLocked(packageName, pkgUid);
6194                    }
6195                }
6196            }
6197        } finally {
6198            Binder.restoreCallingIdentity(callingId);
6199        }
6200    }
6201
6202    @Override
6203    public void addPackageDependency(String packageName) {
6204        synchronized (this) {
6205            int callingPid = Binder.getCallingPid();
6206            if (callingPid == myPid()) {
6207                //  Yeah, um, no.
6208                return;
6209            }
6210            ProcessRecord proc;
6211            synchronized (mPidsSelfLocked) {
6212                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6213            }
6214            if (proc != null) {
6215                if (proc.pkgDeps == null) {
6216                    proc.pkgDeps = new ArraySet<String>(1);
6217                }
6218                proc.pkgDeps.add(packageName);
6219            }
6220        }
6221    }
6222
6223    /*
6224     * The pkg name and app id have to be specified.
6225     */
6226    @Override
6227    public void killApplication(String pkg, int appId, int userId, String reason) {
6228        if (pkg == null) {
6229            return;
6230        }
6231        // Make sure the uid is valid.
6232        if (appId < 0) {
6233            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6234            return;
6235        }
6236        int callerUid = Binder.getCallingUid();
6237        // Only the system server can kill an application
6238        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6239            // Post an aysnc message to kill the application
6240            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6241            msg.arg1 = appId;
6242            msg.arg2 = userId;
6243            Bundle bundle = new Bundle();
6244            bundle.putString("pkg", pkg);
6245            bundle.putString("reason", reason);
6246            msg.obj = bundle;
6247            mHandler.sendMessage(msg);
6248        } else {
6249            throw new SecurityException(callerUid + " cannot kill pkg: " +
6250                    pkg);
6251        }
6252    }
6253
6254    @Override
6255    public void closeSystemDialogs(String reason) {
6256        enforceNotIsolatedCaller("closeSystemDialogs");
6257
6258        final int pid = Binder.getCallingPid();
6259        final int uid = Binder.getCallingUid();
6260        final long origId = Binder.clearCallingIdentity();
6261        try {
6262            synchronized (this) {
6263                // Only allow this from foreground processes, so that background
6264                // applications can't abuse it to prevent system UI from being shown.
6265                if (uid >= FIRST_APPLICATION_UID) {
6266                    ProcessRecord proc;
6267                    synchronized (mPidsSelfLocked) {
6268                        proc = mPidsSelfLocked.get(pid);
6269                    }
6270                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6271                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6272                                + " from background process " + proc);
6273                        return;
6274                    }
6275                }
6276                closeSystemDialogsLocked(reason);
6277            }
6278        } finally {
6279            Binder.restoreCallingIdentity(origId);
6280        }
6281    }
6282
6283    void closeSystemDialogsLocked(String reason) {
6284        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6285        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6286                | Intent.FLAG_RECEIVER_FOREGROUND);
6287        if (reason != null) {
6288            intent.putExtra("reason", reason);
6289        }
6290        mWindowManager.closeSystemDialogs(reason);
6291
6292        mStackSupervisor.closeSystemDialogsLocked();
6293
6294        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6295                AppOpsManager.OP_NONE, null, false, false,
6296                -1, SYSTEM_UID, UserHandle.USER_ALL);
6297    }
6298
6299    @Override
6300    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6301        enforceNotIsolatedCaller("getProcessMemoryInfo");
6302        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6303        for (int i=pids.length-1; i>=0; i--) {
6304            ProcessRecord proc;
6305            int oomAdj;
6306            synchronized (this) {
6307                synchronized (mPidsSelfLocked) {
6308                    proc = mPidsSelfLocked.get(pids[i]);
6309                    oomAdj = proc != null ? proc.setAdj : 0;
6310                }
6311            }
6312            infos[i] = new Debug.MemoryInfo();
6313            Debug.getMemoryInfo(pids[i], infos[i]);
6314            if (proc != null) {
6315                synchronized (this) {
6316                    if (proc.thread != null && proc.setAdj == oomAdj) {
6317                        // Record this for posterity if the process has been stable.
6318                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6319                                infos[i].getTotalUss(), false, proc.pkgList);
6320                    }
6321                }
6322            }
6323        }
6324        return infos;
6325    }
6326
6327    @Override
6328    public long[] getProcessPss(int[] pids) {
6329        enforceNotIsolatedCaller("getProcessPss");
6330        long[] pss = new long[pids.length];
6331        for (int i=pids.length-1; i>=0; i--) {
6332            ProcessRecord proc;
6333            int oomAdj;
6334            synchronized (this) {
6335                synchronized (mPidsSelfLocked) {
6336                    proc = mPidsSelfLocked.get(pids[i]);
6337                    oomAdj = proc != null ? proc.setAdj : 0;
6338                }
6339            }
6340            long[] tmpUss = new long[1];
6341            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6342            if (proc != null) {
6343                synchronized (this) {
6344                    if (proc.thread != null && proc.setAdj == oomAdj) {
6345                        // Record this for posterity if the process has been stable.
6346                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6347                    }
6348                }
6349            }
6350        }
6351        return pss;
6352    }
6353
6354    @Override
6355    public void killApplicationProcess(String processName, int uid) {
6356        if (processName == null) {
6357            return;
6358        }
6359
6360        int callerUid = Binder.getCallingUid();
6361        // Only the system server can kill an application
6362        if (callerUid == SYSTEM_UID) {
6363            synchronized (this) {
6364                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6365                if (app != null && app.thread != null) {
6366                    try {
6367                        app.thread.scheduleSuicide();
6368                    } catch (RemoteException e) {
6369                        // If the other end already died, then our work here is done.
6370                    }
6371                } else {
6372                    Slog.w(TAG, "Process/uid not found attempting kill of "
6373                            + processName + " / " + uid);
6374                }
6375            }
6376        } else {
6377            throw new SecurityException(callerUid + " cannot kill app process: " +
6378                    processName);
6379        }
6380    }
6381
6382    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6383        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6384                false, true, false, false, UserHandle.getUserId(uid), reason);
6385    }
6386
6387    private void finishForceStopPackageLocked(final String packageName, int uid) {
6388        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6389                Uri.fromParts("package", packageName, null));
6390        if (!mProcessesReady) {
6391            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6392                    | Intent.FLAG_RECEIVER_FOREGROUND);
6393        }
6394        intent.putExtra(Intent.EXTRA_UID, uid);
6395        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6396        broadcastIntentLocked(null, null, intent,
6397                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6398                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6399    }
6400
6401
6402    private final boolean killPackageProcessesLocked(String packageName, int appId,
6403            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6404            boolean doit, boolean evenPersistent, String reason) {
6405        ArrayList<ProcessRecord> procs = new ArrayList<>();
6406
6407        // Remove all processes this package may have touched: all with the
6408        // same UID (except for the system or root user), and all whose name
6409        // matches the package name.
6410        final int NP = mProcessNames.getMap().size();
6411        for (int ip=0; ip<NP; ip++) {
6412            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6413            final int NA = apps.size();
6414            for (int ia=0; ia<NA; ia++) {
6415                ProcessRecord app = apps.valueAt(ia);
6416                if (app.persistent && !evenPersistent) {
6417                    // we don't kill persistent processes
6418                    continue;
6419                }
6420                if (app.removed) {
6421                    if (doit) {
6422                        procs.add(app);
6423                    }
6424                    continue;
6425                }
6426
6427                // Skip process if it doesn't meet our oom adj requirement.
6428                if (app.setAdj < minOomAdj) {
6429                    continue;
6430                }
6431
6432                // If no package is specified, we call all processes under the
6433                // give user id.
6434                if (packageName == null) {
6435                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6436                        continue;
6437                    }
6438                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6439                        continue;
6440                    }
6441                // Package has been specified, we want to hit all processes
6442                // that match it.  We need to qualify this by the processes
6443                // that are running under the specified app and user ID.
6444                } else {
6445                    final boolean isDep = app.pkgDeps != null
6446                            && app.pkgDeps.contains(packageName);
6447                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6448                        continue;
6449                    }
6450                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6451                        continue;
6452                    }
6453                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6454                        continue;
6455                    }
6456                }
6457
6458                // Process has passed all conditions, kill it!
6459                if (!doit) {
6460                    return true;
6461                }
6462                app.removed = true;
6463                procs.add(app);
6464            }
6465        }
6466
6467        int N = procs.size();
6468        for (int i=0; i<N; i++) {
6469            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6470        }
6471        updateOomAdjLocked();
6472        return N > 0;
6473    }
6474
6475    private void cleanupDisabledPackageComponentsLocked(
6476            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6477
6478        Set<String> disabledClasses = null;
6479        boolean packageDisabled = false;
6480        IPackageManager pm = AppGlobals.getPackageManager();
6481
6482        if (changedClasses == null) {
6483            // Nothing changed...
6484            return;
6485        }
6486
6487        // Determine enable/disable state of the package and its components.
6488        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6489        for (int i = changedClasses.length - 1; i >= 0; i--) {
6490            final String changedClass = changedClasses[i];
6491
6492            if (changedClass.equals(packageName)) {
6493                try {
6494                    // Entire package setting changed
6495                    enabled = pm.getApplicationEnabledSetting(packageName,
6496                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6497                } catch (Exception e) {
6498                    // No such package/component; probably racing with uninstall.  In any
6499                    // event it means we have nothing further to do here.
6500                    return;
6501                }
6502                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6503                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6504                if (packageDisabled) {
6505                    // Entire package is disabled.
6506                    // No need to continue to check component states.
6507                    disabledClasses = null;
6508                    break;
6509                }
6510            } else {
6511                try {
6512                    enabled = pm.getComponentEnabledSetting(
6513                            new ComponentName(packageName, changedClass),
6514                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6515                } catch (Exception e) {
6516                    // As above, probably racing with uninstall.
6517                    return;
6518                }
6519                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6520                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6521                    if (disabledClasses == null) {
6522                        disabledClasses = new ArraySet<>(changedClasses.length);
6523                    }
6524                    disabledClasses.add(changedClass);
6525                }
6526            }
6527        }
6528
6529        if (!packageDisabled && disabledClasses == null) {
6530            // Nothing to do here...
6531            return;
6532        }
6533
6534        // Clean-up disabled activities.
6535        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6536                packageName, disabledClasses, true, false, userId) && mBooted) {
6537            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6538            mStackSupervisor.scheduleIdleLocked();
6539        }
6540
6541        // Clean-up disabled tasks
6542        mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6543
6544        // Clean-up disabled services.
6545        mServices.bringDownDisabledPackageServicesLocked(
6546                packageName, disabledClasses, userId, false, killProcess, true);
6547
6548        // Clean-up disabled providers.
6549        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6550        mProviderMap.collectPackageProvidersLocked(
6551                packageName, disabledClasses, true, false, userId, providers);
6552        for (int i = providers.size() - 1; i >= 0; i--) {
6553            removeDyingProviderLocked(null, providers.get(i), true);
6554        }
6555
6556        // Clean-up disabled broadcast receivers.
6557        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6558            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6559                    packageName, disabledClasses, userId, true);
6560        }
6561
6562    }
6563
6564    final boolean clearBroadcastQueueForUserLocked(int userId) {
6565        boolean didSomething = false;
6566        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6567            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6568                    null, null, userId, true);
6569        }
6570        return didSomething;
6571    }
6572
6573    final boolean forceStopPackageLocked(String packageName, int appId,
6574            boolean callerWillRestart, boolean purgeCache, boolean doit,
6575            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6576        int i;
6577
6578        if (userId == UserHandle.USER_ALL && packageName == null) {
6579            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6580        }
6581
6582        if (appId < 0 && packageName != null) {
6583            try {
6584                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6585                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6586            } catch (RemoteException e) {
6587            }
6588        }
6589
6590        if (doit) {
6591            if (packageName != null) {
6592                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6593                        + " user=" + userId + ": " + reason);
6594            } else {
6595                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6596            }
6597
6598            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6599        }
6600
6601        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6602                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6603                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6604
6605        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6606
6607        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6608                packageName, null, doit, evenPersistent, userId)) {
6609            if (!doit) {
6610                return true;
6611            }
6612            didSomething = true;
6613        }
6614
6615        if (mServices.bringDownDisabledPackageServicesLocked(
6616                packageName, null, userId, evenPersistent, true, doit)) {
6617            if (!doit) {
6618                return true;
6619            }
6620            didSomething = true;
6621        }
6622
6623        if (packageName == null) {
6624            // Remove all sticky broadcasts from this user.
6625            mStickyBroadcasts.remove(userId);
6626        }
6627
6628        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6629        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6630                userId, providers)) {
6631            if (!doit) {
6632                return true;
6633            }
6634            didSomething = true;
6635        }
6636        for (i = providers.size() - 1; i >= 0; i--) {
6637            removeDyingProviderLocked(null, providers.get(i), true);
6638        }
6639
6640        // Remove transient permissions granted from/to this package/user
6641        removeUriPermissionsForPackageLocked(packageName, userId, false);
6642
6643        if (doit) {
6644            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6645                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6646                        packageName, null, userId, doit);
6647            }
6648        }
6649
6650        if (packageName == null || uninstalling) {
6651            // Remove pending intents.  For now we only do this when force
6652            // stopping users, because we have some problems when doing this
6653            // for packages -- app widgets are not currently cleaned up for
6654            // such packages, so they can be left with bad pending intents.
6655            if (mIntentSenderRecords.size() > 0) {
6656                Iterator<WeakReference<PendingIntentRecord>> it
6657                        = mIntentSenderRecords.values().iterator();
6658                while (it.hasNext()) {
6659                    WeakReference<PendingIntentRecord> wpir = it.next();
6660                    if (wpir == null) {
6661                        it.remove();
6662                        continue;
6663                    }
6664                    PendingIntentRecord pir = wpir.get();
6665                    if (pir == null) {
6666                        it.remove();
6667                        continue;
6668                    }
6669                    if (packageName == null) {
6670                        // Stopping user, remove all objects for the user.
6671                        if (pir.key.userId != userId) {
6672                            // Not the same user, skip it.
6673                            continue;
6674                        }
6675                    } else {
6676                        if (UserHandle.getAppId(pir.uid) != appId) {
6677                            // Different app id, skip it.
6678                            continue;
6679                        }
6680                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6681                            // Different user, skip it.
6682                            continue;
6683                        }
6684                        if (!pir.key.packageName.equals(packageName)) {
6685                            // Different package, skip it.
6686                            continue;
6687                        }
6688                    }
6689                    if (!doit) {
6690                        return true;
6691                    }
6692                    didSomething = true;
6693                    it.remove();
6694                    makeIntentSenderCanceledLocked(pir);
6695                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6696                        pir.key.activity.pendingResults.remove(pir.ref);
6697                    }
6698                }
6699            }
6700        }
6701
6702        if (doit) {
6703            if (purgeCache && packageName != null) {
6704                AttributeCache ac = AttributeCache.instance();
6705                if (ac != null) {
6706                    ac.removePackage(packageName);
6707                }
6708            }
6709            if (mBooted) {
6710                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6711                mStackSupervisor.scheduleIdleLocked();
6712            }
6713        }
6714
6715        return didSomething;
6716    }
6717
6718    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6719        return removeProcessNameLocked(name, uid, null);
6720    }
6721
6722    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6723            final ProcessRecord expecting) {
6724        ProcessRecord old = mProcessNames.get(name, uid);
6725        // Only actually remove when the currently recorded value matches the
6726        // record that we expected; if it doesn't match then we raced with a
6727        // newly created process and we don't want to destroy the new one.
6728        if ((expecting == null) || (old == expecting)) {
6729            mProcessNames.remove(name, uid);
6730        }
6731        if (old != null && old.uidRecord != null) {
6732            old.uidRecord.numProcs--;
6733            if (old.uidRecord.numProcs == 0) {
6734                // No more processes using this uid, tell clients it is gone.
6735                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6736                        "No more processes in " + old.uidRecord);
6737                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6738                EventLogTags.writeAmUidStopped(uid);
6739                mActiveUids.remove(uid);
6740                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6741            }
6742            old.uidRecord = null;
6743        }
6744        mIsolatedProcesses.remove(uid);
6745        return old;
6746    }
6747
6748    private final void addProcessNameLocked(ProcessRecord proc) {
6749        // We shouldn't already have a process under this name, but just in case we
6750        // need to clean up whatever may be there now.
6751        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6752        if (old == proc && proc.persistent) {
6753            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6754            Slog.w(TAG, "Re-adding persistent process " + proc);
6755        } else if (old != null) {
6756            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6757        }
6758        UidRecord uidRec = mActiveUids.get(proc.uid);
6759        if (uidRec == null) {
6760            uidRec = new UidRecord(proc.uid);
6761            // This is the first appearance of the uid, report it now!
6762            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6763                    "Creating new process uid: " + uidRec);
6764            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6765                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6766                uidRec.setWhitelist = uidRec.curWhitelist = true;
6767            }
6768            uidRec.updateHasInternetPermission();
6769            mActiveUids.put(proc.uid, uidRec);
6770            EventLogTags.writeAmUidRunning(uidRec.uid);
6771            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6772        }
6773        proc.uidRecord = uidRec;
6774
6775        // Reset render thread tid if it was already set, so new process can set it again.
6776        proc.renderThreadTid = 0;
6777        uidRec.numProcs++;
6778        mProcessNames.put(proc.processName, proc.uid, proc);
6779        if (proc.isolated) {
6780            mIsolatedProcesses.put(proc.uid, proc);
6781        }
6782    }
6783
6784    boolean removeProcessLocked(ProcessRecord app,
6785            boolean callerWillRestart, boolean allowRestart, String reason) {
6786        final String name = app.processName;
6787        final int uid = app.uid;
6788        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6789            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6790
6791        ProcessRecord old = mProcessNames.get(name, uid);
6792        if (old != app) {
6793            // This process is no longer active, so nothing to do.
6794            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6795            return false;
6796        }
6797        removeProcessNameLocked(name, uid);
6798        if (mHeavyWeightProcess == app) {
6799            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6800                    mHeavyWeightProcess.userId, 0));
6801            mHeavyWeightProcess = null;
6802        }
6803        boolean needRestart = false;
6804        if (app.pid > 0 && app.pid != MY_PID) {
6805            int pid = app.pid;
6806            synchronized (mPidsSelfLocked) {
6807                mPidsSelfLocked.remove(pid);
6808                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6809            }
6810            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6811            boolean willRestart = false;
6812            if (app.persistent && !app.isolated) {
6813                if (!callerWillRestart) {
6814                    willRestart = true;
6815                } else {
6816                    needRestart = true;
6817                }
6818            }
6819            app.kill(reason, true);
6820            if (app.isolated) {
6821                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6822                getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6823            }
6824            handleAppDiedLocked(app, willRestart, allowRestart);
6825            if (willRestart) {
6826                removeLruProcessLocked(app);
6827                addAppLocked(app.info, null, false, null /* ABI override */);
6828            }
6829        } else {
6830            mRemovedProcesses.add(app);
6831        }
6832
6833        return needRestart;
6834    }
6835
6836    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6837        cleanupAppInLaunchingProvidersLocked(app, true);
6838        removeProcessLocked(app, false, true, "timeout publishing content providers");
6839    }
6840
6841    private final void processStartTimedOutLocked(ProcessRecord app) {
6842        final int pid = app.pid;
6843        boolean gone = false;
6844        synchronized (mPidsSelfLocked) {
6845            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6846            if (knownApp != null && knownApp.thread == null) {
6847                mPidsSelfLocked.remove(pid);
6848                gone = true;
6849            }
6850        }
6851
6852        if (gone) {
6853            Slog.w(TAG, "Process " + app + " failed to attach");
6854            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6855                    pid, app.uid, app.processName);
6856            removeProcessNameLocked(app.processName, app.uid);
6857            if (mHeavyWeightProcess == app) {
6858                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6859                        mHeavyWeightProcess.userId, 0));
6860                mHeavyWeightProcess = null;
6861            }
6862            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6863            // Take care of any launching providers waiting for this process.
6864            cleanupAppInLaunchingProvidersLocked(app, true);
6865            // Take care of any services that are waiting for the process.
6866            mServices.processStartTimedOutLocked(app);
6867            app.kill("start timeout", true);
6868            if (app.isolated) {
6869                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6870            }
6871            removeLruProcessLocked(app);
6872            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6873                Slog.w(TAG, "Unattached app died before backup, skipping");
6874                mHandler.post(new Runnable() {
6875                @Override
6876                    public void run(){
6877                        try {
6878                            IBackupManager bm = IBackupManager.Stub.asInterface(
6879                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6880                            bm.agentDisconnected(app.info.packageName);
6881                        } catch (RemoteException e) {
6882                            // Can't happen; the backup manager is local
6883                        }
6884                    }
6885                });
6886            }
6887            if (isPendingBroadcastProcessLocked(pid)) {
6888                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6889                skipPendingBroadcastLocked(pid);
6890            }
6891        } else {
6892            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6893        }
6894    }
6895
6896    private final boolean attachApplicationLocked(IApplicationThread thread,
6897            int pid) {
6898
6899        // Find the application record that is being attached...  either via
6900        // the pid if we are running in multiple processes, or just pull the
6901        // next app record if we are emulating process with anonymous threads.
6902        ProcessRecord app;
6903        long startTime = SystemClock.uptimeMillis();
6904        if (pid != MY_PID && pid >= 0) {
6905            synchronized (mPidsSelfLocked) {
6906                app = mPidsSelfLocked.get(pid);
6907            }
6908        } else {
6909            app = null;
6910        }
6911
6912        if (app == null) {
6913            Slog.w(TAG, "No pending application record for pid " + pid
6914                    + " (IApplicationThread " + thread + "); dropping process");
6915            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6916            if (pid > 0 && pid != MY_PID) {
6917                killProcessQuiet(pid);
6918                //TODO: killProcessGroup(app.info.uid, pid);
6919            } else {
6920                try {
6921                    thread.scheduleExit();
6922                } catch (Exception e) {
6923                    // Ignore exceptions.
6924                }
6925            }
6926            return false;
6927        }
6928
6929        // If this application record is still attached to a previous
6930        // process, clean it up now.
6931        if (app.thread != null) {
6932            handleAppDiedLocked(app, true, true);
6933        }
6934
6935        // Tell the process all about itself.
6936
6937        if (DEBUG_ALL) Slog.v(
6938                TAG, "Binding process pid " + pid + " to record " + app);
6939
6940        final String processName = app.processName;
6941        try {
6942            AppDeathRecipient adr = new AppDeathRecipient(
6943                    app, pid, thread);
6944            thread.asBinder().linkToDeath(adr, 0);
6945            app.deathRecipient = adr;
6946        } catch (RemoteException e) {
6947            app.resetPackageList(mProcessStats);
6948            startProcessLocked(app, "link fail", processName);
6949            return false;
6950        }
6951
6952        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6953
6954        app.makeActive(thread, mProcessStats);
6955        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6956        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6957        app.forcingToImportant = null;
6958        updateProcessForegroundLocked(app, false, false);
6959        app.hasShownUi = false;
6960        app.debugging = false;
6961        app.cached = false;
6962        app.killedByAm = false;
6963        app.killed = false;
6964
6965
6966        // We carefully use the same state that PackageManager uses for
6967        // filtering, since we use this flag to decide if we need to install
6968        // providers when user is unlocked later
6969        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6970
6971        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6972
6973        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6974        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6975
6976        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6977            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6978            msg.obj = app;
6979            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6980        }
6981
6982        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6983
6984        if (!normalMode) {
6985            Slog.i(TAG, "Launching preboot mode app: " + app);
6986        }
6987
6988        if (DEBUG_ALL) Slog.v(
6989            TAG, "New app record " + app
6990            + " thread=" + thread.asBinder() + " pid=" + pid);
6991        try {
6992            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6993            if (mDebugApp != null && mDebugApp.equals(processName)) {
6994                testMode = mWaitForDebugger
6995                    ? ApplicationThreadConstants.DEBUG_WAIT
6996                    : ApplicationThreadConstants.DEBUG_ON;
6997                app.debugging = true;
6998                if (mDebugTransient) {
6999                    mDebugApp = mOrigDebugApp;
7000                    mWaitForDebugger = mOrigWaitForDebugger;
7001                }
7002            }
7003
7004            ProfilerInfo profilerInfo = null;
7005            String agent = null;
7006            if (mProfileApp != null && mProfileApp.equals(processName)) {
7007                mProfileProc = app;
7008                profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ?
7009                        new ProfilerInfo(mProfilerInfo) : null;
7010                agent = mProfilerInfo != null ? mProfilerInfo.agent : null;
7011            } else if (app.instr != null && app.instr.mProfileFile != null) {
7012                profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7013                        null);
7014            }
7015
7016            boolean enableTrackAllocation = false;
7017            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7018                enableTrackAllocation = true;
7019                mTrackAllocationApp = null;
7020            }
7021
7022            // If the app is being launched for restore or full backup, set it up specially
7023            boolean isRestrictedBackupMode = false;
7024            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7025                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7026                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7027                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7028                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7029            }
7030
7031            if (app.instr != null) {
7032                notifyPackageUse(app.instr.mClass.getPackageName(),
7033                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7034            }
7035            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7036                    + processName + " with config " + getGlobalConfiguration());
7037            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7038            app.compat = compatibilityInfoForPackageLocked(appInfo);
7039
7040            if (profilerInfo != null && profilerInfo.profileFd != null) {
7041                profilerInfo.profileFd = profilerInfo.profileFd.dup();
7042            }
7043
7044            // We deprecated Build.SERIAL and it is not accessible to
7045            // apps that target the v2 security sandbox. Since access to
7046            // the serial is now behind a permission we push down the value.
7047            String buildSerial = appInfo.targetSandboxVersion < 2
7048                    ? sTheRealBuildSerial : Build.UNKNOWN;
7049
7050            // Check if this is a secondary process that should be incorporated into some
7051            // currently active instrumentation.  (Note we do this AFTER all of the profiling
7052            // stuff above because profiling can currently happen only in the primary
7053            // instrumentation process.)
7054            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7055                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7056                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7057                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7058                        if (aInstr.mTargetProcesses.length == 0) {
7059                            // This is the wildcard mode, where every process brought up for
7060                            // the target instrumentation should be included.
7061                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7062                                app.instr = aInstr;
7063                                aInstr.mRunningProcesses.add(app);
7064                            }
7065                        } else {
7066                            for (String proc : aInstr.mTargetProcesses) {
7067                                if (proc.equals(app.processName)) {
7068                                    app.instr = aInstr;
7069                                    aInstr.mRunningProcesses.add(app);
7070                                    break;
7071                                }
7072                            }
7073                        }
7074                    }
7075                }
7076            }
7077
7078            // If we were asked to attach an agent on startup, do so now, before we're binding
7079            // application code.
7080            if (agent != null) {
7081                thread.attachAgent(agent);
7082            }
7083
7084            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7085            mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7086            if (app.isolatedEntryPoint != null) {
7087                // This is an isolated process which should just call an entry point instead of
7088                // being bound to an application.
7089                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
7090            } else if (app.instr != null) {
7091                thread.bindApplication(processName, appInfo, providers,
7092                        app.instr.mClass,
7093                        profilerInfo, app.instr.mArguments,
7094                        app.instr.mWatcher,
7095                        app.instr.mUiAutomationConnection, testMode,
7096                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7097                        isRestrictedBackupMode || !normalMode, app.persistent,
7098                        new Configuration(getGlobalConfiguration()), app.compat,
7099                        getCommonServicesLocked(app.isolated),
7100                        mCoreSettingsObserver.getCoreSettingsLocked(),
7101                        buildSerial);
7102            } else {
7103                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7104                        null, null, null, testMode,
7105                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7106                        isRestrictedBackupMode || !normalMode, app.persistent,
7107                        new Configuration(getGlobalConfiguration()), app.compat,
7108                        getCommonServicesLocked(app.isolated),
7109                        mCoreSettingsObserver.getCoreSettingsLocked(),
7110                        buildSerial);
7111            }
7112
7113            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7114            updateLruProcessLocked(app, false, null);
7115            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7116            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7117        } catch (Exception e) {
7118            // todo: Yikes!  What should we do?  For now we will try to
7119            // start another process, but that could easily get us in
7120            // an infinite loop of restarting processes...
7121            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7122
7123            app.resetPackageList(mProcessStats);
7124            app.unlinkDeathRecipient();
7125            startProcessLocked(app, "bind fail", processName);
7126            return false;
7127        }
7128
7129        // Remove this record from the list of starting applications.
7130        mPersistentStartingProcesses.remove(app);
7131        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7132                "Attach application locked removing on hold: " + app);
7133        mProcessesOnHold.remove(app);
7134
7135        boolean badApp = false;
7136        boolean didSomething = false;
7137
7138        // See if the top visible activity is waiting to run in this process...
7139        if (normalMode) {
7140            try {
7141                if (mStackSupervisor.attachApplicationLocked(app)) {
7142                    didSomething = true;
7143                }
7144            } catch (Exception e) {
7145                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7146                badApp = true;
7147            }
7148        }
7149
7150        // Find any services that should be running in this process...
7151        if (!badApp) {
7152            try {
7153                didSomething |= mServices.attachApplicationLocked(app, processName);
7154                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7155            } catch (Exception e) {
7156                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7157                badApp = true;
7158            }
7159        }
7160
7161        // Check if a next-broadcast receiver is in this process...
7162        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7163            try {
7164                didSomething |= sendPendingBroadcastsLocked(app);
7165                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7166            } catch (Exception e) {
7167                // If the app died trying to launch the receiver we declare it 'bad'
7168                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7169                badApp = true;
7170            }
7171        }
7172
7173        // Check whether the next backup agent is in this process...
7174        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7175            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7176                    "New app is backup target, launching agent for " + app);
7177            notifyPackageUse(mBackupTarget.appInfo.packageName,
7178                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7179            try {
7180                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7181                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7182                        mBackupTarget.backupMode);
7183            } catch (Exception e) {
7184                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7185                badApp = true;
7186            }
7187        }
7188
7189        if (badApp) {
7190            app.kill("error during init", true);
7191            handleAppDiedLocked(app, false, true);
7192            return false;
7193        }
7194
7195        if (!didSomething) {
7196            updateOomAdjLocked();
7197            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7198        }
7199
7200        return true;
7201    }
7202
7203    @Override
7204    public final void attachApplication(IApplicationThread thread) {
7205        synchronized (this) {
7206            int callingPid = Binder.getCallingPid();
7207            final long origId = Binder.clearCallingIdentity();
7208            attachApplicationLocked(thread, callingPid);
7209            Binder.restoreCallingIdentity(origId);
7210        }
7211    }
7212
7213    @Override
7214    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7215        final long origId = Binder.clearCallingIdentity();
7216        synchronized (this) {
7217            ActivityStack stack = ActivityRecord.getStackLocked(token);
7218            if (stack != null) {
7219                ActivityRecord r =
7220                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7221                                false /* processPausingActivities */, config);
7222                if (stopProfiling) {
7223                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
7224                        clearProfilerLocked();
7225                    }
7226                }
7227            }
7228        }
7229        Binder.restoreCallingIdentity(origId);
7230    }
7231
7232    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7233        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7234                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7235    }
7236
7237    void enableScreenAfterBoot() {
7238        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7239                SystemClock.uptimeMillis());
7240        mWindowManager.enableScreenAfterBoot();
7241
7242        synchronized (this) {
7243            updateEventDispatchingLocked();
7244        }
7245    }
7246
7247    @Override
7248    public void showBootMessage(final CharSequence msg, final boolean always) {
7249        if (Binder.getCallingUid() != myUid()) {
7250            throw new SecurityException();
7251        }
7252        mWindowManager.showBootMessage(msg, always);
7253    }
7254
7255    @Override
7256    public void keyguardGoingAway(int flags) {
7257        enforceNotIsolatedCaller("keyguardGoingAway");
7258        final long token = Binder.clearCallingIdentity();
7259        try {
7260            synchronized (this) {
7261                mKeyguardController.keyguardGoingAway(flags);
7262            }
7263        } finally {
7264            Binder.restoreCallingIdentity(token);
7265        }
7266    }
7267
7268    /**
7269     * @return whther the keyguard is currently locked.
7270     */
7271    boolean isKeyguardLocked() {
7272        return mKeyguardController.isKeyguardLocked();
7273    }
7274
7275    final void finishBooting() {
7276        synchronized (this) {
7277            if (!mBootAnimationComplete) {
7278                mCallFinishBooting = true;
7279                return;
7280            }
7281            mCallFinishBooting = false;
7282        }
7283
7284        ArraySet<String> completedIsas = new ArraySet<String>();
7285        for (String abi : Build.SUPPORTED_ABIS) {
7286            zygoteProcess.establishZygoteConnectionForAbi(abi);
7287            final String instructionSet = VMRuntime.getInstructionSet(abi);
7288            if (!completedIsas.contains(instructionSet)) {
7289                try {
7290                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7291                } catch (InstallerException e) {
7292                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7293                            e.getMessage() +")");
7294                }
7295                completedIsas.add(instructionSet);
7296            }
7297        }
7298
7299        IntentFilter pkgFilter = new IntentFilter();
7300        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7301        pkgFilter.addDataScheme("package");
7302        mContext.registerReceiver(new BroadcastReceiver() {
7303            @Override
7304            public void onReceive(Context context, Intent intent) {
7305                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7306                if (pkgs != null) {
7307                    for (String pkg : pkgs) {
7308                        synchronized (ActivityManagerService.this) {
7309                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7310                                    0, "query restart")) {
7311                                setResultCode(Activity.RESULT_OK);
7312                                return;
7313                            }
7314                        }
7315                    }
7316                }
7317            }
7318        }, pkgFilter);
7319
7320        IntentFilter dumpheapFilter = new IntentFilter();
7321        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7322        mContext.registerReceiver(new BroadcastReceiver() {
7323            @Override
7324            public void onReceive(Context context, Intent intent) {
7325                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7326                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7327                } else {
7328                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7329                }
7330            }
7331        }, dumpheapFilter);
7332
7333        // Let system services know.
7334        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7335
7336        synchronized (this) {
7337            // Ensure that any processes we had put on hold are now started
7338            // up.
7339            final int NP = mProcessesOnHold.size();
7340            if (NP > 0) {
7341                ArrayList<ProcessRecord> procs =
7342                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7343                for (int ip=0; ip<NP; ip++) {
7344                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7345                            + procs.get(ip));
7346                    startProcessLocked(procs.get(ip), "on-hold", null);
7347                }
7348            }
7349            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7350                return;
7351            }
7352            // Start looking for apps that are abusing wake locks.
7353            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7354            mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7355            // Tell anyone interested that we are done booting!
7356            SystemProperties.set("sys.boot_completed", "1");
7357
7358            // And trigger dev.bootcomplete if we are not showing encryption progress
7359            if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7360                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7361                SystemProperties.set("dev.bootcomplete", "1");
7362            }
7363            mUserController.sendBootCompleted(
7364                    new IIntentReceiver.Stub() {
7365                        @Override
7366                        public void performReceive(Intent intent, int resultCode,
7367                                String data, Bundle extras, boolean ordered,
7368                                boolean sticky, int sendingUser) {
7369                            synchronized (ActivityManagerService.this) {
7370                                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
7371                            }
7372                        }
7373                    });
7374            mUserController.scheduleStartProfiles();
7375        }
7376    }
7377
7378    @Override
7379    public void bootAnimationComplete() {
7380        final boolean callFinishBooting;
7381        synchronized (this) {
7382            callFinishBooting = mCallFinishBooting;
7383            mBootAnimationComplete = true;
7384        }
7385        if (callFinishBooting) {
7386            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7387            finishBooting();
7388            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7389        }
7390    }
7391
7392    final void ensureBootCompleted() {
7393        boolean booting;
7394        boolean enableScreen;
7395        synchronized (this) {
7396            booting = mBooting;
7397            mBooting = false;
7398            enableScreen = !mBooted;
7399            mBooted = true;
7400        }
7401
7402        if (booting) {
7403            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7404            finishBooting();
7405            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7406        }
7407
7408        if (enableScreen) {
7409            enableScreenAfterBoot();
7410        }
7411    }
7412
7413    @Override
7414    public final void activityResumed(IBinder token) {
7415        final long origId = Binder.clearCallingIdentity();
7416        synchronized(this) {
7417            ActivityRecord.activityResumedLocked(token);
7418            mWindowManager.notifyAppResumedFinished(token);
7419        }
7420        Binder.restoreCallingIdentity(origId);
7421    }
7422
7423    @Override
7424    public final void activityPaused(IBinder token) {
7425        final long origId = Binder.clearCallingIdentity();
7426        synchronized(this) {
7427            ActivityStack stack = ActivityRecord.getStackLocked(token);
7428            if (stack != null) {
7429                stack.activityPausedLocked(token, false);
7430            }
7431        }
7432        Binder.restoreCallingIdentity(origId);
7433    }
7434
7435    @Override
7436    public final void activityStopped(IBinder token, Bundle icicle,
7437            PersistableBundle persistentState, CharSequence description) {
7438        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7439
7440        // Refuse possible leaked file descriptors
7441        if (icicle != null && icicle.hasFileDescriptors()) {
7442            throw new IllegalArgumentException("File descriptors passed in Bundle");
7443        }
7444
7445        final long origId = Binder.clearCallingIdentity();
7446
7447        synchronized (this) {
7448            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7449            if (r != null) {
7450                r.activityStoppedLocked(icicle, persistentState, description);
7451            }
7452        }
7453
7454        trimApplications();
7455
7456        Binder.restoreCallingIdentity(origId);
7457    }
7458
7459    @Override
7460    public final void activityDestroyed(IBinder token) {
7461        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7462        synchronized (this) {
7463            ActivityStack stack = ActivityRecord.getStackLocked(token);
7464            if (stack != null) {
7465                stack.activityDestroyedLocked(token, "activityDestroyed");
7466            }
7467        }
7468    }
7469
7470    @Override
7471    public final void activityRelaunched(IBinder token) {
7472        final long origId = Binder.clearCallingIdentity();
7473        synchronized (this) {
7474            mStackSupervisor.activityRelaunchedLocked(token);
7475        }
7476        Binder.restoreCallingIdentity(origId);
7477    }
7478
7479    @Override
7480    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7481            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7482        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7483                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7484        synchronized (this) {
7485            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7486            if (record == null) {
7487                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7488                        + "found for: " + token);
7489            }
7490            record.setSizeConfigurations(horizontalSizeConfiguration,
7491                    verticalSizeConfigurations, smallestSizeConfigurations);
7492        }
7493    }
7494
7495    @Override
7496    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7497        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7498    }
7499
7500    @Override
7501    public final void notifyEnterAnimationComplete(IBinder token) {
7502        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7503    }
7504
7505    @Override
7506    public String getCallingPackage(IBinder token) {
7507        synchronized (this) {
7508            ActivityRecord r = getCallingRecordLocked(token);
7509            return r != null ? r.info.packageName : null;
7510        }
7511    }
7512
7513    @Override
7514    public ComponentName getCallingActivity(IBinder token) {
7515        synchronized (this) {
7516            ActivityRecord r = getCallingRecordLocked(token);
7517            return r != null ? r.intent.getComponent() : null;
7518        }
7519    }
7520
7521    private ActivityRecord getCallingRecordLocked(IBinder token) {
7522        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7523        if (r == null) {
7524            return null;
7525        }
7526        return r.resultTo;
7527    }
7528
7529    @Override
7530    public ComponentName getActivityClassForToken(IBinder token) {
7531        synchronized(this) {
7532            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7533            if (r == null) {
7534                return null;
7535            }
7536            return r.intent.getComponent();
7537        }
7538    }
7539
7540    @Override
7541    public String getPackageForToken(IBinder token) {
7542        synchronized(this) {
7543            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7544            if (r == null) {
7545                return null;
7546            }
7547            return r.packageName;
7548        }
7549    }
7550
7551    @Override
7552    public boolean isRootVoiceInteraction(IBinder token) {
7553        synchronized(this) {
7554            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7555            if (r == null) {
7556                return false;
7557            }
7558            return r.rootVoiceInteraction;
7559        }
7560    }
7561
7562    @Override
7563    public IIntentSender getIntentSender(int type,
7564            String packageName, IBinder token, String resultWho,
7565            int requestCode, Intent[] intents, String[] resolvedTypes,
7566            int flags, Bundle bOptions, int userId) {
7567        enforceNotIsolatedCaller("getIntentSender");
7568        // Refuse possible leaked file descriptors
7569        if (intents != null) {
7570            if (intents.length < 1) {
7571                throw new IllegalArgumentException("Intents array length must be >= 1");
7572            }
7573            for (int i=0; i<intents.length; i++) {
7574                Intent intent = intents[i];
7575                if (intent != null) {
7576                    if (intent.hasFileDescriptors()) {
7577                        throw new IllegalArgumentException("File descriptors passed in Intent");
7578                    }
7579                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7580                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7581                        throw new IllegalArgumentException(
7582                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7583                    }
7584                    intents[i] = new Intent(intent);
7585                }
7586            }
7587            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7588                throw new IllegalArgumentException(
7589                        "Intent array length does not match resolvedTypes length");
7590            }
7591        }
7592        if (bOptions != null) {
7593            if (bOptions.hasFileDescriptors()) {
7594                throw new IllegalArgumentException("File descriptors passed in options");
7595            }
7596        }
7597
7598        synchronized(this) {
7599            int callingUid = Binder.getCallingUid();
7600            int origUserId = userId;
7601            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7602                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7603                    ALLOW_NON_FULL, "getIntentSender", null);
7604            if (origUserId == UserHandle.USER_CURRENT) {
7605                // We don't want to evaluate this until the pending intent is
7606                // actually executed.  However, we do want to always do the
7607                // security checking for it above.
7608                userId = UserHandle.USER_CURRENT;
7609            }
7610            try {
7611                if (callingUid != 0 && callingUid != SYSTEM_UID) {
7612                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7613                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7614                    if (!UserHandle.isSameApp(callingUid, uid)) {
7615                        String msg = "Permission Denial: getIntentSender() from pid="
7616                            + Binder.getCallingPid()
7617                            + ", uid=" + Binder.getCallingUid()
7618                            + ", (need uid=" + uid + ")"
7619                            + " is not allowed to send as package " + packageName;
7620                        Slog.w(TAG, msg);
7621                        throw new SecurityException(msg);
7622                    }
7623                }
7624
7625                return getIntentSenderLocked(type, packageName, callingUid, userId,
7626                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7627
7628            } catch (RemoteException e) {
7629                throw new SecurityException(e);
7630            }
7631        }
7632    }
7633
7634    IIntentSender getIntentSenderLocked(int type, String packageName,
7635            int callingUid, int userId, IBinder token, String resultWho,
7636            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7637            Bundle bOptions) {
7638        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7639        ActivityRecord activity = null;
7640        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7641            activity = ActivityRecord.isInStackLocked(token);
7642            if (activity == null) {
7643                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7644                return null;
7645            }
7646            if (activity.finishing) {
7647                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7648                return null;
7649            }
7650        }
7651
7652        // We're going to be splicing together extras before sending, so we're
7653        // okay poking into any contained extras.
7654        if (intents != null) {
7655            for (int i = 0; i < intents.length; i++) {
7656                intents[i].setDefusable(true);
7657            }
7658        }
7659        Bundle.setDefusable(bOptions, true);
7660
7661        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7662        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7663        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7664        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7665                |PendingIntent.FLAG_UPDATE_CURRENT);
7666
7667        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7668                type, packageName, activity, resultWho,
7669                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7670        WeakReference<PendingIntentRecord> ref;
7671        ref = mIntentSenderRecords.get(key);
7672        PendingIntentRecord rec = ref != null ? ref.get() : null;
7673        if (rec != null) {
7674            if (!cancelCurrent) {
7675                if (updateCurrent) {
7676                    if (rec.key.requestIntent != null) {
7677                        rec.key.requestIntent.replaceExtras(intents != null ?
7678                                intents[intents.length - 1] : null);
7679                    }
7680                    if (intents != null) {
7681                        intents[intents.length-1] = rec.key.requestIntent;
7682                        rec.key.allIntents = intents;
7683                        rec.key.allResolvedTypes = resolvedTypes;
7684                    } else {
7685                        rec.key.allIntents = null;
7686                        rec.key.allResolvedTypes = null;
7687                    }
7688                }
7689                return rec;
7690            }
7691            makeIntentSenderCanceledLocked(rec);
7692            mIntentSenderRecords.remove(key);
7693        }
7694        if (noCreate) {
7695            return rec;
7696        }
7697        rec = new PendingIntentRecord(this, key, callingUid);
7698        mIntentSenderRecords.put(key, rec.ref);
7699        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7700            if (activity.pendingResults == null) {
7701                activity.pendingResults
7702                        = new HashSet<WeakReference<PendingIntentRecord>>();
7703            }
7704            activity.pendingResults.add(rec.ref);
7705        }
7706        return rec;
7707    }
7708
7709    @Override
7710    public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7711            Intent intent, String resolvedType,
7712            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7713        if (target instanceof PendingIntentRecord) {
7714            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7715                    whitelistToken, finishedReceiver, requiredPermission, options);
7716        } else {
7717            if (intent == null) {
7718                // Weird case: someone has given us their own custom IIntentSender, and now
7719                // they have someone else trying to send to it but of course this isn't
7720                // really a PendingIntent, so there is no base Intent, and the caller isn't
7721                // supplying an Intent... but we never want to dispatch a null Intent to
7722                // a receiver, so um...  let's make something up.
7723                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7724                intent = new Intent(Intent.ACTION_MAIN);
7725            }
7726            try {
7727                target.send(code, intent, resolvedType, whitelistToken, null,
7728                        requiredPermission, options);
7729            } catch (RemoteException e) {
7730            }
7731            // Platform code can rely on getting a result back when the send is done, but if
7732            // this intent sender is from outside of the system we can't rely on it doing that.
7733            // So instead we don't give it the result receiver, and instead just directly
7734            // report the finish immediately.
7735            if (finishedReceiver != null) {
7736                try {
7737                    finishedReceiver.performReceive(intent, 0,
7738                            null, null, false, false, UserHandle.getCallingUserId());
7739                } catch (RemoteException e) {
7740                }
7741            }
7742            return 0;
7743        }
7744    }
7745
7746    @Override
7747    public void cancelIntentSender(IIntentSender sender) {
7748        if (!(sender instanceof PendingIntentRecord)) {
7749            return;
7750        }
7751        synchronized(this) {
7752            PendingIntentRecord rec = (PendingIntentRecord)sender;
7753            try {
7754                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7755                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7756                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7757                    String msg = "Permission Denial: cancelIntentSender() from pid="
7758                        + Binder.getCallingPid()
7759                        + ", uid=" + Binder.getCallingUid()
7760                        + " is not allowed to cancel package "
7761                        + rec.key.packageName;
7762                    Slog.w(TAG, msg);
7763                    throw new SecurityException(msg);
7764                }
7765            } catch (RemoteException e) {
7766                throw new SecurityException(e);
7767            }
7768            cancelIntentSenderLocked(rec, true);
7769        }
7770    }
7771
7772    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7773        makeIntentSenderCanceledLocked(rec);
7774        mIntentSenderRecords.remove(rec.key);
7775        if (cleanActivity && rec.key.activity != null) {
7776            rec.key.activity.pendingResults.remove(rec.ref);
7777        }
7778    }
7779
7780    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7781        rec.canceled = true;
7782        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7783        if (callbacks != null) {
7784            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7785        }
7786    }
7787
7788    @Override
7789    public String getPackageForIntentSender(IIntentSender pendingResult) {
7790        if (!(pendingResult instanceof PendingIntentRecord)) {
7791            return null;
7792        }
7793        try {
7794            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7795            return res.key.packageName;
7796        } catch (ClassCastException e) {
7797        }
7798        return null;
7799    }
7800
7801    @Override
7802    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7803        if (!(sender instanceof PendingIntentRecord)) {
7804            return;
7805        }
7806        synchronized(this) {
7807            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7808        }
7809    }
7810
7811    @Override
7812    public void unregisterIntentSenderCancelListener(IIntentSender sender,
7813            IResultReceiver receiver) {
7814        if (!(sender instanceof PendingIntentRecord)) {
7815            return;
7816        }
7817        synchronized(this) {
7818            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7819        }
7820    }
7821
7822    @Override
7823    public int getUidForIntentSender(IIntentSender sender) {
7824        if (sender instanceof PendingIntentRecord) {
7825            try {
7826                PendingIntentRecord res = (PendingIntentRecord)sender;
7827                return res.uid;
7828            } catch (ClassCastException e) {
7829            }
7830        }
7831        return -1;
7832    }
7833
7834    @Override
7835    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7836        if (!(pendingResult instanceof PendingIntentRecord)) {
7837            return false;
7838        }
7839        try {
7840            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7841            if (res.key.allIntents == null) {
7842                return false;
7843            }
7844            for (int i=0; i<res.key.allIntents.length; i++) {
7845                Intent intent = res.key.allIntents[i];
7846                if (intent.getPackage() != null && intent.getComponent() != null) {
7847                    return false;
7848                }
7849            }
7850            return true;
7851        } catch (ClassCastException e) {
7852        }
7853        return false;
7854    }
7855
7856    @Override
7857    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7858        if (!(pendingResult instanceof PendingIntentRecord)) {
7859            return false;
7860        }
7861        try {
7862            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7863            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7864                return true;
7865            }
7866            return false;
7867        } catch (ClassCastException e) {
7868        }
7869        return false;
7870    }
7871
7872    @Override
7873    public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
7874        if (pendingResult instanceof PendingIntentRecord) {
7875            final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
7876            return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
7877        }
7878        return false;
7879    }
7880
7881    @Override
7882    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7883        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7884                "getIntentForIntentSender()");
7885        if (!(pendingResult instanceof PendingIntentRecord)) {
7886            return null;
7887        }
7888        try {
7889            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7890            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7891        } catch (ClassCastException e) {
7892        }
7893        return null;
7894    }
7895
7896    @Override
7897    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7898        if (!(pendingResult instanceof PendingIntentRecord)) {
7899            return null;
7900        }
7901        try {
7902            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7903            synchronized (this) {
7904                return getTagForIntentSenderLocked(res, prefix);
7905            }
7906        } catch (ClassCastException e) {
7907        }
7908        return null;
7909    }
7910
7911    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7912        final Intent intent = res.key.requestIntent;
7913        if (intent != null) {
7914            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7915                    || res.lastTagPrefix.equals(prefix))) {
7916                return res.lastTag;
7917            }
7918            res.lastTagPrefix = prefix;
7919            final StringBuilder sb = new StringBuilder(128);
7920            if (prefix != null) {
7921                sb.append(prefix);
7922            }
7923            if (intent.getAction() != null) {
7924                sb.append(intent.getAction());
7925            } else if (intent.getComponent() != null) {
7926                intent.getComponent().appendShortString(sb);
7927            } else {
7928                sb.append("?");
7929            }
7930            return res.lastTag = sb.toString();
7931        }
7932        return null;
7933    }
7934
7935    @Override
7936    public void setProcessLimit(int max) {
7937        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7938                "setProcessLimit()");
7939        synchronized (this) {
7940            mConstants.setOverrideMaxCachedProcesses(max);
7941        }
7942        trimApplications();
7943    }
7944
7945    @Override
7946    public int getProcessLimit() {
7947        synchronized (this) {
7948            return mConstants.getOverrideMaxCachedProcesses();
7949        }
7950    }
7951
7952    void importanceTokenDied(ImportanceToken token) {
7953        synchronized (ActivityManagerService.this) {
7954            synchronized (mPidsSelfLocked) {
7955                ImportanceToken cur
7956                    = mImportantProcesses.get(token.pid);
7957                if (cur != token) {
7958                    return;
7959                }
7960                mImportantProcesses.remove(token.pid);
7961                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7962                if (pr == null) {
7963                    return;
7964                }
7965                pr.forcingToImportant = null;
7966                updateProcessForegroundLocked(pr, false, false);
7967            }
7968            updateOomAdjLocked();
7969        }
7970    }
7971
7972    @Override
7973    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7974        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7975                "setProcessImportant()");
7976        synchronized(this) {
7977            boolean changed = false;
7978
7979            synchronized (mPidsSelfLocked) {
7980                ProcessRecord pr = mPidsSelfLocked.get(pid);
7981                if (pr == null && isForeground) {
7982                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7983                    return;
7984                }
7985                ImportanceToken oldToken = mImportantProcesses.get(pid);
7986                if (oldToken != null) {
7987                    oldToken.token.unlinkToDeath(oldToken, 0);
7988                    mImportantProcesses.remove(pid);
7989                    if (pr != null) {
7990                        pr.forcingToImportant = null;
7991                    }
7992                    changed = true;
7993                }
7994                if (isForeground && token != null) {
7995                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7996                        @Override
7997                        public void binderDied() {
7998                            importanceTokenDied(this);
7999                        }
8000                    };
8001                    try {
8002                        token.linkToDeath(newToken, 0);
8003                        mImportantProcesses.put(pid, newToken);
8004                        pr.forcingToImportant = newToken;
8005                        changed = true;
8006                    } catch (RemoteException e) {
8007                        // If the process died while doing this, we will later
8008                        // do the cleanup with the process death link.
8009                    }
8010                }
8011            }
8012
8013            if (changed) {
8014                updateOomAdjLocked();
8015            }
8016        }
8017    }
8018
8019    @Override
8020    public boolean isAppForeground(int uid) throws RemoteException {
8021        synchronized (this) {
8022            UidRecord uidRec = mActiveUids.get(uid);
8023            if (uidRec == null || uidRec.idle) {
8024                return false;
8025            }
8026            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8027        }
8028    }
8029
8030    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8031    // be guarded by permission checking.
8032    int getUidState(int uid) {
8033        synchronized (this) {
8034            return getUidStateLocked(uid);
8035        }
8036    }
8037
8038    int getUidStateLocked(int uid) {
8039        UidRecord uidRec = mActiveUids.get(uid);
8040        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8041    }
8042
8043    @Override
8044    public boolean isInMultiWindowMode(IBinder token) {
8045        final long origId = Binder.clearCallingIdentity();
8046        try {
8047            synchronized(this) {
8048                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8049                if (r == null) {
8050                    return false;
8051                }
8052                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8053                return !r.getTask().mFullscreen;
8054            }
8055        } finally {
8056            Binder.restoreCallingIdentity(origId);
8057        }
8058    }
8059
8060    @Override
8061    public boolean isInPictureInPictureMode(IBinder token) {
8062        final long origId = Binder.clearCallingIdentity();
8063        try {
8064            synchronized(this) {
8065                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8066            }
8067        } finally {
8068            Binder.restoreCallingIdentity(origId);
8069        }
8070    }
8071
8072    private boolean isInPictureInPictureMode(ActivityRecord r) {
8073        if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
8074                || r.getStack().isInStackLocked(r) == null) {
8075            return false;
8076        }
8077
8078        // If we are animating to fullscreen then we have already dispatched the PIP mode
8079        // changed, so we should reflect that check here as well.
8080        final PinnedActivityStack stack = r.getStack();
8081        final PinnedStackWindowController windowController = stack.getWindowContainerController();
8082        return !windowController.isAnimatingBoundsToFullscreen();
8083    }
8084
8085    @Override
8086    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8087        final long origId = Binder.clearCallingIdentity();
8088        try {
8089            synchronized(this) {
8090                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8091                        "enterPictureInPictureMode", token, params);
8092
8093                // If the activity is already in picture in picture mode, then just return early
8094                if (isInPictureInPictureMode(r)) {
8095                    return true;
8096                }
8097
8098                // Activity supports picture-in-picture, now check that we can enter PiP at this
8099                // point, if it is
8100                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8101                        false /* beforeStopping */)) {
8102                    return false;
8103                }
8104
8105                final Runnable enterPipRunnable = () -> {
8106                    // Only update the saved args from the args that are set
8107                    r.pictureInPictureArgs.copyOnlySet(params);
8108                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8109                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8110                    // Adjust the source bounds by the insets for the transition down
8111                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8112                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8113                            "enterPictureInPictureMode");
8114                    final PinnedActivityStack stack = r.getStack();
8115                    stack.setPictureInPictureAspectRatio(aspectRatio);
8116                    stack.setPictureInPictureActions(actions);
8117
8118                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8119                            r.supportsEnterPipOnTaskSwitch);
8120                    logPictureInPictureArgs(params);
8121                };
8122
8123                if (isKeyguardLocked()) {
8124                    // If the keyguard is showing or occluded, then try and dismiss it before
8125                    // entering picture-in-picture (this will prompt the user to authenticate if the
8126                    // device is currently locked).
8127                    try {
8128                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8129                            @Override
8130                            public void onDismissError() throws RemoteException {
8131                                // Do nothing
8132                            }
8133
8134                            @Override
8135                            public void onDismissSucceeded() throws RemoteException {
8136                                mHandler.post(enterPipRunnable);
8137                            }
8138
8139                            @Override
8140                            public void onDismissCancelled() throws RemoteException {
8141                                // Do nothing
8142                            }
8143                        });
8144                    } catch (RemoteException e) {
8145                        // Local call
8146                    }
8147                } else {
8148                    // Enter picture in picture immediately otherwise
8149                    enterPipRunnable.run();
8150                }
8151                return true;
8152            }
8153        } finally {
8154            Binder.restoreCallingIdentity(origId);
8155        }
8156    }
8157
8158    @Override
8159    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8160        final long origId = Binder.clearCallingIdentity();
8161        try {
8162            synchronized(this) {
8163                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8164                        "setPictureInPictureParams", token, params);
8165
8166                // Only update the saved args from the args that are set
8167                r.pictureInPictureArgs.copyOnlySet(params);
8168                if (r.inPinnedWindowingMode()) {
8169                    // If the activity is already in picture-in-picture, update the pinned stack now
8170                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
8171                    // be used the next time the activity enters PiP
8172                    final PinnedActivityStack stack = r.getStack();
8173                    if (!stack.isAnimatingBoundsToFullscreen()) {
8174                        stack.setPictureInPictureAspectRatio(
8175                                r.pictureInPictureArgs.getAspectRatio());
8176                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8177                    }
8178                }
8179                logPictureInPictureArgs(params);
8180            }
8181        } finally {
8182            Binder.restoreCallingIdentity(origId);
8183        }
8184    }
8185
8186    @Override
8187    public int getMaxNumPictureInPictureActions(IBinder token) {
8188        // Currently, this is a static constant, but later, we may change this to be dependent on
8189        // the context of the activity
8190        return 3;
8191    }
8192
8193    private void logPictureInPictureArgs(PictureInPictureParams params) {
8194        if (params.hasSetActions()) {
8195            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8196                    params.getActions().size());
8197        }
8198        if (params.hasSetAspectRatio()) {
8199            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8200            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8201            MetricsLogger.action(lm);
8202        }
8203    }
8204
8205    /**
8206     * Checks the state of the system and the activity associated with the given {@param token} to
8207     * verify that picture-in-picture is supported for that activity.
8208     *
8209     * @return the activity record for the given {@param token} if all the checks pass.
8210     */
8211    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8212            IBinder token, PictureInPictureParams params) {
8213        if (!mSupportsPictureInPicture) {
8214            throw new IllegalStateException(caller
8215                    + ": Device doesn't support picture-in-picture mode.");
8216        }
8217
8218        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8219        if (r == null) {
8220            throw new IllegalStateException(caller
8221                    + ": Can't find activity for token=" + token);
8222        }
8223
8224        if (!r.supportsPictureInPicture()) {
8225            throw new IllegalStateException(caller
8226                    + ": Current activity does not support picture-in-picture.");
8227        }
8228
8229        if (params.hasSetAspectRatio()
8230                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8231                        params.getAspectRatio())) {
8232            final float minAspectRatio = mContext.getResources().getFloat(
8233                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8234            final float maxAspectRatio = mContext.getResources().getFloat(
8235                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8236            throw new IllegalArgumentException(String.format(caller
8237                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8238                            minAspectRatio, maxAspectRatio));
8239        }
8240
8241        // Truncate the number of actions if necessary
8242        params.truncateActions(getMaxNumPictureInPictureActions(token));
8243
8244        return r;
8245    }
8246
8247    // =========================================================
8248    // PROCESS INFO
8249    // =========================================================
8250
8251    static class ProcessInfoService extends IProcessInfoService.Stub {
8252        final ActivityManagerService mActivityManagerService;
8253        ProcessInfoService(ActivityManagerService activityManagerService) {
8254            mActivityManagerService = activityManagerService;
8255        }
8256
8257        @Override
8258        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8259            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8260                    /*in*/ pids, /*out*/ states, null);
8261        }
8262
8263        @Override
8264        public void getProcessStatesAndOomScoresFromPids(
8265                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8266            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8267                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8268        }
8269    }
8270
8271    /**
8272     * For each PID in the given input array, write the current process state
8273     * for that process into the states array, or -1 to indicate that no
8274     * process with the given PID exists. If scores array is provided, write
8275     * the oom score for the process into the scores array, with INVALID_ADJ
8276     * indicating the PID doesn't exist.
8277     */
8278    public void getProcessStatesAndOomScoresForPIDs(
8279            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8280        if (scores != null) {
8281            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8282                    "getProcessStatesAndOomScoresForPIDs()");
8283        }
8284
8285        if (pids == null) {
8286            throw new NullPointerException("pids");
8287        } else if (states == null) {
8288            throw new NullPointerException("states");
8289        } else if (pids.length != states.length) {
8290            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8291        } else if (scores != null && pids.length != scores.length) {
8292            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8293        }
8294
8295        synchronized (mPidsSelfLocked) {
8296            for (int i = 0; i < pids.length; i++) {
8297                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8298                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8299                        pr.curProcState;
8300                if (scores != null) {
8301                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8302                }
8303            }
8304        }
8305    }
8306
8307    // =========================================================
8308    // PERMISSIONS
8309    // =========================================================
8310
8311    static class PermissionController extends IPermissionController.Stub {
8312        ActivityManagerService mActivityManagerService;
8313        PermissionController(ActivityManagerService activityManagerService) {
8314            mActivityManagerService = activityManagerService;
8315        }
8316
8317        @Override
8318        public boolean checkPermission(String permission, int pid, int uid) {
8319            return mActivityManagerService.checkPermission(permission, pid,
8320                    uid) == PackageManager.PERMISSION_GRANTED;
8321        }
8322
8323        @Override
8324        public String[] getPackagesForUid(int uid) {
8325            return mActivityManagerService.mContext.getPackageManager()
8326                    .getPackagesForUid(uid);
8327        }
8328
8329        @Override
8330        public boolean isRuntimePermission(String permission) {
8331            try {
8332                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8333                        .getPermissionInfo(permission, 0);
8334                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8335                        == PermissionInfo.PROTECTION_DANGEROUS;
8336            } catch (NameNotFoundException nnfe) {
8337                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8338            }
8339            return false;
8340        }
8341    }
8342
8343    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8344        @Override
8345        public int checkComponentPermission(String permission, int pid, int uid,
8346                int owningUid, boolean exported) {
8347            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8348                    owningUid, exported);
8349        }
8350
8351        @Override
8352        public Object getAMSLock() {
8353            return ActivityManagerService.this;
8354        }
8355    }
8356
8357    int checkComponentPermission(String permission, int pid, int uid,
8358            int owningUid, boolean exported) {
8359        if (pid == MY_PID) {
8360            return PackageManager.PERMISSION_GRANTED;
8361        }
8362        return ActivityManager.checkComponentPermission(permission, uid,
8363                owningUid, exported);
8364    }
8365
8366    /**
8367     * As the only public entry point for permissions checking, this method
8368     * can enforce the semantic that requesting a check on a null global
8369     * permission is automatically denied.  (Internally a null permission
8370     * string is used when calling {@link #checkComponentPermission} in cases
8371     * when only uid-based security is needed.)
8372     *
8373     * This can be called with or without the global lock held.
8374     */
8375    @Override
8376    public int checkPermission(String permission, int pid, int uid) {
8377        if (permission == null) {
8378            return PackageManager.PERMISSION_DENIED;
8379        }
8380        return checkComponentPermission(permission, pid, uid, -1, true);
8381    }
8382
8383    @Override
8384    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8385        if (permission == null) {
8386            return PackageManager.PERMISSION_DENIED;
8387        }
8388
8389        // We might be performing an operation on behalf of an indirect binder
8390        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8391        // client identity accordingly before proceeding.
8392        Identity tlsIdentity = sCallerIdentity.get();
8393        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8394            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8395                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8396            uid = tlsIdentity.uid;
8397            pid = tlsIdentity.pid;
8398        }
8399
8400        return checkComponentPermission(permission, pid, uid, -1, true);
8401    }
8402
8403    /**
8404     * Binder IPC calls go through the public entry point.
8405     * This can be called with or without the global lock held.
8406     */
8407    int checkCallingPermission(String permission) {
8408        return checkPermission(permission,
8409                Binder.getCallingPid(),
8410                UserHandle.getAppId(Binder.getCallingUid()));
8411    }
8412
8413    /**
8414     * This can be called with or without the global lock held.
8415     */
8416    void enforceCallingPermission(String permission, String func) {
8417        if (checkCallingPermission(permission)
8418                == PackageManager.PERMISSION_GRANTED) {
8419            return;
8420        }
8421
8422        String msg = "Permission Denial: " + func + " from pid="
8423                + Binder.getCallingPid()
8424                + ", uid=" + Binder.getCallingUid()
8425                + " requires " + permission;
8426        Slog.w(TAG, msg);
8427        throw new SecurityException(msg);
8428    }
8429
8430    /**
8431     * This can be called with or without the global lock held.
8432     */
8433    void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
8434        if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
8435            enforceCallingPermission(permission, func);
8436        }
8437    }
8438
8439    /**
8440     * Determine if UID is holding permissions required to access {@link Uri} in
8441     * the given {@link ProviderInfo}. Final permission checking is always done
8442     * in {@link ContentProvider}.
8443     */
8444    private final boolean checkHoldingPermissionsLocked(
8445            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8446        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8447                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8448        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8449            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8450                    != PERMISSION_GRANTED) {
8451                return false;
8452            }
8453        }
8454        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8455    }
8456
8457    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8458            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8459        if (pi.applicationInfo.uid == uid) {
8460            return true;
8461        } else if (!pi.exported) {
8462            return false;
8463        }
8464
8465        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8466        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8467        try {
8468            // check if target holds top-level <provider> permissions
8469            if (!readMet && pi.readPermission != null && considerUidPermissions
8470                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8471                readMet = true;
8472            }
8473            if (!writeMet && pi.writePermission != null && considerUidPermissions
8474                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8475                writeMet = true;
8476            }
8477
8478            // track if unprotected read/write is allowed; any denied
8479            // <path-permission> below removes this ability
8480            boolean allowDefaultRead = pi.readPermission == null;
8481            boolean allowDefaultWrite = pi.writePermission == null;
8482
8483            // check if target holds any <path-permission> that match uri
8484            final PathPermission[] pps = pi.pathPermissions;
8485            if (pps != null) {
8486                final String path = grantUri.uri.getPath();
8487                int i = pps.length;
8488                while (i > 0 && (!readMet || !writeMet)) {
8489                    i--;
8490                    PathPermission pp = pps[i];
8491                    if (pp.match(path)) {
8492                        if (!readMet) {
8493                            final String pprperm = pp.getReadPermission();
8494                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8495                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8496                                    + ": match=" + pp.match(path)
8497                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8498                            if (pprperm != null) {
8499                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8500                                        == PERMISSION_GRANTED) {
8501                                    readMet = true;
8502                                } else {
8503                                    allowDefaultRead = false;
8504                                }
8505                            }
8506                        }
8507                        if (!writeMet) {
8508                            final String ppwperm = pp.getWritePermission();
8509                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8510                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8511                                    + ": match=" + pp.match(path)
8512                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8513                            if (ppwperm != null) {
8514                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8515                                        == PERMISSION_GRANTED) {
8516                                    writeMet = true;
8517                                } else {
8518                                    allowDefaultWrite = false;
8519                                }
8520                            }
8521                        }
8522                    }
8523                }
8524            }
8525
8526            // grant unprotected <provider> read/write, if not blocked by
8527            // <path-permission> above
8528            if (allowDefaultRead) readMet = true;
8529            if (allowDefaultWrite) writeMet = true;
8530
8531        } catch (RemoteException e) {
8532            return false;
8533        }
8534
8535        return readMet && writeMet;
8536    }
8537
8538    public boolean isAppStartModeDisabled(int uid, String packageName) {
8539        synchronized (this) {
8540            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8541                    == ActivityManager.APP_START_MODE_DISABLED;
8542        }
8543    }
8544
8545    // Unified app-op and target sdk check
8546    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8547        // Apps that target O+ are always subject to background check
8548        if (packageTargetSdk >= Build.VERSION_CODES.O) {
8549            if (DEBUG_BACKGROUND_CHECK) {
8550                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8551            }
8552            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8553        }
8554        // ...and legacy apps get an AppOp check
8555        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8556                uid, packageName);
8557        if (DEBUG_BACKGROUND_CHECK) {
8558            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8559        }
8560        switch (appop) {
8561            case AppOpsManager.MODE_ALLOWED:
8562                return ActivityManager.APP_START_MODE_NORMAL;
8563            case AppOpsManager.MODE_IGNORED:
8564                return ActivityManager.APP_START_MODE_DELAYED;
8565            default:
8566                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8567        }
8568    }
8569
8570    // Service launch is available to apps with run-in-background exemptions but
8571    // some other background operations are not.  If we're doing a check
8572    // of service-launch policy, allow those callers to proceed unrestricted.
8573    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8574        // Persistent app?
8575        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8576            if (DEBUG_BACKGROUND_CHECK) {
8577                Slog.i(TAG, "App " + uid + "/" + packageName
8578                        + " is persistent; not restricted in background");
8579            }
8580            return ActivityManager.APP_START_MODE_NORMAL;
8581        }
8582
8583        // Non-persistent but background whitelisted?
8584        if (uidOnBackgroundWhitelist(uid)) {
8585            if (DEBUG_BACKGROUND_CHECK) {
8586                Slog.i(TAG, "App " + uid + "/" + packageName
8587                        + " on background whitelist; not restricted in background");
8588            }
8589            return ActivityManager.APP_START_MODE_NORMAL;
8590        }
8591
8592        // Is this app on the battery whitelist?
8593        if (isOnDeviceIdleWhitelistLocked(uid)) {
8594            if (DEBUG_BACKGROUND_CHECK) {
8595                Slog.i(TAG, "App " + uid + "/" + packageName
8596                        + " on idle whitelist; not restricted in background");
8597            }
8598            return ActivityManager.APP_START_MODE_NORMAL;
8599        }
8600
8601        // None of the service-policy criteria apply, so we apply the common criteria
8602        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8603    }
8604
8605    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8606            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8607        UidRecord uidRec = mActiveUids.get(uid);
8608        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8609                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8610                + (uidRec != null ? uidRec.idle : false));
8611        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8612            boolean ephemeral;
8613            if (uidRec == null) {
8614                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8615                        UserHandle.getUserId(uid), packageName);
8616            } else {
8617                ephemeral = uidRec.ephemeral;
8618            }
8619
8620            if (ephemeral) {
8621                // We are hard-core about ephemeral apps not running in the background.
8622                return ActivityManager.APP_START_MODE_DISABLED;
8623            } else {
8624                if (disabledOnly) {
8625                    // The caller is only interested in whether app starts are completely
8626                    // disabled for the given package (that is, it is an instant app).  So
8627                    // we don't need to go further, which is all just seeing if we should
8628                    // apply a "delayed" mode for a regular app.
8629                    return ActivityManager.APP_START_MODE_NORMAL;
8630                }
8631                final int startMode = (alwaysRestrict)
8632                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8633                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8634                                packageTargetSdk);
8635                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8636                        + " pkg=" + packageName + " startMode=" + startMode
8637                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8638                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8639                    // This is an old app that has been forced into a "compatible as possible"
8640                    // mode of background check.  To increase compatibility, we will allow other
8641                    // foreground apps to cause its services to start.
8642                    if (callingPid >= 0) {
8643                        ProcessRecord proc;
8644                        synchronized (mPidsSelfLocked) {
8645                            proc = mPidsSelfLocked.get(callingPid);
8646                        }
8647                        if (proc != null &&
8648                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
8649                            // Whoever is instigating this is in the foreground, so we will allow it
8650                            // to go through.
8651                            return ActivityManager.APP_START_MODE_NORMAL;
8652                        }
8653                    }
8654                }
8655                return startMode;
8656            }
8657        }
8658        return ActivityManager.APP_START_MODE_NORMAL;
8659    }
8660
8661    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8662        final int appId = UserHandle.getAppId(uid);
8663        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8664                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8665                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8666    }
8667
8668    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8669        ProviderInfo pi = null;
8670        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8671        if (cpr != null) {
8672            pi = cpr.info;
8673        } else {
8674            try {
8675                pi = AppGlobals.getPackageManager().resolveContentProvider(
8676                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8677                        userHandle);
8678            } catch (RemoteException ex) {
8679            }
8680        }
8681        return pi;
8682    }
8683
8684    void grantEphemeralAccessLocked(int userId, Intent intent,
8685            int targetAppId, int ephemeralAppId) {
8686        getPackageManagerInternalLocked().
8687                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8688    }
8689
8690    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8691        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8692        if (targetUris != null) {
8693            return targetUris.get(grantUri);
8694        }
8695        return null;
8696    }
8697
8698    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8699            String targetPkg, int targetUid, GrantUri grantUri) {
8700        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8701        if (targetUris == null) {
8702            targetUris = Maps.newArrayMap();
8703            mGrantedUriPermissions.put(targetUid, targetUris);
8704        }
8705
8706        UriPermission perm = targetUris.get(grantUri);
8707        if (perm == null) {
8708            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8709            targetUris.put(grantUri, perm);
8710        }
8711
8712        return perm;
8713    }
8714
8715    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8716            final int modeFlags) {
8717        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8718        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8719                : UriPermission.STRENGTH_OWNED;
8720
8721        // Root gets to do everything.
8722        if (uid == 0) {
8723            return true;
8724        }
8725
8726        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8727        if (perms == null) return false;
8728
8729        // First look for exact match
8730        final UriPermission exactPerm = perms.get(grantUri);
8731        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8732            return true;
8733        }
8734
8735        // No exact match, look for prefixes
8736        final int N = perms.size();
8737        for (int i = 0; i < N; i++) {
8738            final UriPermission perm = perms.valueAt(i);
8739            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8740                    && perm.getStrength(modeFlags) >= minStrength) {
8741                return true;
8742            }
8743        }
8744
8745        return false;
8746    }
8747
8748    /**
8749     * @param uri This uri must NOT contain an embedded userId.
8750     * @param userId The userId in which the uri is to be resolved.
8751     */
8752    @Override
8753    public int checkUriPermission(Uri uri, int pid, int uid,
8754            final int modeFlags, int userId, IBinder callerToken) {
8755        enforceNotIsolatedCaller("checkUriPermission");
8756
8757        // Another redirected-binder-call permissions check as in
8758        // {@link checkPermissionWithToken}.
8759        Identity tlsIdentity = sCallerIdentity.get();
8760        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8761            uid = tlsIdentity.uid;
8762            pid = tlsIdentity.pid;
8763        }
8764
8765        // Our own process gets to do everything.
8766        if (pid == MY_PID) {
8767            return PackageManager.PERMISSION_GRANTED;
8768        }
8769        synchronized (this) {
8770            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8771                    ? PackageManager.PERMISSION_GRANTED
8772                    : PackageManager.PERMISSION_DENIED;
8773        }
8774    }
8775
8776    /**
8777     * Check if the targetPkg can be granted permission to access uri by
8778     * the callingUid using the given modeFlags.  Throws a security exception
8779     * if callingUid is not allowed to do this.  Returns the uid of the target
8780     * if the URI permission grant should be performed; returns -1 if it is not
8781     * needed (for example targetPkg already has permission to access the URI).
8782     * If you already know the uid of the target, you can supply it in
8783     * lastTargetUid else set that to -1.
8784     */
8785    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8786            final int modeFlags, int lastTargetUid) {
8787        if (!Intent.isAccessUriMode(modeFlags)) {
8788            return -1;
8789        }
8790
8791        if (targetPkg != null) {
8792            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8793                    "Checking grant " + targetPkg + " permission to " + grantUri);
8794        }
8795
8796        final IPackageManager pm = AppGlobals.getPackageManager();
8797
8798        // If this is not a content: uri, we can't do anything with it.
8799        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8800            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8801                    "Can't grant URI permission for non-content URI: " + grantUri);
8802            return -1;
8803        }
8804
8805        // Bail early if system is trying to hand out permissions directly; it
8806        // must always grant permissions on behalf of someone explicit.
8807        final int callingAppId = UserHandle.getAppId(callingUid);
8808        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8809            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8810                // Exempted authority for cropping user photos in Settings app
8811            } else {
8812                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8813                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8814                return -1;
8815            }
8816        }
8817
8818        final String authority = grantUri.uri.getAuthority();
8819        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8820                MATCH_DEBUG_TRIAGED_MISSING);
8821        if (pi == null) {
8822            Slog.w(TAG, "No content provider found for permission check: " +
8823                    grantUri.uri.toSafeString());
8824            return -1;
8825        }
8826
8827        int targetUid = lastTargetUid;
8828        if (targetUid < 0 && targetPkg != null) {
8829            try {
8830                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8831                        UserHandle.getUserId(callingUid));
8832                if (targetUid < 0) {
8833                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8834                            "Can't grant URI permission no uid for: " + targetPkg);
8835                    return -1;
8836                }
8837            } catch (RemoteException ex) {
8838                return -1;
8839            }
8840        }
8841
8842        // If we're extending a persistable grant, then we always need to create
8843        // the grant data structure so that take/release APIs work
8844        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8845            return targetUid;
8846        }
8847
8848        if (targetUid >= 0) {
8849            // First...  does the target actually need this permission?
8850            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8851                // No need to grant the target this permission.
8852                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8853                        "Target " + targetPkg + " already has full permission to " + grantUri);
8854                return -1;
8855            }
8856        } else {
8857            // First...  there is no target package, so can anyone access it?
8858            boolean allowed = pi.exported;
8859            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8860                if (pi.readPermission != null) {
8861                    allowed = false;
8862                }
8863            }
8864            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8865                if (pi.writePermission != null) {
8866                    allowed = false;
8867                }
8868            }
8869            if (allowed) {
8870                return -1;
8871            }
8872        }
8873
8874        /* There is a special cross user grant if:
8875         * - The target is on another user.
8876         * - Apps on the current user can access the uri without any uid permissions.
8877         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8878         * grant uri permissions.
8879         */
8880        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8881                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8882                modeFlags, false /*without considering the uid permissions*/);
8883
8884        // Second...  is the provider allowing granting of URI permissions?
8885        if (!specialCrossUserGrant) {
8886            if (!pi.grantUriPermissions) {
8887                throw new SecurityException("Provider " + pi.packageName
8888                        + "/" + pi.name
8889                        + " does not allow granting of Uri permissions (uri "
8890                        + grantUri + ")");
8891            }
8892            if (pi.uriPermissionPatterns != null) {
8893                final int N = pi.uriPermissionPatterns.length;
8894                boolean allowed = false;
8895                for (int i=0; i<N; i++) {
8896                    if (pi.uriPermissionPatterns[i] != null
8897                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8898                        allowed = true;
8899                        break;
8900                    }
8901                }
8902                if (!allowed) {
8903                    throw new SecurityException("Provider " + pi.packageName
8904                            + "/" + pi.name
8905                            + " does not allow granting of permission to path of Uri "
8906                            + grantUri);
8907                }
8908            }
8909        }
8910
8911        // Third...  does the caller itself have permission to access
8912        // this uri?
8913        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8914            // Require they hold a strong enough Uri permission
8915            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8916                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8917                    throw new SecurityException(
8918                            "UID " + callingUid + " does not have permission to " + grantUri
8919                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8920                                    + "or related APIs");
8921                } else {
8922                    throw new SecurityException(
8923                            "UID " + callingUid + " does not have permission to " + grantUri);
8924                }
8925            }
8926        }
8927        return targetUid;
8928    }
8929
8930    /**
8931     * @param uri This uri must NOT contain an embedded userId.
8932     * @param userId The userId in which the uri is to be resolved.
8933     */
8934    @Override
8935    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8936            final int modeFlags, int userId) {
8937        enforceNotIsolatedCaller("checkGrantUriPermission");
8938        synchronized(this) {
8939            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8940                    new GrantUri(userId, uri, false), modeFlags, -1);
8941        }
8942    }
8943
8944    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8945            final int modeFlags, UriPermissionOwner owner) {
8946        if (!Intent.isAccessUriMode(modeFlags)) {
8947            return;
8948        }
8949
8950        // So here we are: the caller has the assumed permission
8951        // to the uri, and the target doesn't.  Let's now give this to
8952        // the target.
8953
8954        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8955                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8956
8957        final String authority = grantUri.uri.getAuthority();
8958        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8959                MATCH_DEBUG_TRIAGED_MISSING);
8960        if (pi == null) {
8961            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8962            return;
8963        }
8964
8965        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8966            grantUri.prefix = true;
8967        }
8968        final UriPermission perm = findOrCreateUriPermissionLocked(
8969                pi.packageName, targetPkg, targetUid, grantUri);
8970        perm.grantModes(modeFlags, owner);
8971    }
8972
8973    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8974            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8975        if (targetPkg == null) {
8976            throw new NullPointerException("targetPkg");
8977        }
8978        int targetUid;
8979        final IPackageManager pm = AppGlobals.getPackageManager();
8980        try {
8981            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8982        } catch (RemoteException ex) {
8983            return;
8984        }
8985
8986        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8987                targetUid);
8988        if (targetUid < 0) {
8989            return;
8990        }
8991
8992        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8993                owner);
8994    }
8995
8996    static class NeededUriGrants extends ArrayList<GrantUri> {
8997        final String targetPkg;
8998        final int targetUid;
8999        final int flags;
9000
9001        NeededUriGrants(String targetPkg, int targetUid, int flags) {
9002            this.targetPkg = targetPkg;
9003            this.targetUid = targetUid;
9004            this.flags = flags;
9005        }
9006    }
9007
9008    /**
9009     * Like checkGrantUriPermissionLocked, but takes an Intent.
9010     */
9011    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9012            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9013        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9014                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9015                + " clip=" + (intent != null ? intent.getClipData() : null)
9016                + " from " + intent + "; flags=0x"
9017                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9018
9019        if (targetPkg == null) {
9020            throw new NullPointerException("targetPkg");
9021        }
9022
9023        if (intent == null) {
9024            return null;
9025        }
9026        Uri data = intent.getData();
9027        ClipData clip = intent.getClipData();
9028        if (data == null && clip == null) {
9029            return null;
9030        }
9031        // Default userId for uris in the intent (if they don't specify it themselves)
9032        int contentUserHint = intent.getContentUserHint();
9033        if (contentUserHint == UserHandle.USER_CURRENT) {
9034            contentUserHint = UserHandle.getUserId(callingUid);
9035        }
9036        final IPackageManager pm = AppGlobals.getPackageManager();
9037        int targetUid;
9038        if (needed != null) {
9039            targetUid = needed.targetUid;
9040        } else {
9041            try {
9042                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9043                        targetUserId);
9044            } catch (RemoteException ex) {
9045                return null;
9046            }
9047            if (targetUid < 0) {
9048                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9049                        "Can't grant URI permission no uid for: " + targetPkg
9050                        + " on user " + targetUserId);
9051                return null;
9052            }
9053        }
9054        if (data != null) {
9055            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9056            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9057                    targetUid);
9058            if (targetUid > 0) {
9059                if (needed == null) {
9060                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
9061                }
9062                needed.add(grantUri);
9063            }
9064        }
9065        if (clip != null) {
9066            for (int i=0; i<clip.getItemCount(); i++) {
9067                Uri uri = clip.getItemAt(i).getUri();
9068                if (uri != null) {
9069                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9070                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9071                            targetUid);
9072                    if (targetUid > 0) {
9073                        if (needed == null) {
9074                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
9075                        }
9076                        needed.add(grantUri);
9077                    }
9078                } else {
9079                    Intent clipIntent = clip.getItemAt(i).getIntent();
9080                    if (clipIntent != null) {
9081                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9082                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9083                        if (newNeeded != null) {
9084                            needed = newNeeded;
9085                        }
9086                    }
9087                }
9088            }
9089        }
9090
9091        return needed;
9092    }
9093
9094    /**
9095     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9096     */
9097    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9098            UriPermissionOwner owner) {
9099        if (needed != null) {
9100            for (int i=0; i<needed.size(); i++) {
9101                GrantUri grantUri = needed.get(i);
9102                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9103                        grantUri, needed.flags, owner);
9104            }
9105        }
9106    }
9107
9108    void grantUriPermissionFromIntentLocked(int callingUid,
9109            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9110        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9111                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9112        if (needed == null) {
9113            return;
9114        }
9115
9116        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9117    }
9118
9119    /**
9120     * @param uri This uri must NOT contain an embedded userId.
9121     * @param userId The userId in which the uri is to be resolved.
9122     */
9123    @Override
9124    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9125            final int modeFlags, int userId) {
9126        enforceNotIsolatedCaller("grantUriPermission");
9127        GrantUri grantUri = new GrantUri(userId, uri, false);
9128        synchronized(this) {
9129            final ProcessRecord r = getRecordForAppLocked(caller);
9130            if (r == null) {
9131                throw new SecurityException("Unable to find app for caller "
9132                        + caller
9133                        + " when granting permission to uri " + grantUri);
9134            }
9135            if (targetPkg == null) {
9136                throw new IllegalArgumentException("null target");
9137            }
9138            if (grantUri == null) {
9139                throw new IllegalArgumentException("null uri");
9140            }
9141
9142            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9143                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9144                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9145                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9146
9147            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9148                    UserHandle.getUserId(r.uid));
9149        }
9150    }
9151
9152    void removeUriPermissionIfNeededLocked(UriPermission perm) {
9153        if (perm.modeFlags == 0) {
9154            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9155                    perm.targetUid);
9156            if (perms != null) {
9157                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9158                        "Removing " + perm.targetUid + " permission to " + perm.uri);
9159
9160                perms.remove(perm.uri);
9161                if (perms.isEmpty()) {
9162                    mGrantedUriPermissions.remove(perm.targetUid);
9163                }
9164            }
9165        }
9166    }
9167
9168    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9169            final int modeFlags) {
9170        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9171                "Revoking all granted permissions to " + grantUri);
9172
9173        final IPackageManager pm = AppGlobals.getPackageManager();
9174        final String authority = grantUri.uri.getAuthority();
9175        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9176                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9177        if (pi == null) {
9178            Slog.w(TAG, "No content provider found for permission revoke: "
9179                    + grantUri.toSafeString());
9180            return;
9181        }
9182
9183        // Does the caller have this permission on the URI?
9184        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9185            // If they don't have direct access to the URI, then revoke any
9186            // ownerless URI permissions that have been granted to them.
9187            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9188            if (perms != null) {
9189                boolean persistChanged = false;
9190                for (int i = perms.size()-1; i >= 0; i--) {
9191                    final UriPermission perm = perms.valueAt(i);
9192                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9193                        continue;
9194                    }
9195                    if (perm.uri.sourceUserId == grantUri.sourceUserId
9196                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9197                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9198                                "Revoking non-owned " + perm.targetUid
9199                                + " permission to " + perm.uri);
9200                        persistChanged |= perm.revokeModes(
9201                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9202                        if (perm.modeFlags == 0) {
9203                            perms.removeAt(i);
9204                        }
9205                    }
9206                }
9207                if (perms.isEmpty()) {
9208                    mGrantedUriPermissions.remove(callingUid);
9209                }
9210                if (persistChanged) {
9211                    schedulePersistUriGrants();
9212                }
9213            }
9214            return;
9215        }
9216
9217        boolean persistChanged = false;
9218
9219        // Go through all of the permissions and remove any that match.
9220        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9221            final int targetUid = mGrantedUriPermissions.keyAt(i);
9222            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9223
9224            for (int j = perms.size()-1; j >= 0; j--) {
9225                final UriPermission perm = perms.valueAt(j);
9226                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9227                    continue;
9228                }
9229                if (perm.uri.sourceUserId == grantUri.sourceUserId
9230                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9231                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9232                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
9233                    persistChanged |= perm.revokeModes(
9234                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9235                            targetPackage == null);
9236                    if (perm.modeFlags == 0) {
9237                        perms.removeAt(j);
9238                    }
9239                }
9240            }
9241
9242            if (perms.isEmpty()) {
9243                mGrantedUriPermissions.removeAt(i);
9244            }
9245        }
9246
9247        if (persistChanged) {
9248            schedulePersistUriGrants();
9249        }
9250    }
9251
9252    /**
9253     * @param uri This uri must NOT contain an embedded userId.
9254     * @param userId The userId in which the uri is to be resolved.
9255     */
9256    @Override
9257    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9258            final int modeFlags, int userId) {
9259        enforceNotIsolatedCaller("revokeUriPermission");
9260        synchronized(this) {
9261            final ProcessRecord r = getRecordForAppLocked(caller);
9262            if (r == null) {
9263                throw new SecurityException("Unable to find app for caller "
9264                        + caller
9265                        + " when revoking permission to uri " + uri);
9266            }
9267            if (uri == null) {
9268                Slog.w(TAG, "revokeUriPermission: null uri");
9269                return;
9270            }
9271
9272            if (!Intent.isAccessUriMode(modeFlags)) {
9273                return;
9274            }
9275
9276            final String authority = uri.getAuthority();
9277            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9278                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9279            if (pi == null) {
9280                Slog.w(TAG, "No content provider found for permission revoke: "
9281                        + uri.toSafeString());
9282                return;
9283            }
9284
9285            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9286                    modeFlags);
9287        }
9288    }
9289
9290    /**
9291     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9292     * given package.
9293     *
9294     * @param packageName Package name to match, or {@code null} to apply to all
9295     *            packages.
9296     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9297     *            to all users.
9298     * @param persistable If persistable grants should be removed.
9299     */
9300    private void removeUriPermissionsForPackageLocked(
9301            String packageName, int userHandle, boolean persistable) {
9302        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9303            throw new IllegalArgumentException("Must narrow by either package or user");
9304        }
9305
9306        boolean persistChanged = false;
9307
9308        int N = mGrantedUriPermissions.size();
9309        for (int i = 0; i < N; i++) {
9310            final int targetUid = mGrantedUriPermissions.keyAt(i);
9311            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9312
9313            // Only inspect grants matching user
9314            if (userHandle == UserHandle.USER_ALL
9315                    || userHandle == UserHandle.getUserId(targetUid)) {
9316                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9317                    final UriPermission perm = it.next();
9318
9319                    // Only inspect grants matching package
9320                    if (packageName == null || perm.sourcePkg.equals(packageName)
9321                            || perm.targetPkg.equals(packageName)) {
9322                        // Hacky solution as part of fixing a security bug; ignore
9323                        // grants associated with DownloadManager so we don't have
9324                        // to immediately launch it to regrant the permissions
9325                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9326                                && !persistable) continue;
9327
9328                        persistChanged |= perm.revokeModes(persistable
9329                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9330
9331                        // Only remove when no modes remain; any persisted grants
9332                        // will keep this alive.
9333                        if (perm.modeFlags == 0) {
9334                            it.remove();
9335                        }
9336                    }
9337                }
9338
9339                if (perms.isEmpty()) {
9340                    mGrantedUriPermissions.remove(targetUid);
9341                    N--;
9342                    i--;
9343                }
9344            }
9345        }
9346
9347        if (persistChanged) {
9348            schedulePersistUriGrants();
9349        }
9350    }
9351
9352    @Override
9353    public IBinder newUriPermissionOwner(String name) {
9354        enforceNotIsolatedCaller("newUriPermissionOwner");
9355        synchronized(this) {
9356            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9357            return owner.getExternalTokenLocked();
9358        }
9359    }
9360
9361    @Override
9362    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9363        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9364        synchronized(this) {
9365            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9366            if (r == null) {
9367                throw new IllegalArgumentException("Activity does not exist; token="
9368                        + activityToken);
9369            }
9370            return r.getUriPermissionsLocked().getExternalTokenLocked();
9371        }
9372    }
9373    /**
9374     * @param uri This uri must NOT contain an embedded userId.
9375     * @param sourceUserId The userId in which the uri is to be resolved.
9376     * @param targetUserId The userId of the app that receives the grant.
9377     */
9378    @Override
9379    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9380            final int modeFlags, int sourceUserId, int targetUserId) {
9381        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9382                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9383                "grantUriPermissionFromOwner", null);
9384        synchronized(this) {
9385            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9386            if (owner == null) {
9387                throw new IllegalArgumentException("Unknown owner: " + token);
9388            }
9389            if (fromUid != Binder.getCallingUid()) {
9390                if (Binder.getCallingUid() != myUid()) {
9391                    // Only system code can grant URI permissions on behalf
9392                    // of other users.
9393                    throw new SecurityException("nice try");
9394                }
9395            }
9396            if (targetPkg == null) {
9397                throw new IllegalArgumentException("null target");
9398            }
9399            if (uri == null) {
9400                throw new IllegalArgumentException("null uri");
9401            }
9402
9403            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9404                    modeFlags, owner, targetUserId);
9405        }
9406    }
9407
9408    /**
9409     * @param uri This uri must NOT contain an embedded userId.
9410     * @param userId The userId in which the uri is to be resolved.
9411     */
9412    @Override
9413    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9414        synchronized(this) {
9415            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9416            if (owner == null) {
9417                throw new IllegalArgumentException("Unknown owner: " + token);
9418            }
9419
9420            if (uri == null) {
9421                owner.removeUriPermissionsLocked(mode);
9422            } else {
9423                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9424                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9425            }
9426        }
9427    }
9428
9429    private void schedulePersistUriGrants() {
9430        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9431            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9432                    10 * DateUtils.SECOND_IN_MILLIS);
9433        }
9434    }
9435
9436    private void writeGrantedUriPermissions() {
9437        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9438
9439        // Snapshot permissions so we can persist without lock
9440        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9441        synchronized (this) {
9442            final int size = mGrantedUriPermissions.size();
9443            for (int i = 0; i < size; i++) {
9444                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9445                for (UriPermission perm : perms.values()) {
9446                    if (perm.persistedModeFlags != 0) {
9447                        persist.add(perm.snapshot());
9448                    }
9449                }
9450            }
9451        }
9452
9453        FileOutputStream fos = null;
9454        try {
9455            fos = mGrantFile.startWrite();
9456
9457            XmlSerializer out = new FastXmlSerializer();
9458            out.setOutput(fos, StandardCharsets.UTF_8.name());
9459            out.startDocument(null, true);
9460            out.startTag(null, TAG_URI_GRANTS);
9461            for (UriPermission.Snapshot perm : persist) {
9462                out.startTag(null, TAG_URI_GRANT);
9463                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9464                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9465                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9466                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9467                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9468                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9469                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9470                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9471                out.endTag(null, TAG_URI_GRANT);
9472            }
9473            out.endTag(null, TAG_URI_GRANTS);
9474            out.endDocument();
9475
9476            mGrantFile.finishWrite(fos);
9477        } catch (IOException e) {
9478            if (fos != null) {
9479                mGrantFile.failWrite(fos);
9480            }
9481        }
9482    }
9483
9484    private void readGrantedUriPermissionsLocked() {
9485        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9486
9487        final long now = System.currentTimeMillis();
9488
9489        FileInputStream fis = null;
9490        try {
9491            fis = mGrantFile.openRead();
9492            final XmlPullParser in = Xml.newPullParser();
9493            in.setInput(fis, StandardCharsets.UTF_8.name());
9494
9495            int type;
9496            while ((type = in.next()) != END_DOCUMENT) {
9497                final String tag = in.getName();
9498                if (type == START_TAG) {
9499                    if (TAG_URI_GRANT.equals(tag)) {
9500                        final int sourceUserId;
9501                        final int targetUserId;
9502                        final int userHandle = readIntAttribute(in,
9503                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9504                        if (userHandle != UserHandle.USER_NULL) {
9505                            // For backwards compatibility.
9506                            sourceUserId = userHandle;
9507                            targetUserId = userHandle;
9508                        } else {
9509                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9510                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9511                        }
9512                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9513                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9514                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9515                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9516                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9517                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9518
9519                        // Sanity check that provider still belongs to source package
9520                        // Both direct boot aware and unaware packages are fine as we
9521                        // will do filtering at query time to avoid multiple parsing.
9522                        final ProviderInfo pi = getProviderInfoLocked(
9523                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9524                                        | MATCH_DIRECT_BOOT_UNAWARE);
9525                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9526                            int targetUid = -1;
9527                            try {
9528                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9529                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9530                            } catch (RemoteException e) {
9531                            }
9532                            if (targetUid != -1) {
9533                                final UriPermission perm = findOrCreateUriPermissionLocked(
9534                                        sourcePkg, targetPkg, targetUid,
9535                                        new GrantUri(sourceUserId, uri, prefix));
9536                                perm.initPersistedModes(modeFlags, createdTime);
9537                            }
9538                        } else {
9539                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9540                                    + " but instead found " + pi);
9541                        }
9542                    }
9543                }
9544            }
9545        } catch (FileNotFoundException e) {
9546            // Missing grants is okay
9547        } catch (IOException e) {
9548            Slog.wtf(TAG, "Failed reading Uri grants", e);
9549        } catch (XmlPullParserException e) {
9550            Slog.wtf(TAG, "Failed reading Uri grants", e);
9551        } finally {
9552            IoUtils.closeQuietly(fis);
9553        }
9554    }
9555
9556    /**
9557     * @param uri This uri must NOT contain an embedded userId.
9558     * @param userId The userId in which the uri is to be resolved.
9559     */
9560    @Override
9561    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9562        enforceNotIsolatedCaller("takePersistableUriPermission");
9563
9564        Preconditions.checkFlagsArgument(modeFlags,
9565                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9566
9567        synchronized (this) {
9568            final int callingUid = Binder.getCallingUid();
9569            boolean persistChanged = false;
9570            GrantUri grantUri = new GrantUri(userId, uri, false);
9571
9572            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9573                    new GrantUri(userId, uri, false));
9574            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9575                    new GrantUri(userId, uri, true));
9576
9577            final boolean exactValid = (exactPerm != null)
9578                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9579            final boolean prefixValid = (prefixPerm != null)
9580                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9581
9582            if (!(exactValid || prefixValid)) {
9583                throw new SecurityException("No persistable permission grants found for UID "
9584                        + callingUid + " and Uri " + grantUri.toSafeString());
9585            }
9586
9587            if (exactValid) {
9588                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9589            }
9590            if (prefixValid) {
9591                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9592            }
9593
9594            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9595
9596            if (persistChanged) {
9597                schedulePersistUriGrants();
9598            }
9599        }
9600    }
9601
9602    /**
9603     * @param uri This uri must NOT contain an embedded userId.
9604     * @param userId The userId in which the uri is to be resolved.
9605     */
9606    @Override
9607    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9608        enforceNotIsolatedCaller("releasePersistableUriPermission");
9609
9610        Preconditions.checkFlagsArgument(modeFlags,
9611                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9612
9613        synchronized (this) {
9614            final int callingUid = Binder.getCallingUid();
9615            boolean persistChanged = false;
9616
9617            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9618                    new GrantUri(userId, uri, false));
9619            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9620                    new GrantUri(userId, uri, true));
9621            if (exactPerm == null && prefixPerm == null) {
9622                throw new SecurityException("No permission grants found for UID " + callingUid
9623                        + " and Uri " + uri.toSafeString());
9624            }
9625
9626            if (exactPerm != null) {
9627                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9628                removeUriPermissionIfNeededLocked(exactPerm);
9629            }
9630            if (prefixPerm != null) {
9631                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9632                removeUriPermissionIfNeededLocked(prefixPerm);
9633            }
9634
9635            if (persistChanged) {
9636                schedulePersistUriGrants();
9637            }
9638        }
9639    }
9640
9641    /**
9642     * Prune any older {@link UriPermission} for the given UID until outstanding
9643     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9644     *
9645     * @return if any mutations occured that require persisting.
9646     */
9647    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9648        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9649        if (perms == null) return false;
9650        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9651
9652        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9653        for (UriPermission perm : perms.values()) {
9654            if (perm.persistedModeFlags != 0) {
9655                persisted.add(perm);
9656            }
9657        }
9658
9659        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9660        if (trimCount <= 0) return false;
9661
9662        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9663        for (int i = 0; i < trimCount; i++) {
9664            final UriPermission perm = persisted.get(i);
9665
9666            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9667                    "Trimming grant created at " + perm.persistedCreateTime);
9668
9669            perm.releasePersistableModes(~0);
9670            removeUriPermissionIfNeededLocked(perm);
9671        }
9672
9673        return true;
9674    }
9675
9676    @Override
9677    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9678            String packageName, boolean incoming) {
9679        enforceNotIsolatedCaller("getPersistedUriPermissions");
9680        Preconditions.checkNotNull(packageName, "packageName");
9681
9682        final int callingUid = Binder.getCallingUid();
9683        final int callingUserId = UserHandle.getUserId(callingUid);
9684        final IPackageManager pm = AppGlobals.getPackageManager();
9685        try {
9686            final int packageUid = pm.getPackageUid(packageName,
9687                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9688            if (packageUid != callingUid) {
9689                throw new SecurityException(
9690                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9691            }
9692        } catch (RemoteException e) {
9693            throw new SecurityException("Failed to verify package name ownership");
9694        }
9695
9696        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9697        synchronized (this) {
9698            if (incoming) {
9699                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9700                        callingUid);
9701                if (perms == null) {
9702                    Slog.w(TAG, "No permission grants found for " + packageName);
9703                } else {
9704                    for (UriPermission perm : perms.values()) {
9705                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9706                            result.add(perm.buildPersistedPublicApiObject());
9707                        }
9708                    }
9709                }
9710            } else {
9711                final int size = mGrantedUriPermissions.size();
9712                for (int i = 0; i < size; i++) {
9713                    final ArrayMap<GrantUri, UriPermission> perms =
9714                            mGrantedUriPermissions.valueAt(i);
9715                    for (UriPermission perm : perms.values()) {
9716                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9717                            result.add(perm.buildPersistedPublicApiObject());
9718                        }
9719                    }
9720                }
9721            }
9722        }
9723        return new ParceledListSlice<android.content.UriPermission>(result);
9724    }
9725
9726    @Override
9727    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9728            String packageName, int userId) {
9729        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9730                "getGrantedUriPermissions");
9731
9732        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9733        synchronized (this) {
9734            final int size = mGrantedUriPermissions.size();
9735            for (int i = 0; i < size; i++) {
9736                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9737                for (UriPermission perm : perms.values()) {
9738                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9739                            && perm.persistedModeFlags != 0) {
9740                        result.add(perm.buildPersistedPublicApiObject());
9741                    }
9742                }
9743            }
9744        }
9745        return new ParceledListSlice<android.content.UriPermission>(result);
9746    }
9747
9748    @Override
9749    public void clearGrantedUriPermissions(String packageName, int userId) {
9750        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9751                "clearGrantedUriPermissions");
9752        removeUriPermissionsForPackageLocked(packageName, userId, true);
9753    }
9754
9755    @Override
9756    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9757        synchronized (this) {
9758            ProcessRecord app =
9759                who != null ? getRecordForAppLocked(who) : null;
9760            if (app == null) return;
9761
9762            Message msg = Message.obtain();
9763            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9764            msg.obj = app;
9765            msg.arg1 = waiting ? 1 : 0;
9766            mUiHandler.sendMessage(msg);
9767        }
9768    }
9769
9770    @Override
9771    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9772        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9773        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9774        outInfo.availMem = getFreeMemory();
9775        outInfo.totalMem = getTotalMemory();
9776        outInfo.threshold = homeAppMem;
9777        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9778        outInfo.hiddenAppThreshold = cachedAppMem;
9779        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9780                ProcessList.SERVICE_ADJ);
9781        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9782                ProcessList.VISIBLE_APP_ADJ);
9783        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9784                ProcessList.FOREGROUND_APP_ADJ);
9785    }
9786
9787    // =========================================================
9788    // TASK MANAGEMENT
9789    // =========================================================
9790
9791    @Override
9792    public List<IBinder> getAppTasks(String callingPackage) {
9793        int callingUid = Binder.getCallingUid();
9794        long ident = Binder.clearCallingIdentity();
9795        try {
9796            synchronized(this) {
9797                return mRecentTasks.getAppTasksList(callingUid, callingPackage);
9798            }
9799        } finally {
9800            Binder.restoreCallingIdentity(ident);
9801        }
9802    }
9803
9804    @Override
9805    public List<RunningTaskInfo> getTasks(int maxNum) {
9806       return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
9807    }
9808
9809    @Override
9810    public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType,
9811            @WindowingMode int ignoreWindowingMode) {
9812        final int callingUid = Binder.getCallingUid();
9813        ArrayList<RunningTaskInfo> list = new ArrayList<>();
9814
9815        synchronized(this) {
9816            if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
9817
9818            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9819                    callingUid);
9820            mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
9821                    ignoreWindowingMode, callingUid, allowed);
9822        }
9823
9824        return list;
9825    }
9826
9827    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9828        if (mRecentTasks.isCallerRecents(callingUid)) {
9829            // Always allow the recents component to get tasks
9830            return true;
9831        }
9832
9833        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9834                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9835        if (!allowed) {
9836            if (checkPermission(android.Manifest.permission.GET_TASKS,
9837                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9838                // Temporary compatibility: some existing apps on the system image may
9839                // still be requesting the old permission and not switched to the new
9840                // one; if so, we'll still allow them full access.  This means we need
9841                // to see if they are holding the old permission and are a system app.
9842                try {
9843                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9844                        allowed = true;
9845                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9846                                + " is using old GET_TASKS but privileged; allowing");
9847                    }
9848                } catch (RemoteException e) {
9849                }
9850            }
9851        }
9852        if (!allowed) {
9853            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9854                    + " does not hold REAL_GET_TASKS; limiting output");
9855        }
9856        return allowed;
9857    }
9858
9859    @Override
9860    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9861            int userId) {
9862        final int callingUid = Binder.getCallingUid();
9863        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9864                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9865        final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9866                callingUid);
9867        final boolean detailed = checkCallingPermission(
9868                android.Manifest.permission.GET_DETAILED_TASKS)
9869                        == PackageManager.PERMISSION_GRANTED;
9870
9871        synchronized (this) {
9872            return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
9873                    callingUid);
9874        }
9875    }
9876
9877    @Override
9878    public ActivityManager.TaskDescription getTaskDescription(int id) {
9879        synchronized (this) {
9880            enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
9881            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9882                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
9883            if (tr != null) {
9884                return tr.lastTaskDescription;
9885            }
9886        }
9887        return null;
9888    }
9889
9890    @Override
9891    public int addAppTask(IBinder activityToken, Intent intent,
9892            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9893        final int callingUid = Binder.getCallingUid();
9894        final long callingIdent = Binder.clearCallingIdentity();
9895
9896        try {
9897            synchronized (this) {
9898                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9899                if (r == null) {
9900                    throw new IllegalArgumentException("Activity does not exist; token="
9901                            + activityToken);
9902                }
9903                ComponentName comp = intent.getComponent();
9904                if (comp == null) {
9905                    throw new IllegalArgumentException("Intent " + intent
9906                            + " must specify explicit component");
9907                }
9908                if (thumbnail.getWidth() != mThumbnailWidth
9909                        || thumbnail.getHeight() != mThumbnailHeight) {
9910                    throw new IllegalArgumentException("Bad thumbnail size: got "
9911                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9912                            + mThumbnailWidth + "x" + mThumbnailHeight);
9913                }
9914                if (intent.getSelector() != null) {
9915                    intent.setSelector(null);
9916                }
9917                if (intent.getSourceBounds() != null) {
9918                    intent.setSourceBounds(null);
9919                }
9920                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9921                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9922                        // The caller has added this as an auto-remove task...  that makes no
9923                        // sense, so turn off auto-remove.
9924                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9925                    }
9926                }
9927                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9928                    mLastAddedTaskActivity = null;
9929                }
9930                ActivityInfo ainfo = mLastAddedTaskActivity;
9931                if (ainfo == null) {
9932                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9933                            comp, 0, UserHandle.getUserId(callingUid));
9934                    if (ainfo.applicationInfo.uid != callingUid) {
9935                        throw new SecurityException(
9936                                "Can't add task for another application: target uid="
9937                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9938                    }
9939                }
9940
9941                TaskRecord task = new TaskRecord(this,
9942                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9943                        ainfo, intent, description);
9944                if (!mRecentTasks.addToBottom(task)) {
9945                    return INVALID_TASK_ID;
9946                }
9947                r.getStack().addTask(task, !ON_TOP, "addAppTask");
9948
9949                // TODO: Send the thumbnail to WM to store it.
9950
9951                return task.taskId;
9952            }
9953        } finally {
9954            Binder.restoreCallingIdentity(callingIdent);
9955        }
9956    }
9957
9958    @Override
9959    public Point getAppTaskThumbnailSize() {
9960        synchronized (this) {
9961            return new Point(mThumbnailWidth,  mThumbnailHeight);
9962        }
9963    }
9964
9965    @Override
9966    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9967        synchronized (this) {
9968            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9969            if (r != null) {
9970                r.setTaskDescription(td);
9971                final TaskRecord task = r.getTask();
9972                task.updateTaskDescription();
9973                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
9974            }
9975        }
9976    }
9977
9978    @Override
9979    public void setTaskResizeable(int taskId, int resizeableMode) {
9980        synchronized (this) {
9981            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9982                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
9983            if (task == null) {
9984                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9985                return;
9986            }
9987            task.setResizeMode(resizeableMode);
9988        }
9989    }
9990
9991    @Override
9992    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9993        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9994        long ident = Binder.clearCallingIdentity();
9995        try {
9996            synchronized (this) {
9997                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9998                if (task == null) {
9999                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10000                    return;
10001                }
10002                // Place the task in the right stack if it isn't there already based on
10003                // the requested bounds.
10004                // The stack transition logic is:
10005                // - a null bounds on a freeform task moves that task to fullscreen
10006                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10007                //   that task to freeform
10008                // - otherwise the task is not moved
10009                ActivityStack stack = task.getStack();
10010                if (!task.getWindowConfiguration().canResizeTask()) {
10011                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10012                }
10013                if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
10014                    stack = stack.getDisplay().getOrCreateStack(
10015                            WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
10016                } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
10017                    stack = stack.getDisplay().getOrCreateStack(
10018                            WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
10019                }
10020
10021                // Reparent the task to the right stack if necessary
10022                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10023                if (stack != task.getStack()) {
10024                    // Defer resume until the task is resized below
10025                    task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10026                            DEFER_RESUME, "resizeTask");
10027                    preserveWindow = false;
10028                }
10029
10030                // After reparenting (which only resizes the task to the stack bounds), resize the
10031                // task to the actual bounds provided
10032                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10033            }
10034        } finally {
10035            Binder.restoreCallingIdentity(ident);
10036        }
10037    }
10038
10039    @Override
10040    public Rect getTaskBounds(int taskId) {
10041        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10042        long ident = Binder.clearCallingIdentity();
10043        Rect rect = new Rect();
10044        try {
10045            synchronized (this) {
10046                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10047                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10048                if (task == null) {
10049                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10050                    return rect;
10051                }
10052                if (task.getStack() != null) {
10053                    // Return the bounds from window manager since it will be adjusted for various
10054                    // things like the presense of a docked stack for tasks that aren't resizeable.
10055                    task.getWindowContainerBounds(rect);
10056                } else {
10057                    // Task isn't in window manager yet since it isn't associated with a stack.
10058                    // Return the persist value from activity manager
10059                    if (task.mBounds != null) {
10060                        rect.set(task.mBounds);
10061                    } else if (task.mLastNonFullscreenBounds != null) {
10062                        rect.set(task.mLastNonFullscreenBounds);
10063                    }
10064                }
10065            }
10066        } finally {
10067            Binder.restoreCallingIdentity(ident);
10068        }
10069        return rect;
10070    }
10071
10072    @Override
10073    public void cancelTaskWindowTransition(int taskId) {
10074        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10075                "cancelTaskWindowTransition()");
10076        final long ident = Binder.clearCallingIdentity();
10077        try {
10078            synchronized (this) {
10079                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10080                        MATCH_TASK_IN_STACKS_ONLY);
10081                if (task == null) {
10082                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10083                    return;
10084                }
10085                task.cancelWindowTransition();
10086            }
10087        } finally {
10088            Binder.restoreCallingIdentity(ident);
10089        }
10090    }
10091
10092    @Override
10093    public void cancelTaskThumbnailTransition(int taskId) {
10094        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10095                "cancelTaskThumbnailTransition()");
10096        final long ident = Binder.clearCallingIdentity();
10097        try {
10098            synchronized (this) {
10099                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10100                        MATCH_TASK_IN_STACKS_ONLY);
10101                if (task == null) {
10102                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10103                    return;
10104                }
10105                task.cancelThumbnailTransition();
10106            }
10107        } finally {
10108            Binder.restoreCallingIdentity(ident);
10109        }
10110    }
10111
10112    @Override
10113    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10114        enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10115        final long ident = Binder.clearCallingIdentity();
10116        try {
10117            final TaskRecord task;
10118            synchronized (this) {
10119                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10120                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10121                if (task == null) {
10122                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10123                    return null;
10124                }
10125            }
10126            // Don't call this while holding the lock as this operation might hit the disk.
10127            return task.getSnapshot(reducedResolution);
10128        } finally {
10129            Binder.restoreCallingIdentity(ident);
10130        }
10131    }
10132
10133    @Override
10134    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10135        if (userId != UserHandle.getCallingUserId()) {
10136            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10137                    "getTaskDescriptionIcon");
10138        }
10139        final File passedIconFile = new File(filePath);
10140        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10141                passedIconFile.getName());
10142        if (!legitIconFile.getPath().equals(filePath)
10143                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10144            throw new IllegalArgumentException("Bad file path: " + filePath
10145                    + " passed for userId " + userId);
10146        }
10147        return mRecentTasks.getTaskDescriptionIcon(filePath);
10148    }
10149
10150    @Override
10151    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10152            throws RemoteException {
10153        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10154        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10155                activityOptions.getCustomInPlaceResId() == 0) {
10156            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10157                    "with valid animation");
10158        }
10159        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10160        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10161                activityOptions.getCustomInPlaceResId());
10162        mWindowManager.executeAppTransition();
10163    }
10164
10165    @Override
10166    public void removeStack(int stackId) {
10167        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
10168        synchronized (this) {
10169            final long ident = Binder.clearCallingIdentity();
10170            try {
10171                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10172                if (stack == null) {
10173                    Slog.w(TAG, "removeStack: No stack with id=" + stackId);
10174                    return;
10175                }
10176                if (!stack.isActivityTypeStandardOrUndefined()) {
10177                    throw new IllegalArgumentException(
10178                            "Removing non-standard stack is not allowed.");
10179                }
10180                mStackSupervisor.removeStack(stack);
10181            } finally {
10182                Binder.restoreCallingIdentity(ident);
10183            }
10184        }
10185    }
10186
10187    /**
10188     * Removes stacks in the input windowing modes from the system if they are of activity type
10189     * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
10190     */
10191    @Override
10192    public void removeStacksInWindowingModes(int[] windowingModes) {
10193        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10194                "removeStacksInWindowingModes()");
10195        synchronized (this) {
10196            final long ident = Binder.clearCallingIdentity();
10197            try {
10198                mStackSupervisor.removeStacksInWindowingModes(windowingModes);
10199            } finally {
10200                Binder.restoreCallingIdentity(ident);
10201            }
10202        }
10203    }
10204
10205    @Override
10206    public void removeStacksWithActivityTypes(int[] activityTypes) {
10207        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10208                "removeStacksWithActivityTypes()");
10209        synchronized (this) {
10210            final long ident = Binder.clearCallingIdentity();
10211            try {
10212                mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
10213            } finally {
10214                Binder.restoreCallingIdentity(ident);
10215            }
10216        }
10217    }
10218
10219    @Override
10220    public void moveStackToDisplay(int stackId, int displayId) {
10221        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10222
10223        synchronized (this) {
10224            final long ident = Binder.clearCallingIdentity();
10225            try {
10226                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10227                        + " to displayId=" + displayId);
10228                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10229            } finally {
10230                Binder.restoreCallingIdentity(ident);
10231            }
10232        }
10233    }
10234
10235    @Override
10236    public boolean removeTask(int taskId) {
10237        enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
10238        synchronized (this) {
10239            final long ident = Binder.clearCallingIdentity();
10240            try {
10241                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10242            } finally {
10243                Binder.restoreCallingIdentity(ident);
10244            }
10245        }
10246    }
10247
10248    /**
10249     * TODO: Add mController hook
10250     */
10251    @Override
10252    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10253        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10254
10255        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10256        synchronized(this) {
10257            moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10258        }
10259    }
10260
10261    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10262        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10263
10264        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10265                Binder.getCallingUid(), -1, -1, "Task to front")) {
10266            ActivityOptions.abort(options);
10267            return;
10268        }
10269        final long origId = Binder.clearCallingIdentity();
10270        try {
10271            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10272            if (task == null) {
10273                Slog.d(TAG, "Could not find task for id: "+ taskId);
10274                return;
10275            }
10276            if (mLockTaskController.isLockTaskModeViolation(task)) {
10277                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10278                return;
10279            }
10280            mStackSupervisor.findTaskToMoveToFront(task, flags, options, "moveTaskToFront",
10281                    false /* forceNonResizable */);
10282
10283            final ActivityRecord topActivity = task.getTopActivity();
10284            if (topActivity != null) {
10285
10286                // We are reshowing a task, use a starting window to hide the initial draw delay
10287                // so the transition can start earlier.
10288                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10289                        true /* taskSwitch */, fromRecents);
10290            }
10291        } finally {
10292            Binder.restoreCallingIdentity(origId);
10293        }
10294        ActivityOptions.abort(options);
10295    }
10296
10297    /**
10298     * Attempts to move a task backwards in z-order (the order of activities within the task is
10299     * unchanged).
10300     *
10301     * There are several possible results of this call:
10302     * - if the task is locked, then we will show the lock toast
10303     * - if there is a task behind the provided task, then that task is made visible and resumed as
10304     *   this task is moved to the back
10305     * - otherwise, if there are no other tasks in the stack:
10306     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10307     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10308     *       (depending on whether it is visible)
10309     *     - otherwise, we simply return home and hide this task
10310     *
10311     * @param token A reference to the activity we wish to move
10312     * @param nonRoot If false then this only works if the activity is the root
10313     *                of a task; if true it will work for any activity in a task.
10314     * @return Returns true if the move completed, false if not.
10315     */
10316    @Override
10317    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10318        enforceNotIsolatedCaller("moveActivityTaskToBack");
10319        synchronized(this) {
10320            final long origId = Binder.clearCallingIdentity();
10321            try {
10322                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10323                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10324                if (task != null) {
10325                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10326                }
10327            } finally {
10328                Binder.restoreCallingIdentity(origId);
10329            }
10330        }
10331        return false;
10332    }
10333
10334    @Override
10335    public void moveTaskBackwards(int task) {
10336        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10337                "moveTaskBackwards()");
10338
10339        synchronized(this) {
10340            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10341                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10342                return;
10343            }
10344            final long origId = Binder.clearCallingIdentity();
10345            moveTaskBackwardsLocked(task);
10346            Binder.restoreCallingIdentity(origId);
10347        }
10348    }
10349
10350    private final void moveTaskBackwardsLocked(int task) {
10351        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10352    }
10353
10354    @Override
10355    public int createStackOnDisplay(int displayId) throws RemoteException {
10356        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10357        synchronized (this) {
10358            final ActivityDisplay display =
10359                    mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
10360            if (display == null) {
10361                return INVALID_STACK_ID;
10362            }
10363            // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
10364            final ActivityStack stack = display.createStack(
10365                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
10366                    ON_TOP);
10367            return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
10368        }
10369    }
10370
10371    @Override
10372    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10373        synchronized (this) {
10374            final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10375            if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10376                return stack.mDisplayId;
10377            }
10378            return DEFAULT_DISPLAY;
10379        }
10380    }
10381
10382    @Override
10383    public void exitFreeformMode(IBinder token) throws RemoteException {
10384        synchronized (this) {
10385            long ident = Binder.clearCallingIdentity();
10386            try {
10387                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10388                if (r == null) {
10389                    throw new IllegalArgumentException(
10390                            "exitFreeformMode: No activity record matching token=" + token);
10391                }
10392
10393                final ActivityStack stack = r.getStack();
10394                if (stack == null || !stack.inFreeformWindowingMode()) {
10395                    throw new IllegalStateException(
10396                            "exitFreeformMode: You can only go fullscreen from freeform.");
10397                }
10398
10399                final ActivityStack fullscreenStack = stack.getDisplay().getOrCreateStack(
10400                        WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
10401
10402                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10403                // TODO: Should just change windowing mode vs. re-parenting...
10404                r.getTask().reparent(fullscreenStack, ON_TOP,
10405                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10406            } finally {
10407                Binder.restoreCallingIdentity(ident);
10408            }
10409        }
10410    }
10411
10412    @Override
10413    public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
10414        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
10415        synchronized (this) {
10416            final long ident = Binder.clearCallingIdentity();
10417            try {
10418                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10419                if (task == null) {
10420                    Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
10421                    return;
10422                }
10423
10424                if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
10425                        + " to windowingMode=" + windowingMode + " toTop=" + toTop);
10426                if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
10427                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10428                            null /* initialBounds */);
10429                }
10430
10431                if (!task.isActivityTypeStandardOrUndefined()) {
10432                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move task "
10433                            + taskId + " to non-standard windowin mode=" + windowingMode);
10434                }
10435                final ActivityDisplay display = task.getStack().getDisplay();
10436                final ActivityStack stack = display.getOrCreateStack(windowingMode,
10437                        task.getStack().getActivityType(), toTop);
10438                // TODO: We should just change the windowing mode for the task vs. creating and
10439                // moving it to a stack.
10440                task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
10441                        "moveTaskToStack");
10442            } finally {
10443                Binder.restoreCallingIdentity(ident);
10444            }
10445        }
10446    }
10447
10448    @Override
10449    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10450        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10451        synchronized (this) {
10452            long ident = Binder.clearCallingIdentity();
10453            try {
10454                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10455                if (task == null) {
10456                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10457                    return;
10458                }
10459
10460                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10461                        + " to stackId=" + stackId + " toTop=" + toTop);
10462
10463                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10464                if (stack == null) {
10465                    throw new IllegalStateException(
10466                            "moveTaskToStack: No stack for stackId=" + stackId);
10467                }
10468                if (!stack.isActivityTypeStandardOrUndefined()) {
10469                    throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
10470                            + taskId + " to stack " + stackId);
10471                }
10472                if (stack.inSplitScreenPrimaryWindowingMode()) {
10473                    mWindowManager.setDockedStackCreateState(
10474                            DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
10475                }
10476                task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
10477                        "moveTaskToStack");
10478            } finally {
10479                Binder.restoreCallingIdentity(ident);
10480            }
10481        }
10482    }
10483
10484    /**
10485     * Moves the input task to the docked stack.
10486     *
10487     * @param taskId Id of task to move.
10488     * @param createMode The mode the docked stack should be created in if it doesn't exist
10489     *                   already. See
10490     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10491     *                   and
10492     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10493     * @param toTop If the task and stack should be moved to the top.
10494     * @param animate Whether we should play an animation for the moving the task
10495     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10496     *                      docked stack. Pass {@code null} to use default bounds.
10497     */
10498    @Override
10499    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10500            Rect initialBounds) {
10501        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10502        synchronized (this) {
10503            long ident = Binder.clearCallingIdentity();
10504            try {
10505                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10506                if (task == null) {
10507                    Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10508                    return false;
10509                }
10510                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10511                        + " to createMode=" + createMode + " toTop=" + toTop);
10512                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10513
10514                final ActivityDisplay display = task.getStack().getDisplay();
10515                final ActivityStack stack = display.getOrCreateStack(
10516                        WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, task.getStack().getActivityType(),
10517                        toTop);
10518
10519                // Defer resuming until we move the home stack to the front below
10520                // TODO: Should just change windowing mode vs. re-parenting...
10521                final boolean moved = task.reparent(stack, toTop,
10522                        REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10523                        "moveTaskToDockedStack");
10524                if (moved) {
10525                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10526                }
10527                return moved;
10528            } finally {
10529                Binder.restoreCallingIdentity(ident);
10530            }
10531        }
10532    }
10533
10534    /**
10535     * Dismisses split-screen multi-window mode.
10536     * @param toTop If true the current primary split-screen stack will be placed or left on top.
10537     */
10538    @Override
10539    public void dismissSplitScreenMode(boolean toTop) {
10540        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
10541        final long ident = Binder.clearCallingIdentity();
10542        try {
10543            synchronized (this) {
10544                final ActivityStack stack =
10545                        mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
10546                if (stack == null) {
10547                    Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
10548                    return;
10549                }
10550                if (toTop) {
10551                    mStackSupervisor.resizeStackLocked(stack, null /* destBounds */,
10552                            null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
10553                            true /* preserveWindows */, true /* allowResizeInDockedMode */,
10554                            !DEFER_RESUME);
10555                } else {
10556                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, false /* onTop */);
10557                }
10558            }
10559        } finally {
10560            Binder.restoreCallingIdentity(ident);
10561        }
10562    }
10563
10564    /**
10565     * Dismisses Pip
10566     * @param animate True if the dismissal should be animated.
10567     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
10568     *                          default animation duration should be used.
10569     */
10570    @Override
10571    public void dismissPip(boolean animate, int animationDuration) {
10572        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
10573        final long ident = Binder.clearCallingIdentity();
10574        try {
10575            synchronized (this) {
10576                final PinnedActivityStack stack =
10577                        mStackSupervisor.getDefaultDisplay().getPinnedStack();
10578                if (stack == null) {
10579                    Slog.w(TAG, "dismissPip: pinned stack not found.");
10580                    return;
10581                }
10582                if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
10583                    throw new IllegalArgumentException("Stack: " + stack
10584                            + " doesn't support animated resize.");
10585                }
10586                if (animate) {
10587                    stack.animateResizePinnedStack(null /* sourceHintBounds */,
10588                            null /* destBounds */, animationDuration, false /* fromFullscreen */);
10589                } else {
10590                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
10591                }
10592            }
10593        } finally {
10594            Binder.restoreCallingIdentity(ident);
10595        }
10596    }
10597
10598    /**
10599     * Moves the top activity in the input stackId to the pinned stack.
10600     *
10601     * @param stackId Id of stack to move the top activity to pinned stack.
10602     * @param bounds Bounds to use for pinned stack.
10603     *
10604     * @return True if the top activity of the input stack was successfully moved to the pinned
10605     *          stack.
10606     */
10607    @Override
10608    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10609        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10610                "moveTopActivityToPinnedStack()");
10611        synchronized (this) {
10612            if (!mSupportsPictureInPicture) {
10613                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10614                        + "Device doesn't support picture-in-picture mode");
10615            }
10616
10617            long ident = Binder.clearCallingIdentity();
10618            try {
10619                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10620            } finally {
10621                Binder.restoreCallingIdentity(ident);
10622            }
10623        }
10624    }
10625
10626    @Override
10627    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10628            boolean preserveWindows, boolean animate, int animationDuration) {
10629        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10630        long ident = Binder.clearCallingIdentity();
10631        try {
10632            synchronized (this) {
10633                if (animate) {
10634                    final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
10635                    if (stack == null) {
10636                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
10637                        return;
10638                    }
10639                    if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
10640                        throw new IllegalArgumentException("Stack: " + stackId
10641                                + " doesn't support animated resize.");
10642                    }
10643                    stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
10644                            animationDuration, false /* fromFullscreen */);
10645                } else {
10646                    final ActivityStack stack = mStackSupervisor.getStack(stackId);
10647                    if (stack == null) {
10648                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
10649                        return;
10650                    }
10651                    mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
10652                            null /* tempTaskInsetBounds */, preserveWindows,
10653                            allowResizeInDockedMode, !DEFER_RESUME);
10654                }
10655            }
10656        } finally {
10657            Binder.restoreCallingIdentity(ident);
10658        }
10659    }
10660
10661    @Override
10662    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10663            Rect tempDockedTaskInsetBounds,
10664            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10665        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
10666        long ident = Binder.clearCallingIdentity();
10667        try {
10668            synchronized (this) {
10669                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10670                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10671                        PRESERVE_WINDOWS);
10672            }
10673        } finally {
10674            Binder.restoreCallingIdentity(ident);
10675        }
10676    }
10677
10678    @Override
10679    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10680        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
10681        final long ident = Binder.clearCallingIdentity();
10682        try {
10683            synchronized (this) {
10684                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10685            }
10686        } finally {
10687            Binder.restoreCallingIdentity(ident);
10688        }
10689    }
10690
10691    /**
10692     * Try to place task to provided position. The final position might be different depending on
10693     * current user and stacks state. The task will be moved to target stack if it's currently in
10694     * different stack.
10695     */
10696    @Override
10697    public void positionTaskInStack(int taskId, int stackId, int position) {
10698        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10699        synchronized (this) {
10700            long ident = Binder.clearCallingIdentity();
10701            try {
10702                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10703                        + taskId + " in stackId=" + stackId + " at position=" + position);
10704                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10705                if (task == null) {
10706                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10707                            + taskId);
10708                }
10709
10710                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10711
10712                if (stack == null) {
10713                    throw new IllegalArgumentException("positionTaskInStack: no stack for id="
10714                            + stackId);
10715                }
10716                if (!stack.isActivityTypeStandardOrUndefined()) {
10717                    throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
10718                            + " the position of task " + taskId + " in/to non-standard stack");
10719                }
10720
10721                // TODO: Have the callers of this API call a separate reparent method if that is
10722                // what they intended to do vs. having this method also do reparenting.
10723                if (task.getStack() == stack) {
10724                    // Change position in current stack.
10725                    stack.positionChildAt(task, position);
10726                } else {
10727                    // Reparent to new stack.
10728                    task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
10729                            !DEFER_RESUME, "positionTaskInStack");
10730                }
10731            } finally {
10732                Binder.restoreCallingIdentity(ident);
10733            }
10734        }
10735    }
10736
10737    @Override
10738    public List<StackInfo> getAllStackInfos() {
10739        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10740        long ident = Binder.clearCallingIdentity();
10741        try {
10742            synchronized (this) {
10743                return mStackSupervisor.getAllStackInfosLocked();
10744            }
10745        } finally {
10746            Binder.restoreCallingIdentity(ident);
10747        }
10748    }
10749
10750    @Override
10751    public StackInfo getStackInfo(int windowingMode, int activityType) {
10752        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10753        long ident = Binder.clearCallingIdentity();
10754        try {
10755            synchronized (this) {
10756                return mStackSupervisor.getStackInfo(windowingMode, activityType);
10757            }
10758        } finally {
10759            Binder.restoreCallingIdentity(ident);
10760        }
10761    }
10762
10763    @Override
10764    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10765        synchronized(this) {
10766            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10767        }
10768    }
10769
10770    @Override
10771    public void updateDeviceOwner(String packageName) {
10772        final int callingUid = Binder.getCallingUid();
10773        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10774            throw new SecurityException("updateDeviceOwner called from non-system process");
10775        }
10776        synchronized (this) {
10777            mDeviceOwnerName = packageName;
10778        }
10779    }
10780
10781    @Override
10782    public void updateLockTaskPackages(int userId, String[] packages) {
10783        final int callingUid = Binder.getCallingUid();
10784        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10785            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10786                    "updateLockTaskPackages()");
10787        }
10788        synchronized (this) {
10789            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10790                    Arrays.toString(packages));
10791            mLockTaskController.updateLockTaskPackages(userId, packages);
10792        }
10793    }
10794
10795    private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isAppPinning) {
10796        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10797        if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10798            return;
10799        }
10800
10801        final ActivityStack stack = mStackSupervisor.getFocusedStack();
10802        if (stack == null || task != stack.topTask()) {
10803            throw new IllegalArgumentException("Invalid task, not in foreground");
10804        }
10805
10806        // When a task is locked, dismiss the pinned stack if it exists
10807        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
10808
10809        // isAppPinning is used to distinguish between locked and pinned mode, as pinned mode
10810        // is initiated by system after the pinning request was shown and locked mode is initiated
10811        // by an authorized app directly
10812        final int callingUid = Binder.getCallingUid();
10813        long ident = Binder.clearCallingIdentity();
10814        try {
10815            mLockTaskController.startLockTaskMode(task, isAppPinning, callingUid);
10816        } finally {
10817            Binder.restoreCallingIdentity(ident);
10818        }
10819    }
10820
10821    @Override
10822    public void startLockTaskModeByToken(IBinder token) {
10823        synchronized (this) {
10824            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10825            if (r == null) {
10826                return;
10827            }
10828            startLockTaskModeLocked(r.getTask(), false /* not system initiated */);
10829        }
10830    }
10831
10832    @Override
10833    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10834        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10835        // This makes inner call to look as if it was initiated by system.
10836        long ident = Binder.clearCallingIdentity();
10837        try {
10838            synchronized (this) {
10839                startLockTaskModeLocked(mStackSupervisor.anyTaskForIdLocked(taskId),
10840                        true /* system initiated */);
10841            }
10842        } finally {
10843            Binder.restoreCallingIdentity(ident);
10844        }
10845    }
10846
10847    @Override
10848    public void stopLockTaskMode() {
10849        stopLockTaskModeInternal(false /* not system initiated */);
10850    }
10851
10852    /**
10853     * This API should be called by SystemUI only when user perform certain action to dismiss
10854     * lock task mode. We should only dismiss pinned lock task mode in this case.
10855     */
10856    @Override
10857    public void stopSystemLockTaskMode() throws RemoteException {
10858        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
10859        stopLockTaskModeInternal(true /* system initiated */);
10860    }
10861
10862    private void stopLockTaskModeInternal(boolean isSystemRequest) {
10863        final int callingUid = Binder.getCallingUid();
10864        long ident = Binder.clearCallingIdentity();
10865        try {
10866            synchronized (this) {
10867                mLockTaskController.stopLockTaskMode(isSystemRequest, callingUid);
10868            }
10869            // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
10870            // task and jumping straight into a call in the case of emergency call back.
10871            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10872            if (tm != null) {
10873                tm.showInCallScreen(false);
10874            }
10875        } finally {
10876            Binder.restoreCallingIdentity(ident);
10877        }
10878    }
10879
10880    @Override
10881    public boolean isInLockTaskMode() {
10882        return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
10883    }
10884
10885    @Override
10886    public int getLockTaskModeState() {
10887        synchronized (this) {
10888            return mLockTaskController.getLockTaskModeState();
10889        }
10890    }
10891
10892    @Override
10893    public void showLockTaskEscapeMessage(IBinder token) {
10894        synchronized (this) {
10895            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10896            if (r == null) {
10897                return;
10898            }
10899            mLockTaskController.showLockTaskToast();
10900        }
10901    }
10902
10903    @Override
10904    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
10905            throws RemoteException {
10906        synchronized (this) {
10907            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10908            if (r == null) {
10909                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
10910                        + token);
10911                return;
10912            }
10913            final long origId = Binder.clearCallingIdentity();
10914            try {
10915                r.setDisablePreviewScreenshots(disable);
10916            } finally {
10917                Binder.restoreCallingIdentity(origId);
10918            }
10919        }
10920    }
10921
10922    // =========================================================
10923    // CONTENT PROVIDERS
10924    // =========================================================
10925
10926    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10927        List<ProviderInfo> providers = null;
10928        try {
10929            providers = AppGlobals.getPackageManager()
10930                    .queryContentProviders(app.processName, app.uid,
10931                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10932                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
10933                    .getList();
10934        } catch (RemoteException ex) {
10935        }
10936        if (DEBUG_MU) Slog.v(TAG_MU,
10937                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10938        int userId = app.userId;
10939        if (providers != null) {
10940            int N = providers.size();
10941            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10942            for (int i=0; i<N; i++) {
10943                // TODO: keep logic in sync with installEncryptionUnawareProviders
10944                ProviderInfo cpi =
10945                    (ProviderInfo)providers.get(i);
10946                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10947                        cpi.name, cpi.flags);
10948                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10949                    // This is a singleton provider, but a user besides the
10950                    // default user is asking to initialize a process it runs
10951                    // in...  well, no, it doesn't actually run in this process,
10952                    // it runs in the process of the default user.  Get rid of it.
10953                    providers.remove(i);
10954                    N--;
10955                    i--;
10956                    continue;
10957                }
10958
10959                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10960                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10961                if (cpr == null) {
10962                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10963                    mProviderMap.putProviderByClass(comp, cpr);
10964                }
10965                if (DEBUG_MU) Slog.v(TAG_MU,
10966                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10967                app.pubProviders.put(cpi.name, cpr);
10968                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10969                    // Don't add this if it is a platform component that is marked
10970                    // to run in multiple processes, because this is actually
10971                    // part of the framework so doesn't make sense to track as a
10972                    // separate apk in the process.
10973                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10974                            mProcessStats);
10975                }
10976                notifyPackageUse(cpi.applicationInfo.packageName,
10977                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10978            }
10979        }
10980        return providers;
10981    }
10982
10983    /**
10984     * Check if the calling UID has a possible chance at accessing the provider
10985     * at the given authority and user.
10986     */
10987    public String checkContentProviderAccess(String authority, int userId) {
10988        if (userId == UserHandle.USER_ALL) {
10989            mContext.enforceCallingOrSelfPermission(
10990                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10991            userId = UserHandle.getCallingUserId();
10992        }
10993
10994        ProviderInfo cpi = null;
10995        try {
10996            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10997                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10998                            | PackageManager.MATCH_DISABLED_COMPONENTS
10999                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
11000                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11001                    userId);
11002        } catch (RemoteException ignored) {
11003        }
11004        if (cpi == null) {
11005            return "Failed to find provider " + authority + " for user " + userId
11006                    + "; expected to find a valid ContentProvider for this authority";
11007        }
11008
11009        ProcessRecord r = null;
11010        synchronized (mPidsSelfLocked) {
11011            r = mPidsSelfLocked.get(Binder.getCallingPid());
11012        }
11013        if (r == null) {
11014            return "Failed to find PID " + Binder.getCallingPid();
11015        }
11016
11017        synchronized (this) {
11018            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11019        }
11020    }
11021
11022    /**
11023     * Check if {@link ProcessRecord} has a possible chance at accessing the
11024     * given {@link ProviderInfo}. Final permission checking is always done
11025     * in {@link ContentProvider}.
11026     */
11027    private final String checkContentProviderPermissionLocked(
11028            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11029        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11030        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11031        boolean checkedGrants = false;
11032        if (checkUser) {
11033            // Looking for cross-user grants before enforcing the typical cross-users permissions
11034            int tmpTargetUserId = mUserController.unsafeConvertIncomingUser(userId);
11035            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11036                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11037                    return null;
11038                }
11039                checkedGrants = true;
11040            }
11041            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11042                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11043            if (userId != tmpTargetUserId) {
11044                // When we actually went to determine the final targer user ID, this ended
11045                // up different than our initial check for the authority.  This is because
11046                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11047                // SELF.  So we need to re-check the grants again.
11048                checkedGrants = false;
11049            }
11050        }
11051        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11052                cpi.applicationInfo.uid, cpi.exported)
11053                == PackageManager.PERMISSION_GRANTED) {
11054            return null;
11055        }
11056        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11057                cpi.applicationInfo.uid, cpi.exported)
11058                == PackageManager.PERMISSION_GRANTED) {
11059            return null;
11060        }
11061
11062        PathPermission[] pps = cpi.pathPermissions;
11063        if (pps != null) {
11064            int i = pps.length;
11065            while (i > 0) {
11066                i--;
11067                PathPermission pp = pps[i];
11068                String pprperm = pp.getReadPermission();
11069                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11070                        cpi.applicationInfo.uid, cpi.exported)
11071                        == PackageManager.PERMISSION_GRANTED) {
11072                    return null;
11073                }
11074                String ppwperm = pp.getWritePermission();
11075                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11076                        cpi.applicationInfo.uid, cpi.exported)
11077                        == PackageManager.PERMISSION_GRANTED) {
11078                    return null;
11079                }
11080            }
11081        }
11082        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11083            return null;
11084        }
11085
11086        final String suffix;
11087        if (!cpi.exported) {
11088            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11089        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11090            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11091        } else {
11092            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11093        }
11094        final String msg = "Permission Denial: opening provider " + cpi.name
11095                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11096                + ", uid=" + callingUid + ")" + suffix;
11097        Slog.w(TAG, msg);
11098        return msg;
11099    }
11100
11101    /**
11102     * Returns if the ContentProvider has granted a uri to callingUid
11103     */
11104    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11105        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11106        if (perms != null) {
11107            for (int i=perms.size()-1; i>=0; i--) {
11108                GrantUri grantUri = perms.keyAt(i);
11109                if (grantUri.sourceUserId == userId || !checkUser) {
11110                    if (matchesProvider(grantUri.uri, cpi)) {
11111                        return true;
11112                    }
11113                }
11114            }
11115        }
11116        return false;
11117    }
11118
11119    /**
11120     * Returns true if the uri authority is one of the authorities specified in the provider.
11121     */
11122    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11123        String uriAuth = uri.getAuthority();
11124        String cpiAuth = cpi.authority;
11125        if (cpiAuth.indexOf(';') == -1) {
11126            return cpiAuth.equals(uriAuth);
11127        }
11128        String[] cpiAuths = cpiAuth.split(";");
11129        int length = cpiAuths.length;
11130        for (int i = 0; i < length; i++) {
11131            if (cpiAuths[i].equals(uriAuth)) return true;
11132        }
11133        return false;
11134    }
11135
11136    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11137            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11138        if (r != null) {
11139            for (int i=0; i<r.conProviders.size(); i++) {
11140                ContentProviderConnection conn = r.conProviders.get(i);
11141                if (conn.provider == cpr) {
11142                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11143                            "Adding provider requested by "
11144                            + r.processName + " from process "
11145                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11146                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11147                    if (stable) {
11148                        conn.stableCount++;
11149                        conn.numStableIncs++;
11150                    } else {
11151                        conn.unstableCount++;
11152                        conn.numUnstableIncs++;
11153                    }
11154                    return conn;
11155                }
11156            }
11157            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11158            if (stable) {
11159                conn.stableCount = 1;
11160                conn.numStableIncs = 1;
11161            } else {
11162                conn.unstableCount = 1;
11163                conn.numUnstableIncs = 1;
11164            }
11165            cpr.connections.add(conn);
11166            r.conProviders.add(conn);
11167            startAssociationLocked(r.uid, r.processName, r.curProcState,
11168                    cpr.uid, cpr.name, cpr.info.processName);
11169            return conn;
11170        }
11171        cpr.addExternalProcessHandleLocked(externalProcessToken);
11172        return null;
11173    }
11174
11175    boolean decProviderCountLocked(ContentProviderConnection conn,
11176            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11177        if (conn != null) {
11178            cpr = conn.provider;
11179            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11180                    "Removing provider requested by "
11181                    + conn.client.processName + " from process "
11182                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11183                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11184            if (stable) {
11185                conn.stableCount--;
11186            } else {
11187                conn.unstableCount--;
11188            }
11189            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11190                cpr.connections.remove(conn);
11191                conn.client.conProviders.remove(conn);
11192                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11193                    // The client is more important than last activity -- note the time this
11194                    // is happening, so we keep the old provider process around a bit as last
11195                    // activity to avoid thrashing it.
11196                    if (cpr.proc != null) {
11197                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11198                    }
11199                }
11200                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11201                return true;
11202            }
11203            return false;
11204        }
11205        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11206        return false;
11207    }
11208
11209    private void checkTime(long startTime, String where) {
11210        long now = SystemClock.uptimeMillis();
11211        if ((now-startTime) > 50) {
11212            // If we are taking more than 50ms, log about it.
11213            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11214        }
11215    }
11216
11217    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11218            PROC_SPACE_TERM,
11219            PROC_SPACE_TERM|PROC_PARENS,
11220            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11221    };
11222
11223    private final long[] mProcessStateStatsLongs = new long[1];
11224
11225    boolean isProcessAliveLocked(ProcessRecord proc) {
11226        if (proc.procStatFile == null) {
11227            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11228        }
11229        mProcessStateStatsLongs[0] = 0;
11230        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11231                mProcessStateStatsLongs, null)) {
11232            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11233            return false;
11234        }
11235        final long state = mProcessStateStatsLongs[0];
11236        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11237                + (char)state);
11238        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11239    }
11240
11241    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11242            String name, IBinder token, boolean stable, int userId) {
11243        ContentProviderRecord cpr;
11244        ContentProviderConnection conn = null;
11245        ProviderInfo cpi = null;
11246
11247        synchronized(this) {
11248            long startTime = SystemClock.uptimeMillis();
11249
11250            ProcessRecord r = null;
11251            if (caller != null) {
11252                r = getRecordForAppLocked(caller);
11253                if (r == null) {
11254                    throw new SecurityException(
11255                            "Unable to find app for caller " + caller
11256                          + " (pid=" + Binder.getCallingPid()
11257                          + ") when getting content provider " + name);
11258                }
11259            }
11260
11261            boolean checkCrossUser = true;
11262
11263            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11264
11265            // First check if this content provider has been published...
11266            cpr = mProviderMap.getProviderByName(name, userId);
11267            // If that didn't work, check if it exists for user 0 and then
11268            // verify that it's a singleton provider before using it.
11269            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11270                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11271                if (cpr != null) {
11272                    cpi = cpr.info;
11273                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11274                            cpi.name, cpi.flags)
11275                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11276                        userId = UserHandle.USER_SYSTEM;
11277                        checkCrossUser = false;
11278                    } else {
11279                        cpr = null;
11280                        cpi = null;
11281                    }
11282                }
11283            }
11284
11285            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11286            if (providerRunning) {
11287                cpi = cpr.info;
11288                String msg;
11289                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11290                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11291                        != null) {
11292                    throw new SecurityException(msg);
11293                }
11294                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11295
11296                if (r != null && cpr.canRunHere(r)) {
11297                    // This provider has been published or is in the process
11298                    // of being published...  but it is also allowed to run
11299                    // in the caller's process, so don't make a connection
11300                    // and just let the caller instantiate its own instance.
11301                    ContentProviderHolder holder = cpr.newHolder(null);
11302                    // don't give caller the provider object, it needs
11303                    // to make its own.
11304                    holder.provider = null;
11305                    return holder;
11306                }
11307                // Don't expose providers between normal apps and instant apps
11308                try {
11309                    if (AppGlobals.getPackageManager()
11310                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11311                        return null;
11312                    }
11313                } catch (RemoteException e) {
11314                }
11315
11316                final long origId = Binder.clearCallingIdentity();
11317
11318                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11319
11320                // In this case the provider instance already exists, so we can
11321                // return it right away.
11322                conn = incProviderCountLocked(r, cpr, token, stable);
11323                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11324                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11325                        // If this is a perceptible app accessing the provider,
11326                        // make sure to count it as being accessed and thus
11327                        // back up on the LRU list.  This is good because
11328                        // content providers are often expensive to start.
11329                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11330                        updateLruProcessLocked(cpr.proc, false, null);
11331                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11332                    }
11333                }
11334
11335                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11336                final int verifiedAdj = cpr.proc.verifiedAdj;
11337                boolean success = updateOomAdjLocked(cpr.proc, true);
11338                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11339                // if the process has been successfully adjusted.  So to reduce races with
11340                // it, we will check whether the process still exists.  Note that this doesn't
11341                // completely get rid of races with LMK killing the process, but should make
11342                // them much smaller.
11343                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11344                    success = false;
11345                }
11346                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11347                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11348                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11349                // NOTE: there is still a race here where a signal could be
11350                // pending on the process even though we managed to update its
11351                // adj level.  Not sure what to do about this, but at least
11352                // the race is now smaller.
11353                if (!success) {
11354                    // Uh oh...  it looks like the provider's process
11355                    // has been killed on us.  We need to wait for a new
11356                    // process to be started, and make sure its death
11357                    // doesn't kill our process.
11358                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11359                            + " is crashing; detaching " + r);
11360                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11361                    checkTime(startTime, "getContentProviderImpl: before appDied");
11362                    appDiedLocked(cpr.proc);
11363                    checkTime(startTime, "getContentProviderImpl: after appDied");
11364                    if (!lastRef) {
11365                        // This wasn't the last ref our process had on
11366                        // the provider...  we have now been killed, bail.
11367                        return null;
11368                    }
11369                    providerRunning = false;
11370                    conn = null;
11371                } else {
11372                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11373                }
11374
11375                Binder.restoreCallingIdentity(origId);
11376            }
11377
11378            if (!providerRunning) {
11379                try {
11380                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11381                    cpi = AppGlobals.getPackageManager().
11382                        resolveContentProvider(name,
11383                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11384                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11385                } catch (RemoteException ex) {
11386                }
11387                if (cpi == null) {
11388                    return null;
11389                }
11390                // If the provider is a singleton AND
11391                // (it's a call within the same user || the provider is a
11392                // privileged app)
11393                // Then allow connecting to the singleton provider
11394                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11395                        cpi.name, cpi.flags)
11396                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11397                if (singleton) {
11398                    userId = UserHandle.USER_SYSTEM;
11399                }
11400                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11401                checkTime(startTime, "getContentProviderImpl: got app info for user");
11402
11403                String msg;
11404                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11405                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11406                        != null) {
11407                    throw new SecurityException(msg);
11408                }
11409                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11410
11411                if (!mProcessesReady
11412                        && !cpi.processName.equals("system")) {
11413                    // If this content provider does not run in the system
11414                    // process, and the system is not yet ready to run other
11415                    // processes, then fail fast instead of hanging.
11416                    throw new IllegalArgumentException(
11417                            "Attempt to launch content provider before system ready");
11418                }
11419
11420                // Make sure that the user who owns this provider is running.  If not,
11421                // we don't want to allow it to run.
11422                if (!mUserController.isUserRunning(userId, 0)) {
11423                    Slog.w(TAG, "Unable to launch app "
11424                            + cpi.applicationInfo.packageName + "/"
11425                            + cpi.applicationInfo.uid + " for provider "
11426                            + name + ": user " + userId + " is stopped");
11427                    return null;
11428                }
11429
11430                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11431                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11432                cpr = mProviderMap.getProviderByClass(comp, userId);
11433                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11434                final boolean firstClass = cpr == null;
11435                if (firstClass) {
11436                    final long ident = Binder.clearCallingIdentity();
11437
11438                    // If permissions need a review before any of the app components can run,
11439                    // we return no provider and launch a review activity if the calling app
11440                    // is in the foreground.
11441                    if (mPermissionReviewRequired) {
11442                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11443                            return null;
11444                        }
11445                    }
11446
11447                    try {
11448                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11449                        ApplicationInfo ai =
11450                            AppGlobals.getPackageManager().
11451                                getApplicationInfo(
11452                                        cpi.applicationInfo.packageName,
11453                                        STOCK_PM_FLAGS, userId);
11454                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11455                        if (ai == null) {
11456                            Slog.w(TAG, "No package info for content provider "
11457                                    + cpi.name);
11458                            return null;
11459                        }
11460                        ai = getAppInfoForUser(ai, userId);
11461                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11462                    } catch (RemoteException ex) {
11463                        // pm is in same process, this will never happen.
11464                    } finally {
11465                        Binder.restoreCallingIdentity(ident);
11466                    }
11467                }
11468
11469                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11470
11471                if (r != null && cpr.canRunHere(r)) {
11472                    // If this is a multiprocess provider, then just return its
11473                    // info and allow the caller to instantiate it.  Only do
11474                    // this if the provider is the same user as the caller's
11475                    // process, or can run as root (so can be in any process).
11476                    return cpr.newHolder(null);
11477                }
11478
11479                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11480                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11481                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11482
11483                // This is single process, and our app is now connecting to it.
11484                // See if we are already in the process of launching this
11485                // provider.
11486                final int N = mLaunchingProviders.size();
11487                int i;
11488                for (i = 0; i < N; i++) {
11489                    if (mLaunchingProviders.get(i) == cpr) {
11490                        break;
11491                    }
11492                }
11493
11494                // If the provider is not already being launched, then get it
11495                // started.
11496                if (i >= N) {
11497                    final long origId = Binder.clearCallingIdentity();
11498
11499                    try {
11500                        // Content provider is now in use, its package can't be stopped.
11501                        try {
11502                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11503                            AppGlobals.getPackageManager().setPackageStoppedState(
11504                                    cpr.appInfo.packageName, false, userId);
11505                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11506                        } catch (RemoteException e) {
11507                        } catch (IllegalArgumentException e) {
11508                            Slog.w(TAG, "Failed trying to unstop package "
11509                                    + cpr.appInfo.packageName + ": " + e);
11510                        }
11511
11512                        // Use existing process if already started
11513                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11514                        ProcessRecord proc = getProcessRecordLocked(
11515                                cpi.processName, cpr.appInfo.uid, false);
11516                        if (proc != null && proc.thread != null && !proc.killed) {
11517                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11518                                    "Installing in existing process " + proc);
11519                            if (!proc.pubProviders.containsKey(cpi.name)) {
11520                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11521                                proc.pubProviders.put(cpi.name, cpr);
11522                                try {
11523                                    proc.thread.scheduleInstallProvider(cpi);
11524                                } catch (RemoteException e) {
11525                                }
11526                            }
11527                        } else {
11528                            checkTime(startTime, "getContentProviderImpl: before start process");
11529                            proc = startProcessLocked(cpi.processName,
11530                                    cpr.appInfo, false, 0, "content provider",
11531                                    new ComponentName(cpi.applicationInfo.packageName,
11532                                            cpi.name), false, false, false);
11533                            checkTime(startTime, "getContentProviderImpl: after start process");
11534                            if (proc == null) {
11535                                Slog.w(TAG, "Unable to launch app "
11536                                        + cpi.applicationInfo.packageName + "/"
11537                                        + cpi.applicationInfo.uid + " for provider "
11538                                        + name + ": process is bad");
11539                                return null;
11540                            }
11541                        }
11542                        cpr.launchingApp = proc;
11543                        mLaunchingProviders.add(cpr);
11544                    } finally {
11545                        Binder.restoreCallingIdentity(origId);
11546                    }
11547                }
11548
11549                checkTime(startTime, "getContentProviderImpl: updating data structures");
11550
11551                // Make sure the provider is published (the same provider class
11552                // may be published under multiple names).
11553                if (firstClass) {
11554                    mProviderMap.putProviderByClass(comp, cpr);
11555                }
11556
11557                mProviderMap.putProviderByName(name, cpr);
11558                conn = incProviderCountLocked(r, cpr, token, stable);
11559                if (conn != null) {
11560                    conn.waiting = true;
11561                }
11562            }
11563            checkTime(startTime, "getContentProviderImpl: done!");
11564
11565            grantEphemeralAccessLocked(userId, null /*intent*/,
11566                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11567        }
11568
11569        // Wait for the provider to be published...
11570        synchronized (cpr) {
11571            while (cpr.provider == null) {
11572                if (cpr.launchingApp == null) {
11573                    Slog.w(TAG, "Unable to launch app "
11574                            + cpi.applicationInfo.packageName + "/"
11575                            + cpi.applicationInfo.uid + " for provider "
11576                            + name + ": launching app became null");
11577                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11578                            UserHandle.getUserId(cpi.applicationInfo.uid),
11579                            cpi.applicationInfo.packageName,
11580                            cpi.applicationInfo.uid, name);
11581                    return null;
11582                }
11583                try {
11584                    if (DEBUG_MU) Slog.v(TAG_MU,
11585                            "Waiting to start provider " + cpr
11586                            + " launchingApp=" + cpr.launchingApp);
11587                    if (conn != null) {
11588                        conn.waiting = true;
11589                    }
11590                    cpr.wait();
11591                } catch (InterruptedException ex) {
11592                } finally {
11593                    if (conn != null) {
11594                        conn.waiting = false;
11595                    }
11596                }
11597            }
11598        }
11599        return cpr != null ? cpr.newHolder(conn) : null;
11600    }
11601
11602    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11603            ProcessRecord r, final int userId) {
11604        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11605                cpi.packageName, userId)) {
11606
11607            final boolean callerForeground = r == null || r.setSchedGroup
11608                    != ProcessList.SCHED_GROUP_BACKGROUND;
11609
11610            // Show a permission review UI only for starting from a foreground app
11611            if (!callerForeground) {
11612                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11613                        + cpi.packageName + " requires a permissions review");
11614                return false;
11615            }
11616
11617            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11618            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11619                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11620            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11621
11622            if (DEBUG_PERMISSIONS_REVIEW) {
11623                Slog.i(TAG, "u" + userId + " Launching permission review "
11624                        + "for package " + cpi.packageName);
11625            }
11626
11627            final UserHandle userHandle = new UserHandle(userId);
11628            mHandler.post(new Runnable() {
11629                @Override
11630                public void run() {
11631                    mContext.startActivityAsUser(intent, userHandle);
11632                }
11633            });
11634
11635            return false;
11636        }
11637
11638        return true;
11639    }
11640
11641    PackageManagerInternal getPackageManagerInternalLocked() {
11642        if (mPackageManagerInt == null) {
11643            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11644        }
11645        return mPackageManagerInt;
11646    }
11647
11648    @Override
11649    public final ContentProviderHolder getContentProvider(
11650            IApplicationThread caller, String name, int userId, boolean stable) {
11651        enforceNotIsolatedCaller("getContentProvider");
11652        if (caller == null) {
11653            String msg = "null IApplicationThread when getting content provider "
11654                    + name;
11655            Slog.w(TAG, msg);
11656            throw new SecurityException(msg);
11657        }
11658        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11659        // with cross-user grant.
11660        return getContentProviderImpl(caller, name, null, stable, userId);
11661    }
11662
11663    public ContentProviderHolder getContentProviderExternal(
11664            String name, int userId, IBinder token) {
11665        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11666            "Do not have permission in call getContentProviderExternal()");
11667        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11668                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11669        return getContentProviderExternalUnchecked(name, token, userId);
11670    }
11671
11672    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11673            IBinder token, int userId) {
11674        return getContentProviderImpl(null, name, token, true, userId);
11675    }
11676
11677    /**
11678     * Drop a content provider from a ProcessRecord's bookkeeping
11679     */
11680    public void removeContentProvider(IBinder connection, boolean stable) {
11681        enforceNotIsolatedCaller("removeContentProvider");
11682        long ident = Binder.clearCallingIdentity();
11683        try {
11684            synchronized (this) {
11685                ContentProviderConnection conn;
11686                try {
11687                    conn = (ContentProviderConnection)connection;
11688                } catch (ClassCastException e) {
11689                    String msg ="removeContentProvider: " + connection
11690                            + " not a ContentProviderConnection";
11691                    Slog.w(TAG, msg);
11692                    throw new IllegalArgumentException(msg);
11693                }
11694                if (conn == null) {
11695                    throw new NullPointerException("connection is null");
11696                }
11697                if (decProviderCountLocked(conn, null, null, stable)) {
11698                    updateOomAdjLocked();
11699                }
11700            }
11701        } finally {
11702            Binder.restoreCallingIdentity(ident);
11703        }
11704    }
11705
11706    public void removeContentProviderExternal(String name, IBinder token) {
11707        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11708            "Do not have permission in call removeContentProviderExternal()");
11709        int userId = UserHandle.getCallingUserId();
11710        long ident = Binder.clearCallingIdentity();
11711        try {
11712            removeContentProviderExternalUnchecked(name, token, userId);
11713        } finally {
11714            Binder.restoreCallingIdentity(ident);
11715        }
11716    }
11717
11718    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11719        synchronized (this) {
11720            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11721            if(cpr == null) {
11722                //remove from mProvidersByClass
11723                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11724                return;
11725            }
11726
11727            //update content provider record entry info
11728            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11729            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11730            if (localCpr.hasExternalProcessHandles()) {
11731                if (localCpr.removeExternalProcessHandleLocked(token)) {
11732                    updateOomAdjLocked();
11733                } else {
11734                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11735                            + " with no external reference for token: "
11736                            + token + ".");
11737                }
11738            } else {
11739                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11740                        + " with no external references.");
11741            }
11742        }
11743    }
11744
11745    public final void publishContentProviders(IApplicationThread caller,
11746            List<ContentProviderHolder> providers) {
11747        if (providers == null) {
11748            return;
11749        }
11750
11751        enforceNotIsolatedCaller("publishContentProviders");
11752        synchronized (this) {
11753            final ProcessRecord r = getRecordForAppLocked(caller);
11754            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11755            if (r == null) {
11756                throw new SecurityException(
11757                        "Unable to find app for caller " + caller
11758                      + " (pid=" + Binder.getCallingPid()
11759                      + ") when publishing content providers");
11760            }
11761
11762            final long origId = Binder.clearCallingIdentity();
11763
11764            final int N = providers.size();
11765            for (int i = 0; i < N; i++) {
11766                ContentProviderHolder src = providers.get(i);
11767                if (src == null || src.info == null || src.provider == null) {
11768                    continue;
11769                }
11770                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11771                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11772                if (dst != null) {
11773                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11774                    mProviderMap.putProviderByClass(comp, dst);
11775                    String names[] = dst.info.authority.split(";");
11776                    for (int j = 0; j < names.length; j++) {
11777                        mProviderMap.putProviderByName(names[j], dst);
11778                    }
11779
11780                    int launchingCount = mLaunchingProviders.size();
11781                    int j;
11782                    boolean wasInLaunchingProviders = false;
11783                    for (j = 0; j < launchingCount; j++) {
11784                        if (mLaunchingProviders.get(j) == dst) {
11785                            mLaunchingProviders.remove(j);
11786                            wasInLaunchingProviders = true;
11787                            j--;
11788                            launchingCount--;
11789                        }
11790                    }
11791                    if (wasInLaunchingProviders) {
11792                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11793                    }
11794                    synchronized (dst) {
11795                        dst.provider = src.provider;
11796                        dst.proc = r;
11797                        dst.notifyAll();
11798                    }
11799                    updateOomAdjLocked(r, true);
11800                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11801                            src.info.authority);
11802                }
11803            }
11804
11805            Binder.restoreCallingIdentity(origId);
11806        }
11807    }
11808
11809    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11810        ContentProviderConnection conn;
11811        try {
11812            conn = (ContentProviderConnection)connection;
11813        } catch (ClassCastException e) {
11814            String msg ="refContentProvider: " + connection
11815                    + " not a ContentProviderConnection";
11816            Slog.w(TAG, msg);
11817            throw new IllegalArgumentException(msg);
11818        }
11819        if (conn == null) {
11820            throw new NullPointerException("connection is null");
11821        }
11822
11823        synchronized (this) {
11824            if (stable > 0) {
11825                conn.numStableIncs += stable;
11826            }
11827            stable = conn.stableCount + stable;
11828            if (stable < 0) {
11829                throw new IllegalStateException("stableCount < 0: " + stable);
11830            }
11831
11832            if (unstable > 0) {
11833                conn.numUnstableIncs += unstable;
11834            }
11835            unstable = conn.unstableCount + unstable;
11836            if (unstable < 0) {
11837                throw new IllegalStateException("unstableCount < 0: " + unstable);
11838            }
11839
11840            if ((stable+unstable) <= 0) {
11841                throw new IllegalStateException("ref counts can't go to zero here: stable="
11842                        + stable + " unstable=" + unstable);
11843            }
11844            conn.stableCount = stable;
11845            conn.unstableCount = unstable;
11846            return !conn.dead;
11847        }
11848    }
11849
11850    public void unstableProviderDied(IBinder connection) {
11851        ContentProviderConnection conn;
11852        try {
11853            conn = (ContentProviderConnection)connection;
11854        } catch (ClassCastException e) {
11855            String msg ="refContentProvider: " + connection
11856                    + " not a ContentProviderConnection";
11857            Slog.w(TAG, msg);
11858            throw new IllegalArgumentException(msg);
11859        }
11860        if (conn == null) {
11861            throw new NullPointerException("connection is null");
11862        }
11863
11864        // Safely retrieve the content provider associated with the connection.
11865        IContentProvider provider;
11866        synchronized (this) {
11867            provider = conn.provider.provider;
11868        }
11869
11870        if (provider == null) {
11871            // Um, yeah, we're way ahead of you.
11872            return;
11873        }
11874
11875        // Make sure the caller is being honest with us.
11876        if (provider.asBinder().pingBinder()) {
11877            // Er, no, still looks good to us.
11878            synchronized (this) {
11879                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11880                        + " says " + conn + " died, but we don't agree");
11881                return;
11882            }
11883        }
11884
11885        // Well look at that!  It's dead!
11886        synchronized (this) {
11887            if (conn.provider.provider != provider) {
11888                // But something changed...  good enough.
11889                return;
11890            }
11891
11892            ProcessRecord proc = conn.provider.proc;
11893            if (proc == null || proc.thread == null) {
11894                // Seems like the process is already cleaned up.
11895                return;
11896            }
11897
11898            // As far as we're concerned, this is just like receiving a
11899            // death notification...  just a bit prematurely.
11900            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11901                    + ") early provider death");
11902            final long ident = Binder.clearCallingIdentity();
11903            try {
11904                appDiedLocked(proc);
11905            } finally {
11906                Binder.restoreCallingIdentity(ident);
11907            }
11908        }
11909    }
11910
11911    @Override
11912    public void appNotRespondingViaProvider(IBinder connection) {
11913        enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
11914
11915        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11916        if (conn == null) {
11917            Slog.w(TAG, "ContentProviderConnection is null");
11918            return;
11919        }
11920
11921        final ProcessRecord host = conn.provider.proc;
11922        if (host == null) {
11923            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11924            return;
11925        }
11926
11927        mHandler.post(new Runnable() {
11928            @Override
11929            public void run() {
11930                mAppErrors.appNotResponding(host, null, null, false,
11931                        "ContentProvider not responding");
11932            }
11933        });
11934    }
11935
11936    public final void installSystemProviders() {
11937        List<ProviderInfo> providers;
11938        synchronized (this) {
11939            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
11940            providers = generateApplicationProvidersLocked(app);
11941            if (providers != null) {
11942                for (int i=providers.size()-1; i>=0; i--) {
11943                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11944                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11945                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11946                                + ": not system .apk");
11947                        providers.remove(i);
11948                    }
11949                }
11950            }
11951        }
11952        if (providers != null) {
11953            mSystemThread.installSystemProviders(providers);
11954        }
11955
11956        mConstants.start(mContext.getContentResolver());
11957        mCoreSettingsObserver = new CoreSettingsObserver(this);
11958        mFontScaleSettingObserver = new FontScaleSettingObserver();
11959
11960        // Now that the settings provider is published we can consider sending
11961        // in a rescue party.
11962        RescueParty.onSettingsProviderPublished(mContext);
11963
11964        //mUsageStatsService.monitorPackages();
11965    }
11966
11967    void startPersistentApps(int matchFlags) {
11968        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11969
11970        synchronized (this) {
11971            try {
11972                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11973                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11974                for (ApplicationInfo app : apps) {
11975                    if (!"android".equals(app.packageName)) {
11976                        addAppLocked(app, null, false, null /* ABI override */);
11977                    }
11978                }
11979            } catch (RemoteException ex) {
11980            }
11981        }
11982    }
11983
11984    /**
11985     * When a user is unlocked, we need to install encryption-unaware providers
11986     * belonging to any running apps.
11987     */
11988    void installEncryptionUnawareProviders(int userId) {
11989        // We're only interested in providers that are encryption unaware, and
11990        // we don't care about uninstalled apps, since there's no way they're
11991        // running at this point.
11992        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11993
11994        synchronized (this) {
11995            final int NP = mProcessNames.getMap().size();
11996            for (int ip = 0; ip < NP; ip++) {
11997                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11998                final int NA = apps.size();
11999                for (int ia = 0; ia < NA; ia++) {
12000                    final ProcessRecord app = apps.valueAt(ia);
12001                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
12002
12003                    final int NG = app.pkgList.size();
12004                    for (int ig = 0; ig < NG; ig++) {
12005                        try {
12006                            final String pkgName = app.pkgList.keyAt(ig);
12007                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12008                                    .getPackageInfo(pkgName, matchFlags, userId);
12009                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12010                                for (ProviderInfo pi : pkgInfo.providers) {
12011                                    // TODO: keep in sync with generateApplicationProvidersLocked
12012                                    final boolean processMatch = Objects.equals(pi.processName,
12013                                            app.processName) || pi.multiprocess;
12014                                    final boolean userMatch = isSingleton(pi.processName,
12015                                            pi.applicationInfo, pi.name, pi.flags)
12016                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12017                                    if (processMatch && userMatch) {
12018                                        Log.v(TAG, "Installing " + pi);
12019                                        app.thread.scheduleInstallProvider(pi);
12020                                    } else {
12021                                        Log.v(TAG, "Skipping " + pi);
12022                                    }
12023                                }
12024                            }
12025                        } catch (RemoteException ignored) {
12026                        }
12027                    }
12028                }
12029            }
12030        }
12031    }
12032
12033    /**
12034     * Allows apps to retrieve the MIME type of a URI.
12035     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12036     * users, then it does not need permission to access the ContentProvider.
12037     * Either, it needs cross-user uri grants.
12038     *
12039     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12040     *
12041     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12042     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12043     */
12044    public String getProviderMimeType(Uri uri, int userId) {
12045        enforceNotIsolatedCaller("getProviderMimeType");
12046        final String name = uri.getAuthority();
12047        int callingUid = Binder.getCallingUid();
12048        int callingPid = Binder.getCallingPid();
12049        long ident = 0;
12050        boolean clearedIdentity = false;
12051        userId = mUserController.unsafeConvertIncomingUser(userId);
12052        if (canClearIdentity(callingPid, callingUid, userId)) {
12053            clearedIdentity = true;
12054            ident = Binder.clearCallingIdentity();
12055        }
12056        ContentProviderHolder holder = null;
12057        try {
12058            holder = getContentProviderExternalUnchecked(name, null, userId);
12059            if (holder != null) {
12060                return holder.provider.getType(uri);
12061            }
12062        } catch (RemoteException e) {
12063            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12064            return null;
12065        } catch (Exception e) {
12066            Log.w(TAG, "Exception while determining type of " + uri, e);
12067            return null;
12068        } finally {
12069            // We need to clear the identity to call removeContentProviderExternalUnchecked
12070            if (!clearedIdentity) {
12071                ident = Binder.clearCallingIdentity();
12072            }
12073            try {
12074                if (holder != null) {
12075                    removeContentProviderExternalUnchecked(name, null, userId);
12076                }
12077            } finally {
12078                Binder.restoreCallingIdentity(ident);
12079            }
12080        }
12081
12082        return null;
12083    }
12084
12085    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12086        if (UserHandle.getUserId(callingUid) == userId) {
12087            return true;
12088        }
12089        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12090                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12091                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12092                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12093                return true;
12094        }
12095        return false;
12096    }
12097
12098    // =========================================================
12099    // GLOBAL MANAGEMENT
12100    // =========================================================
12101
12102    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12103            boolean isolated, int isolatedUid) {
12104        String proc = customProcess != null ? customProcess : info.processName;
12105        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12106        final int userId = UserHandle.getUserId(info.uid);
12107        int uid = info.uid;
12108        if (isolated) {
12109            if (isolatedUid == 0) {
12110                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12111                while (true) {
12112                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12113                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12114                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12115                    }
12116                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12117                    mNextIsolatedProcessUid++;
12118                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12119                        // No process for this uid, use it.
12120                        break;
12121                    }
12122                    stepsLeft--;
12123                    if (stepsLeft <= 0) {
12124                        return null;
12125                    }
12126                }
12127            } else {
12128                // Special case for startIsolatedProcess (internal only), where
12129                // the uid of the isolated process is specified by the caller.
12130                uid = isolatedUid;
12131            }
12132            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12133
12134            // Register the isolated UID with this application so BatteryStats knows to
12135            // attribute resource usage to the application.
12136            //
12137            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12138            // about the process state of the isolated UID *before* it is registered with the
12139            // owning application.
12140            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12141        }
12142        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12143        if (!mBooted && !mBooting
12144                && userId == UserHandle.USER_SYSTEM
12145                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12146            r.persistent = true;
12147            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12148        }
12149        if (isolated && isolatedUid != 0) {
12150            // Special case for startIsolatedProcess (internal only) - assume the process
12151            // is required by the system server to prevent it being killed.
12152            r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
12153        }
12154        addProcessNameLocked(r);
12155        return r;
12156    }
12157
12158    private boolean uidOnBackgroundWhitelist(final int uid) {
12159        final int appId = UserHandle.getAppId(uid);
12160        final int[] whitelist = mBackgroundAppIdWhitelist;
12161        final int N = whitelist.length;
12162        for (int i = 0; i < N; i++) {
12163            if (appId == whitelist[i]) {
12164                return true;
12165            }
12166        }
12167        return false;
12168    }
12169
12170    @Override
12171    public void backgroundWhitelistUid(final int uid) {
12172        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12173            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12174        }
12175
12176        if (DEBUG_BACKGROUND_CHECK) {
12177            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12178        }
12179        synchronized (this) {
12180            final int N = mBackgroundAppIdWhitelist.length;
12181            int[] newList = new int[N+1];
12182            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12183            newList[N] = UserHandle.getAppId(uid);
12184            mBackgroundAppIdWhitelist = newList;
12185        }
12186    }
12187
12188    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12189            String abiOverride) {
12190        ProcessRecord app;
12191        if (!isolated) {
12192            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12193                    info.uid, true);
12194        } else {
12195            app = null;
12196        }
12197
12198        if (app == null) {
12199            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12200            updateLruProcessLocked(app, false, null);
12201            updateOomAdjLocked();
12202        }
12203
12204        // This package really, really can not be stopped.
12205        try {
12206            AppGlobals.getPackageManager().setPackageStoppedState(
12207                    info.packageName, false, UserHandle.getUserId(app.uid));
12208        } catch (RemoteException e) {
12209        } catch (IllegalArgumentException e) {
12210            Slog.w(TAG, "Failed trying to unstop package "
12211                    + info.packageName + ": " + e);
12212        }
12213
12214        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12215            app.persistent = true;
12216            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12217        }
12218        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12219            mPersistentStartingProcesses.add(app);
12220            startProcessLocked(app, "added application",
12221                    customProcess != null ? customProcess : app.processName, abiOverride);
12222        }
12223
12224        return app;
12225    }
12226
12227    public void unhandledBack() {
12228        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12229                "unhandledBack()");
12230
12231        synchronized(this) {
12232            final long origId = Binder.clearCallingIdentity();
12233            try {
12234                getFocusedStack().unhandledBackLocked();
12235            } finally {
12236                Binder.restoreCallingIdentity(origId);
12237            }
12238        }
12239    }
12240
12241    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12242        enforceNotIsolatedCaller("openContentUri");
12243        final int userId = UserHandle.getCallingUserId();
12244        final Uri uri = Uri.parse(uriString);
12245        String name = uri.getAuthority();
12246        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12247        ParcelFileDescriptor pfd = null;
12248        if (cph != null) {
12249            // We record the binder invoker's uid in thread-local storage before
12250            // going to the content provider to open the file.  Later, in the code
12251            // that handles all permissions checks, we look for this uid and use
12252            // that rather than the Activity Manager's own uid.  The effect is that
12253            // we do the check against the caller's permissions even though it looks
12254            // to the content provider like the Activity Manager itself is making
12255            // the request.
12256            Binder token = new Binder();
12257            sCallerIdentity.set(new Identity(
12258                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12259            try {
12260                pfd = cph.provider.openFile(null, uri, "r", null, token);
12261            } catch (FileNotFoundException e) {
12262                // do nothing; pfd will be returned null
12263            } finally {
12264                // Ensure that whatever happens, we clean up the identity state
12265                sCallerIdentity.remove();
12266                // Ensure we're done with the provider.
12267                removeContentProviderExternalUnchecked(name, null, userId);
12268            }
12269        } else {
12270            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12271        }
12272        return pfd;
12273    }
12274
12275    // Actually is sleeping or shutting down or whatever else in the future
12276    // is an inactive state.
12277    boolean isSleepingOrShuttingDownLocked() {
12278        return isSleepingLocked() || mShuttingDown;
12279    }
12280
12281    boolean isShuttingDownLocked() {
12282        return mShuttingDown;
12283    }
12284
12285    boolean isSleepingLocked() {
12286        return mSleeping;
12287    }
12288
12289    void onWakefulnessChanged(int wakefulness) {
12290        synchronized(this) {
12291            boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12292            boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12293            mWakefulness = wakefulness;
12294
12295            if (wasAwake != isAwake) {
12296                // Also update state in a special way for running foreground services UI.
12297                mServices.updateScreenStateLocked(isAwake);
12298                sendNotifyVrManagerOfSleepState(!isAwake);
12299            }
12300        }
12301    }
12302
12303    void finishRunningVoiceLocked() {
12304        if (mRunningVoice != null) {
12305            mRunningVoice = null;
12306            mVoiceWakeLock.release();
12307            updateSleepIfNeededLocked();
12308        }
12309    }
12310
12311    void startTimeTrackingFocusedActivityLocked() {
12312        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12313        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12314            mCurAppTimeTracker.start(resumedActivity.packageName);
12315        }
12316    }
12317
12318    void updateSleepIfNeededLocked() {
12319        final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12320        final boolean wasSleeping = mSleeping;
12321
12322        if (!shouldSleep) {
12323            // If wasSleeping is true, we need to wake up activity manager state from when
12324            // we started sleeping. In either case, we need to apply the sleep tokens, which
12325            // will wake up stacks or put them to sleep as appropriate.
12326            if (wasSleeping) {
12327                mSleeping = false;
12328                startTimeTrackingFocusedActivityLocked();
12329                mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12330                mStackSupervisor.comeOutOfSleepIfNeededLocked();
12331            }
12332            mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12333            if (wasSleeping) {
12334                updateOomAdjLocked();
12335            }
12336        } else if (!mSleeping && shouldSleep) {
12337            mSleeping = true;
12338            if (mCurAppTimeTracker != null) {
12339                mCurAppTimeTracker.stop();
12340            }
12341            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12342            mStackSupervisor.goingToSleepLocked();
12343            updateOomAdjLocked();
12344        }
12345    }
12346
12347    /** Pokes the task persister. */
12348    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12349        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12350    }
12351
12352    /**
12353     * Notifies all listeners when the pinned stack animation starts.
12354     */
12355    @Override
12356    public void notifyPinnedStackAnimationStarted() {
12357        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12358    }
12359
12360    /**
12361     * Notifies all listeners when the pinned stack animation ends.
12362     */
12363    @Override
12364    public void notifyPinnedStackAnimationEnded() {
12365        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12366    }
12367
12368    @Override
12369    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12370        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12371    }
12372
12373    @Override
12374    public boolean shutdown(int timeout) {
12375        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12376                != PackageManager.PERMISSION_GRANTED) {
12377            throw new SecurityException("Requires permission "
12378                    + android.Manifest.permission.SHUTDOWN);
12379        }
12380
12381        // TODO: Where should the corresponding '1' (start) write go?
12382        StatsLog.write(StatsLog.DEVICE_ON_STATUS_CHANGED, 0);
12383
12384        boolean timedout = false;
12385
12386        synchronized(this) {
12387            mShuttingDown = true;
12388            mStackSupervisor.prepareForShutdownLocked();
12389            updateEventDispatchingLocked();
12390            timedout = mStackSupervisor.shutdownLocked(timeout);
12391        }
12392
12393        mAppOpsService.shutdown();
12394        if (mUsageStatsService != null) {
12395            mUsageStatsService.prepareShutdown();
12396        }
12397        mBatteryStatsService.shutdown();
12398        synchronized (this) {
12399            mProcessStats.shutdownLocked();
12400            notifyTaskPersisterLocked(null, true);
12401        }
12402
12403        return timedout;
12404    }
12405
12406    public final void activitySlept(IBinder token) {
12407        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12408
12409        final long origId = Binder.clearCallingIdentity();
12410
12411        synchronized (this) {
12412            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12413            if (r != null) {
12414                mStackSupervisor.activitySleptLocked(r);
12415            }
12416        }
12417
12418        Binder.restoreCallingIdentity(origId);
12419    }
12420
12421    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12422        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12423        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12424        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12425            boolean wasRunningVoice = mRunningVoice != null;
12426            mRunningVoice = session;
12427            if (!wasRunningVoice) {
12428                mVoiceWakeLock.acquire();
12429                updateSleepIfNeededLocked();
12430            }
12431        }
12432    }
12433
12434    private void updateEventDispatchingLocked() {
12435        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12436    }
12437
12438    @Override
12439    public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12440        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12441                != PackageManager.PERMISSION_GRANTED) {
12442            throw new SecurityException("Requires permission "
12443                    + android.Manifest.permission.DEVICE_POWER);
12444        }
12445
12446        synchronized(this) {
12447            long ident = Binder.clearCallingIdentity();
12448            try {
12449                mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12450            } finally {
12451                Binder.restoreCallingIdentity(ident);
12452            }
12453        }
12454        sendNotifyVrManagerOfKeyguardState(showing);
12455    }
12456
12457    @Override
12458    public void notifyLockedProfile(@UserIdInt int userId) {
12459        try {
12460            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12461                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12462            }
12463        } catch (RemoteException ex) {
12464            throw new SecurityException("Fail to check is caller a privileged app", ex);
12465        }
12466
12467        synchronized (this) {
12468            final long ident = Binder.clearCallingIdentity();
12469            try {
12470                if (mUserController.shouldConfirmCredentials(userId)) {
12471                    if (mKeyguardController.isKeyguardLocked()) {
12472                        // Showing launcher to avoid user entering credential twice.
12473                        final int currentUserId = mUserController.getCurrentUserId();
12474                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12475                    }
12476                    mStackSupervisor.lockAllProfileTasks(userId);
12477                }
12478            } finally {
12479                Binder.restoreCallingIdentity(ident);
12480            }
12481        }
12482    }
12483
12484    @Override
12485    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12486        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12487        synchronized (this) {
12488            final long ident = Binder.clearCallingIdentity();
12489            try {
12490                mActivityStarter.startConfirmCredentialIntent(intent, options);
12491            } finally {
12492                Binder.restoreCallingIdentity(ident);
12493            }
12494        }
12495    }
12496
12497    @Override
12498    public void stopAppSwitches() {
12499        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12500                != PackageManager.PERMISSION_GRANTED) {
12501            throw new SecurityException("viewquires permission "
12502                    + android.Manifest.permission.STOP_APP_SWITCHES);
12503        }
12504
12505        synchronized(this) {
12506            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12507                    + APP_SWITCH_DELAY_TIME;
12508            mDidAppSwitch = false;
12509            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12510            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12511            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12512        }
12513    }
12514
12515    public void resumeAppSwitches() {
12516        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12517                != PackageManager.PERMISSION_GRANTED) {
12518            throw new SecurityException("Requires permission "
12519                    + android.Manifest.permission.STOP_APP_SWITCHES);
12520        }
12521
12522        synchronized(this) {
12523            // Note that we don't execute any pending app switches... we will
12524            // let those wait until either the timeout, or the next start
12525            // activity request.
12526            mAppSwitchesAllowedTime = 0;
12527        }
12528    }
12529
12530    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12531            int callingPid, int callingUid, String name) {
12532        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12533            return true;
12534        }
12535
12536        int perm = checkComponentPermission(
12537                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12538                sourceUid, -1, true);
12539        if (perm == PackageManager.PERMISSION_GRANTED) {
12540            return true;
12541        }
12542
12543        // If the actual IPC caller is different from the logical source, then
12544        // also see if they are allowed to control app switches.
12545        if (callingUid != -1 && callingUid != sourceUid) {
12546            perm = checkComponentPermission(
12547                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12548                    callingUid, -1, true);
12549            if (perm == PackageManager.PERMISSION_GRANTED) {
12550                return true;
12551            }
12552        }
12553
12554        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12555        return false;
12556    }
12557
12558    public void setDebugApp(String packageName, boolean waitForDebugger,
12559            boolean persistent) {
12560        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12561                "setDebugApp()");
12562
12563        long ident = Binder.clearCallingIdentity();
12564        try {
12565            // Note that this is not really thread safe if there are multiple
12566            // callers into it at the same time, but that's not a situation we
12567            // care about.
12568            if (persistent) {
12569                final ContentResolver resolver = mContext.getContentResolver();
12570                Settings.Global.putString(
12571                    resolver, Settings.Global.DEBUG_APP,
12572                    packageName);
12573                Settings.Global.putInt(
12574                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12575                    waitForDebugger ? 1 : 0);
12576            }
12577
12578            synchronized (this) {
12579                if (!persistent) {
12580                    mOrigDebugApp = mDebugApp;
12581                    mOrigWaitForDebugger = mWaitForDebugger;
12582                }
12583                mDebugApp = packageName;
12584                mWaitForDebugger = waitForDebugger;
12585                mDebugTransient = !persistent;
12586                if (packageName != null) {
12587                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12588                            false, UserHandle.USER_ALL, "set debug app");
12589                }
12590            }
12591        } finally {
12592            Binder.restoreCallingIdentity(ident);
12593        }
12594    }
12595
12596    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12597        synchronized (this) {
12598            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12599            if (!isDebuggable) {
12600                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12601                    throw new SecurityException("Process not debuggable: " + app.packageName);
12602                }
12603            }
12604
12605            mTrackAllocationApp = processName;
12606        }
12607    }
12608
12609    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12610        synchronized (this) {
12611            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12612            if (!isDebuggable) {
12613                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12614                    throw new SecurityException("Process not debuggable: " + app.packageName);
12615                }
12616            }
12617            mProfileApp = processName;
12618
12619            if (mProfilerInfo != null) {
12620                if (mProfilerInfo.profileFd != null) {
12621                    try {
12622                        mProfilerInfo.profileFd.close();
12623                    } catch (IOException e) {
12624                    }
12625                }
12626            }
12627            mProfilerInfo = new ProfilerInfo(profilerInfo);
12628            mProfileType = 0;
12629        }
12630    }
12631
12632    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12633        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12634        if (!isDebuggable) {
12635            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12636                throw new SecurityException("Process not debuggable: " + app.packageName);
12637            }
12638        }
12639        mNativeDebuggingApp = processName;
12640    }
12641
12642    @Override
12643    public void setAlwaysFinish(boolean enabled) {
12644        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12645                "setAlwaysFinish()");
12646
12647        long ident = Binder.clearCallingIdentity();
12648        try {
12649            Settings.Global.putInt(
12650                    mContext.getContentResolver(),
12651                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12652
12653            synchronized (this) {
12654                mAlwaysFinishActivities = enabled;
12655            }
12656        } finally {
12657            Binder.restoreCallingIdentity(ident);
12658        }
12659    }
12660
12661    @Override
12662    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12663        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12664                "setActivityController()");
12665        synchronized (this) {
12666            mController = controller;
12667            mControllerIsAMonkey = imAMonkey;
12668            Watchdog.getInstance().setActivityController(controller);
12669        }
12670    }
12671
12672    @Override
12673    public void setUserIsMonkey(boolean userIsMonkey) {
12674        synchronized (this) {
12675            synchronized (mPidsSelfLocked) {
12676                final int callingPid = Binder.getCallingPid();
12677                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12678                if (proc == null) {
12679                    throw new SecurityException("Unknown process: " + callingPid);
12680                }
12681                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12682                    throw new SecurityException("Only an instrumentation process "
12683                            + "with a UiAutomation can call setUserIsMonkey");
12684                }
12685            }
12686            mUserIsMonkey = userIsMonkey;
12687        }
12688    }
12689
12690    @Override
12691    public boolean isUserAMonkey() {
12692        synchronized (this) {
12693            // If there is a controller also implies the user is a monkey.
12694            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12695        }
12696    }
12697
12698    /**
12699     * @deprecated This method is only used by a few internal components and it will soon be
12700     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12701     * No new code should be calling it.
12702     */
12703    @Deprecated
12704    @Override
12705    public void requestBugReport(int bugreportType) {
12706        String extraOptions = null;
12707        switch (bugreportType) {
12708            case ActivityManager.BUGREPORT_OPTION_FULL:
12709                // Default options.
12710                break;
12711            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12712                extraOptions = "bugreportplus";
12713                break;
12714            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12715                extraOptions = "bugreportremote";
12716                break;
12717            case ActivityManager.BUGREPORT_OPTION_WEAR:
12718                extraOptions = "bugreportwear";
12719                break;
12720            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12721                extraOptions = "bugreporttelephony";
12722                break;
12723            default:
12724                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12725                        + bugreportType);
12726        }
12727        // Always log caller, even if it does not have permission to dump.
12728        String type = extraOptions == null ? "bugreport" : extraOptions;
12729        Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12730
12731        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12732        if (extraOptions != null) {
12733            SystemProperties.set("dumpstate.options", extraOptions);
12734        }
12735        SystemProperties.set("ctl.start", "bugreport");
12736    }
12737
12738    /**
12739     * @deprecated This method is only used by a few internal components and it will soon be
12740     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12741     * No new code should be calling it.
12742     */
12743    @Deprecated
12744    @Override
12745    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12746
12747        if (!TextUtils.isEmpty(shareTitle)) {
12748            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12749                String errorStr = "shareTitle should be less than " +
12750                        MAX_BUGREPORT_TITLE_SIZE + " characters";
12751                throw new IllegalArgumentException(errorStr);
12752            } else {
12753                if (!TextUtils.isEmpty(shareDescription)) {
12754                    int length;
12755                    try {
12756                        length = shareDescription.getBytes("UTF-8").length;
12757                    } catch (UnsupportedEncodingException e) {
12758                        String errorStr = "shareDescription: UnsupportedEncodingException";
12759                        throw new IllegalArgumentException(errorStr);
12760                    }
12761                    if (length > SystemProperties.PROP_VALUE_MAX) {
12762                        String errorStr = "shareTitle should be less than " +
12763                                SystemProperties.PROP_VALUE_MAX + " bytes";
12764                        throw new IllegalArgumentException(errorStr);
12765                    } else {
12766                        SystemProperties.set("dumpstate.options.description", shareDescription);
12767                    }
12768                }
12769                SystemProperties.set("dumpstate.options.title", shareTitle);
12770            }
12771        }
12772
12773        Slog.d(TAG, "Bugreport notification title " + shareTitle
12774                + " description " + shareDescription);
12775        requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12776    }
12777
12778    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12779        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12780    }
12781
12782    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12783        if (r != null && (r.instr != null || r.usingWrapper)) {
12784            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12785        }
12786        return KEY_DISPATCHING_TIMEOUT;
12787    }
12788
12789    @Override
12790    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12791        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12792                != PackageManager.PERMISSION_GRANTED) {
12793            throw new SecurityException("Requires permission "
12794                    + android.Manifest.permission.FILTER_EVENTS);
12795        }
12796        ProcessRecord proc;
12797        long timeout;
12798        synchronized (this) {
12799            synchronized (mPidsSelfLocked) {
12800                proc = mPidsSelfLocked.get(pid);
12801            }
12802            timeout = getInputDispatchingTimeoutLocked(proc);
12803        }
12804
12805        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12806            return -1;
12807        }
12808
12809        return timeout;
12810    }
12811
12812    /**
12813     * Handle input dispatching timeouts.
12814     * Returns whether input dispatching should be aborted or not.
12815     */
12816    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12817            final ActivityRecord activity, final ActivityRecord parent,
12818            final boolean aboveSystem, String reason) {
12819        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12820                != PackageManager.PERMISSION_GRANTED) {
12821            throw new SecurityException("Requires permission "
12822                    + android.Manifest.permission.FILTER_EVENTS);
12823        }
12824
12825        final String annotation;
12826        if (reason == null) {
12827            annotation = "Input dispatching timed out";
12828        } else {
12829            annotation = "Input dispatching timed out (" + reason + ")";
12830        }
12831
12832        if (proc != null) {
12833            synchronized (this) {
12834                if (proc.debugging) {
12835                    return false;
12836                }
12837
12838                if (proc.instr != null) {
12839                    Bundle info = new Bundle();
12840                    info.putString("shortMsg", "keyDispatchingTimedOut");
12841                    info.putString("longMsg", annotation);
12842                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12843                    return true;
12844                }
12845            }
12846            mHandler.post(new Runnable() {
12847                @Override
12848                public void run() {
12849                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12850                }
12851            });
12852        }
12853
12854        return true;
12855    }
12856
12857    @Override
12858    public Bundle getAssistContextExtras(int requestType) {
12859        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12860                null, null, true /* focused */, true /* newSessionId */,
12861                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12862        if (pae == null) {
12863            return null;
12864        }
12865        synchronized (pae) {
12866            while (!pae.haveResult) {
12867                try {
12868                    pae.wait();
12869                } catch (InterruptedException e) {
12870                }
12871            }
12872        }
12873        synchronized (this) {
12874            buildAssistBundleLocked(pae, pae.result);
12875            mPendingAssistExtras.remove(pae);
12876            mUiHandler.removeCallbacks(pae);
12877        }
12878        return pae.extras;
12879    }
12880
12881    @Override
12882    public boolean isAssistDataAllowedOnCurrentActivity() {
12883        int userId;
12884        synchronized (this) {
12885            final ActivityStack focusedStack = getFocusedStack();
12886            if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
12887                return false;
12888            }
12889
12890            final ActivityRecord activity = focusedStack.topActivity();
12891            if (activity == null) {
12892                return false;
12893            }
12894            userId = activity.userId;
12895        }
12896        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12897                Context.DEVICE_POLICY_SERVICE);
12898        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12899    }
12900
12901    @Override
12902    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12903        long ident = Binder.clearCallingIdentity();
12904        try {
12905            synchronized (this) {
12906                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12907                ActivityRecord top = getFocusedStack().topActivity();
12908                if (top != caller) {
12909                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12910                            + " is not current top " + top);
12911                    return false;
12912                }
12913                if (!top.nowVisible) {
12914                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12915                            + " is not visible");
12916                    return false;
12917                }
12918            }
12919            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
12920                    token);
12921        } finally {
12922            Binder.restoreCallingIdentity(ident);
12923        }
12924    }
12925
12926    @Override
12927    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12928            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
12929        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12930                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
12931                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
12932    }
12933
12934    @Override
12935    public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
12936            IBinder activityToken, int flags) {
12937        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
12938                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
12939                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
12940    }
12941
12942    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12943            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12944            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
12945            int flags) {
12946        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12947                "enqueueAssistContext()");
12948
12949        synchronized (this) {
12950            ActivityRecord activity = getFocusedStack().topActivity();
12951            if (activity == null) {
12952                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12953                return null;
12954            }
12955            if (activity.app == null || activity.app.thread == null) {
12956                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12957                return null;
12958            }
12959            if (focused) {
12960                if (activityToken != null) {
12961                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12962                    if (activity != caller) {
12963                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12964                                + " is not current top " + activity);
12965                        return null;
12966                    }
12967                }
12968            } else {
12969                activity = ActivityRecord.forTokenLocked(activityToken);
12970                if (activity == null) {
12971                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12972                            + " couldn't be found");
12973                    return null;
12974                }
12975                if (activity.app == null || activity.app.thread == null) {
12976                    Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
12977                    return null;
12978                }
12979            }
12980
12981            PendingAssistExtras pae;
12982            Bundle extras = new Bundle();
12983            if (args != null) {
12984                extras.putAll(args);
12985            }
12986            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12987            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12988
12989            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12990                    userHandle);
12991            pae.isHome = activity.isActivityTypeHome();
12992
12993            // Increment the sessionId if necessary
12994            if (newSessionId) {
12995                mViSessionId++;
12996            }
12997            try {
12998                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
12999                        mViSessionId, flags);
13000                mPendingAssistExtras.add(pae);
13001                mUiHandler.postDelayed(pae, timeout);
13002            } catch (RemoteException e) {
13003                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13004                return null;
13005            }
13006            return pae;
13007        }
13008    }
13009
13010    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13011        IResultReceiver receiver;
13012        synchronized (this) {
13013            mPendingAssistExtras.remove(pae);
13014            receiver = pae.receiver;
13015        }
13016        if (receiver != null) {
13017            // Caller wants result sent back to them.
13018            Bundle sendBundle = new Bundle();
13019            // At least return the receiver extras
13020            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13021                    pae.receiverExtras);
13022            try {
13023                pae.receiver.send(0, sendBundle);
13024            } catch (RemoteException e) {
13025            }
13026        }
13027    }
13028
13029    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13030        if (result != null) {
13031            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13032        }
13033        if (pae.hint != null) {
13034            pae.extras.putBoolean(pae.hint, true);
13035        }
13036    }
13037
13038    /** Called from an app when assist data is ready. */
13039    @Override
13040    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13041            AssistContent content, Uri referrer) {
13042        PendingAssistExtras pae = (PendingAssistExtras)token;
13043        synchronized (pae) {
13044            pae.result = extras;
13045            pae.structure = structure;
13046            pae.content = content;
13047            if (referrer != null) {
13048                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13049            }
13050            if (structure != null) {
13051                structure.setHomeActivity(pae.isHome);
13052            }
13053            pae.haveResult = true;
13054            pae.notifyAll();
13055            if (pae.intent == null && pae.receiver == null) {
13056                // Caller is just waiting for the result.
13057                return;
13058            }
13059        }
13060        // We are now ready to launch the assist activity.
13061        IResultReceiver sendReceiver = null;
13062        Bundle sendBundle = null;
13063        synchronized (this) {
13064            buildAssistBundleLocked(pae, extras);
13065            boolean exists = mPendingAssistExtras.remove(pae);
13066            mUiHandler.removeCallbacks(pae);
13067            if (!exists) {
13068                // Timed out.
13069                return;
13070            }
13071            if ((sendReceiver=pae.receiver) != null) {
13072                // Caller wants result sent back to them.
13073                sendBundle = new Bundle();
13074                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13075                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13076                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13077                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13078                        pae.receiverExtras);
13079            }
13080        }
13081        if (sendReceiver != null) {
13082            try {
13083                sendReceiver.send(0, sendBundle);
13084            } catch (RemoteException e) {
13085            }
13086            return;
13087        }
13088
13089        final long ident = Binder.clearCallingIdentity();
13090        try {
13091            if (TextUtils.equals(pae.intent.getAction(),
13092                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13093                pae.intent.putExtras(pae.extras);
13094                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13095            } else {
13096                pae.intent.replaceExtras(pae.extras);
13097                pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13098                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
13099                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13100                closeSystemDialogs("assist");
13101
13102                try {
13103                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13104                } catch (ActivityNotFoundException e) {
13105                    Slog.w(TAG, "No activity to handle assist action.", e);
13106                }
13107            }
13108        } finally {
13109            Binder.restoreCallingIdentity(ident);
13110        }
13111    }
13112
13113    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13114            Bundle args) {
13115        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13116                true /* focused */, true /* newSessionId */, userHandle, args,
13117                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13118    }
13119
13120    public void registerProcessObserver(IProcessObserver observer) {
13121        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13122                "registerProcessObserver()");
13123        synchronized (this) {
13124            mProcessObservers.register(observer);
13125        }
13126    }
13127
13128    @Override
13129    public void unregisterProcessObserver(IProcessObserver observer) {
13130        synchronized (this) {
13131            mProcessObservers.unregister(observer);
13132        }
13133    }
13134
13135    @Override
13136    public int getUidProcessState(int uid, String callingPackage) {
13137        if (!hasUsageStatsPermission(callingPackage)) {
13138            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13139                    "getUidProcessState");
13140        }
13141
13142        synchronized (this) {
13143            UidRecord uidRec = mActiveUids.get(uid);
13144            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13145        }
13146    }
13147
13148    @Override
13149    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13150            String callingPackage) {
13151        if (!hasUsageStatsPermission(callingPackage)) {
13152            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13153                    "registerUidObserver");
13154        }
13155        synchronized (this) {
13156            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13157                    callingPackage, which, cutpoint));
13158        }
13159    }
13160
13161    @Override
13162    public void unregisterUidObserver(IUidObserver observer) {
13163        synchronized (this) {
13164            mUidObservers.unregister(observer);
13165        }
13166    }
13167
13168    @Override
13169    public boolean convertFromTranslucent(IBinder token) {
13170        final long origId = Binder.clearCallingIdentity();
13171        try {
13172            synchronized (this) {
13173                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13174                if (r == null) {
13175                    return false;
13176                }
13177                final boolean translucentChanged = r.changeWindowTranslucency(true);
13178                if (translucentChanged) {
13179                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13180                }
13181                mWindowManager.setAppFullscreen(token, true);
13182                return translucentChanged;
13183            }
13184        } finally {
13185            Binder.restoreCallingIdentity(origId);
13186        }
13187    }
13188
13189    @Override
13190    public boolean convertToTranslucent(IBinder token, Bundle options) {
13191        final long origId = Binder.clearCallingIdentity();
13192        try {
13193            synchronized (this) {
13194                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13195                if (r == null) {
13196                    return false;
13197                }
13198                final TaskRecord task = r.getTask();
13199                int index = task.mActivities.lastIndexOf(r);
13200                if (index > 0) {
13201                    ActivityRecord under = task.mActivities.get(index - 1);
13202                    under.returningOptions = ActivityOptions.fromBundle(options);
13203                }
13204                final boolean translucentChanged = r.changeWindowTranslucency(false);
13205                if (translucentChanged) {
13206                    r.getStack().convertActivityToTranslucent(r);
13207                }
13208                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13209                mWindowManager.setAppFullscreen(token, false);
13210                return translucentChanged;
13211            }
13212        } finally {
13213            Binder.restoreCallingIdentity(origId);
13214        }
13215    }
13216
13217    @Override
13218    public Bundle getActivityOptions(IBinder token) {
13219        final long origId = Binder.clearCallingIdentity();
13220        try {
13221            synchronized (this) {
13222                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13223                if (r != null) {
13224                    final ActivityOptions activityOptions = r.takeOptionsLocked();
13225                    return activityOptions == null ? null : activityOptions.toBundle();
13226                }
13227                return null;
13228            }
13229        } finally {
13230            Binder.restoreCallingIdentity(origId);
13231        }
13232    }
13233
13234    @Override
13235    public void setImmersive(IBinder token, boolean immersive) {
13236        synchronized(this) {
13237            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13238            if (r == null) {
13239                throw new IllegalArgumentException();
13240            }
13241            r.immersive = immersive;
13242
13243            // update associated state if we're frontmost
13244            if (r == mStackSupervisor.getResumedActivityLocked()) {
13245                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13246                applyUpdateLockStateLocked(r);
13247            }
13248        }
13249    }
13250
13251    @Override
13252    public boolean isImmersive(IBinder token) {
13253        synchronized (this) {
13254            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13255            if (r == null) {
13256                throw new IllegalArgumentException();
13257            }
13258            return r.immersive;
13259        }
13260    }
13261
13262    @Override
13263    public void setVrThread(int tid) {
13264        enforceSystemHasVrFeature();
13265        synchronized (this) {
13266            synchronized (mPidsSelfLocked) {
13267                final int pid = Binder.getCallingPid();
13268                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13269                mVrController.setVrThreadLocked(tid, pid, proc);
13270            }
13271        }
13272    }
13273
13274    @Override
13275    public void setPersistentVrThread(int tid) {
13276        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13277            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13278                    + Binder.getCallingPid()
13279                    + ", uid=" + Binder.getCallingUid()
13280                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13281            Slog.w(TAG, msg);
13282            throw new SecurityException(msg);
13283        }
13284        enforceSystemHasVrFeature();
13285        synchronized (this) {
13286            synchronized (mPidsSelfLocked) {
13287                final int pid = Binder.getCallingPid();
13288                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13289                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13290            }
13291        }
13292    }
13293
13294    /**
13295     * Schedule the given thread a normal scheduling priority.
13296     *
13297     * @param tid the tid of the thread to adjust the scheduling of.
13298     * @param suppressLogs {@code true} if any error logging should be disabled.
13299     *
13300     * @return {@code true} if this succeeded.
13301     */
13302    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13303        try {
13304            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13305            return true;
13306        } catch (IllegalArgumentException e) {
13307            if (!suppressLogs) {
13308                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13309            }
13310        } catch (SecurityException e) {
13311            if (!suppressLogs) {
13312                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13313            }
13314        }
13315        return false;
13316    }
13317
13318    /**
13319     * Schedule the given thread an FIFO scheduling priority.
13320     *
13321     * @param tid the tid of the thread to adjust the scheduling of.
13322     * @param suppressLogs {@code true} if any error logging should be disabled.
13323     *
13324     * @return {@code true} if this succeeded.
13325     */
13326    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13327        try {
13328            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13329            return true;
13330        } catch (IllegalArgumentException e) {
13331            if (!suppressLogs) {
13332                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13333            }
13334        } catch (SecurityException e) {
13335            if (!suppressLogs) {
13336                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13337            }
13338        }
13339        return false;
13340    }
13341
13342    /**
13343     * Check that we have the features required for VR-related API calls, and throw an exception if
13344     * not.
13345     */
13346    private void enforceSystemHasVrFeature() {
13347        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13348            throw new UnsupportedOperationException("VR mode not supported on this device!");
13349        }
13350    }
13351
13352    @Override
13353    public void setRenderThread(int tid) {
13354        synchronized (this) {
13355            ProcessRecord proc;
13356            int pid = Binder.getCallingPid();
13357            if (pid == Process.myPid()) {
13358                demoteSystemServerRenderThread(tid);
13359                return;
13360            }
13361            synchronized (mPidsSelfLocked) {
13362                proc = mPidsSelfLocked.get(pid);
13363                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13364                    // ensure the tid belongs to the process
13365                    if (!isThreadInProcess(pid, tid)) {
13366                        throw new IllegalArgumentException(
13367                            "Render thread does not belong to process");
13368                    }
13369                    proc.renderThreadTid = tid;
13370                    if (DEBUG_OOM_ADJ) {
13371                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13372                    }
13373                    // promote to FIFO now
13374                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13375                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13376                        if (mUseFifoUiScheduling) {
13377                            setThreadScheduler(proc.renderThreadTid,
13378                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13379                        } else {
13380                            setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13381                        }
13382                    }
13383                } else {
13384                    if (DEBUG_OOM_ADJ) {
13385                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13386                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13387                               mUseFifoUiScheduling);
13388                    }
13389                }
13390            }
13391        }
13392    }
13393
13394    /**
13395     * We only use RenderThread in system_server to store task snapshots to the disk, which should
13396     * happen in the background. Thus, demote render thread from system_server to a lower priority.
13397     *
13398     * @param tid the tid of the RenderThread
13399     */
13400    private void demoteSystemServerRenderThread(int tid) {
13401        setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13402    }
13403
13404    @Override
13405    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13406        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13407            throw new UnsupportedOperationException("VR mode not supported on this device!");
13408        }
13409
13410        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13411
13412        ActivityRecord r;
13413        synchronized (this) {
13414            r = ActivityRecord.isInStackLocked(token);
13415        }
13416
13417        if (r == null) {
13418            throw new IllegalArgumentException();
13419        }
13420
13421        int err;
13422        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13423                VrManagerInternal.NO_ERROR) {
13424            return err;
13425        }
13426
13427        synchronized(this) {
13428            r.requestedVrComponent = (enabled) ? packageName : null;
13429
13430            // Update associated state if this activity is currently focused
13431            if (r == mStackSupervisor.getResumedActivityLocked()) {
13432                applyUpdateVrModeLocked(r);
13433            }
13434            return 0;
13435        }
13436    }
13437
13438    @Override
13439    public boolean isVrModePackageEnabled(ComponentName packageName) {
13440        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13441            throw new UnsupportedOperationException("VR mode not supported on this device!");
13442        }
13443
13444        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13445
13446        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13447                VrManagerInternal.NO_ERROR;
13448    }
13449
13450    public boolean isTopActivityImmersive() {
13451        enforceNotIsolatedCaller("startActivity");
13452        synchronized (this) {
13453            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13454            return (r != null) ? r.immersive : false;
13455        }
13456    }
13457
13458    /**
13459     * @return whether the system should disable UI modes incompatible with VR mode.
13460     */
13461    boolean shouldDisableNonVrUiLocked() {
13462        return mVrController.shouldDisableNonVrUiLocked();
13463    }
13464
13465    @Override
13466    public boolean isTopOfTask(IBinder token) {
13467        synchronized (this) {
13468            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13469            if (r == null) {
13470                throw new IllegalArgumentException();
13471            }
13472            return r.getTask().getTopActivity() == r;
13473        }
13474    }
13475
13476    @Override
13477    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13478        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13479            String msg = "Permission Denial: setHasTopUi() from pid="
13480                    + Binder.getCallingPid()
13481                    + ", uid=" + Binder.getCallingUid()
13482                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13483            Slog.w(TAG, msg);
13484            throw new SecurityException(msg);
13485        }
13486        final int pid = Binder.getCallingPid();
13487        final long origId = Binder.clearCallingIdentity();
13488        try {
13489            synchronized (this) {
13490                boolean changed = false;
13491                ProcessRecord pr;
13492                synchronized (mPidsSelfLocked) {
13493                    pr = mPidsSelfLocked.get(pid);
13494                    if (pr == null) {
13495                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13496                        return;
13497                    }
13498                    if (pr.hasTopUi != hasTopUi) {
13499                        if (DEBUG_OOM_ADJ) {
13500                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13501                        }
13502                        pr.hasTopUi = hasTopUi;
13503                        changed = true;
13504                    }
13505                }
13506                if (changed) {
13507                    updateOomAdjLocked(pr, true);
13508                }
13509            }
13510        } finally {
13511            Binder.restoreCallingIdentity(origId);
13512        }
13513    }
13514
13515    public final void enterSafeMode() {
13516        synchronized(this) {
13517            // It only makes sense to do this before the system is ready
13518            // and started launching other packages.
13519            if (!mSystemReady) {
13520                try {
13521                    AppGlobals.getPackageManager().enterSafeMode();
13522                } catch (RemoteException e) {
13523                }
13524            }
13525
13526            mSafeMode = true;
13527        }
13528    }
13529
13530    public final void showSafeModeOverlay() {
13531        View v = LayoutInflater.from(mContext).inflate(
13532                com.android.internal.R.layout.safe_mode, null);
13533        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13534        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13535        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13536        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13537        lp.gravity = Gravity.BOTTOM | Gravity.START;
13538        lp.format = v.getBackground().getOpacity();
13539        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13540                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13541        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13542        ((WindowManager)mContext.getSystemService(
13543                Context.WINDOW_SERVICE)).addView(v, lp);
13544    }
13545
13546    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13547        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13548            return;
13549        }
13550        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13551        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13552        synchronized (stats) {
13553            if (mBatteryStatsService.isOnBattery()) {
13554                mBatteryStatsService.enforceCallingPermission();
13555                int MY_UID = Binder.getCallingUid();
13556                final int uid;
13557                if (sender == null) {
13558                    uid = sourceUid;
13559                } else {
13560                    uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13561                }
13562                BatteryStatsImpl.Uid.Pkg pkg =
13563                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13564                            sourcePkg != null ? sourcePkg : rec.key.packageName);
13565                pkg.noteWakeupAlarmLocked(tag);
13566                StatsLog.write(StatsLog.WAKEUP_ALARM_OCCURRED, sourceUid >= 0 ? sourceUid : uid);
13567            }
13568        }
13569    }
13570
13571    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13572        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13573            return;
13574        }
13575        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13576        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13577        synchronized (stats) {
13578            mBatteryStatsService.enforceCallingPermission();
13579            int MY_UID = Binder.getCallingUid();
13580            final int uid;
13581            if (sender == null) {
13582                uid = sourceUid;
13583            } else {
13584                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13585            }
13586            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13587        }
13588    }
13589
13590    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13591        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13592            return;
13593        }
13594        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13595        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13596        synchronized (stats) {
13597            mBatteryStatsService.enforceCallingPermission();
13598            int MY_UID = Binder.getCallingUid();
13599            final int uid;
13600            if (sender == null) {
13601                uid = sourceUid;
13602            } else {
13603                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13604            }
13605            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13606        }
13607    }
13608
13609    public boolean killPids(int[] pids, String pReason, boolean secure) {
13610        if (Binder.getCallingUid() != SYSTEM_UID) {
13611            throw new SecurityException("killPids only available to the system");
13612        }
13613        String reason = (pReason == null) ? "Unknown" : pReason;
13614        // XXX Note: don't acquire main activity lock here, because the window
13615        // manager calls in with its locks held.
13616
13617        boolean killed = false;
13618        synchronized (mPidsSelfLocked) {
13619            int worstType = 0;
13620            for (int i=0; i<pids.length; i++) {
13621                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13622                if (proc != null) {
13623                    int type = proc.setAdj;
13624                    if (type > worstType) {
13625                        worstType = type;
13626                    }
13627                }
13628            }
13629
13630            // If the worst oom_adj is somewhere in the cached proc LRU range,
13631            // then constrain it so we will kill all cached procs.
13632            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13633                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13634                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13635            }
13636
13637            // If this is not a secure call, don't let it kill processes that
13638            // are important.
13639            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13640                worstType = ProcessList.SERVICE_ADJ;
13641            }
13642
13643            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13644            for (int i=0; i<pids.length; i++) {
13645                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13646                if (proc == null) {
13647                    continue;
13648                }
13649                int adj = proc.setAdj;
13650                if (adj >= worstType && !proc.killedByAm) {
13651                    proc.kill(reason, true);
13652                    killed = true;
13653                }
13654            }
13655        }
13656        return killed;
13657    }
13658
13659    @Override
13660    public void killUid(int appId, int userId, String reason) {
13661        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13662        synchronized (this) {
13663            final long identity = Binder.clearCallingIdentity();
13664            try {
13665                killPackageProcessesLocked(null, appId, userId,
13666                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13667                        reason != null ? reason : "kill uid");
13668            } finally {
13669                Binder.restoreCallingIdentity(identity);
13670            }
13671        }
13672    }
13673
13674    @Override
13675    public boolean killProcessesBelowForeground(String reason) {
13676        if (Binder.getCallingUid() != SYSTEM_UID) {
13677            throw new SecurityException("killProcessesBelowForeground() only available to system");
13678        }
13679
13680        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13681    }
13682
13683    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13684        if (Binder.getCallingUid() != SYSTEM_UID) {
13685            throw new SecurityException("killProcessesBelowAdj() only available to system");
13686        }
13687
13688        boolean killed = false;
13689        synchronized (mPidsSelfLocked) {
13690            final int size = mPidsSelfLocked.size();
13691            for (int i = 0; i < size; i++) {
13692                final int pid = mPidsSelfLocked.keyAt(i);
13693                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13694                if (proc == null) continue;
13695
13696                final int adj = proc.setAdj;
13697                if (adj > belowAdj && !proc.killedByAm) {
13698                    proc.kill(reason, true);
13699                    killed = true;
13700                }
13701            }
13702        }
13703        return killed;
13704    }
13705
13706    @Override
13707    public void hang(final IBinder who, boolean allowRestart) {
13708        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13709                != PackageManager.PERMISSION_GRANTED) {
13710            throw new SecurityException("Requires permission "
13711                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13712        }
13713
13714        final IBinder.DeathRecipient death = new DeathRecipient() {
13715            @Override
13716            public void binderDied() {
13717                synchronized (this) {
13718                    notifyAll();
13719                }
13720            }
13721        };
13722
13723        try {
13724            who.linkToDeath(death, 0);
13725        } catch (RemoteException e) {
13726            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13727            return;
13728        }
13729
13730        synchronized (this) {
13731            Watchdog.getInstance().setAllowRestart(allowRestart);
13732            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13733            synchronized (death) {
13734                while (who.isBinderAlive()) {
13735                    try {
13736                        death.wait();
13737                    } catch (InterruptedException e) {
13738                    }
13739                }
13740            }
13741            Watchdog.getInstance().setAllowRestart(true);
13742        }
13743    }
13744
13745    @Override
13746    public void restart() {
13747        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13748                != PackageManager.PERMISSION_GRANTED) {
13749            throw new SecurityException("Requires permission "
13750                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13751        }
13752
13753        Log.i(TAG, "Sending shutdown broadcast...");
13754
13755        BroadcastReceiver br = new BroadcastReceiver() {
13756            @Override public void onReceive(Context context, Intent intent) {
13757                // Now the broadcast is done, finish up the low-level shutdown.
13758                Log.i(TAG, "Shutting down activity manager...");
13759                shutdown(10000);
13760                Log.i(TAG, "Shutdown complete, restarting!");
13761                killProcess(myPid());
13762                System.exit(10);
13763            }
13764        };
13765
13766        // First send the high-level shut down broadcast.
13767        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13768        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13769        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13770        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13771        mContext.sendOrderedBroadcastAsUser(intent,
13772                UserHandle.ALL, null, br, mHandler, 0, null, null);
13773        */
13774        br.onReceive(mContext, intent);
13775    }
13776
13777    private long getLowRamTimeSinceIdle(long now) {
13778        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13779    }
13780
13781    @Override
13782    public void performIdleMaintenance() {
13783        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13784                != PackageManager.PERMISSION_GRANTED) {
13785            throw new SecurityException("Requires permission "
13786                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13787        }
13788
13789        synchronized (this) {
13790            final long now = SystemClock.uptimeMillis();
13791            final long timeSinceLastIdle = now - mLastIdleTime;
13792            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13793            mLastIdleTime = now;
13794            mLowRamTimeSinceLastIdle = 0;
13795            if (mLowRamStartTime != 0) {
13796                mLowRamStartTime = now;
13797            }
13798
13799            StringBuilder sb = new StringBuilder(128);
13800            sb.append("Idle maintenance over ");
13801            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13802            sb.append(" low RAM for ");
13803            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13804            Slog.i(TAG, sb.toString());
13805
13806            // If at least 1/3 of our time since the last idle period has been spent
13807            // with RAM low, then we want to kill processes.
13808            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13809
13810            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13811                ProcessRecord proc = mLruProcesses.get(i);
13812                if (proc.notCachedSinceIdle) {
13813                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13814                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13815                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13816                        if (doKilling && proc.initialIdlePss != 0
13817                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13818                            sb = new StringBuilder(128);
13819                            sb.append("Kill");
13820                            sb.append(proc.processName);
13821                            sb.append(" in idle maint: pss=");
13822                            sb.append(proc.lastPss);
13823                            sb.append(", swapPss=");
13824                            sb.append(proc.lastSwapPss);
13825                            sb.append(", initialPss=");
13826                            sb.append(proc.initialIdlePss);
13827                            sb.append(", period=");
13828                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13829                            sb.append(", lowRamPeriod=");
13830                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13831                            Slog.wtfQuiet(TAG, sb.toString());
13832                            proc.kill("idle maint (pss " + proc.lastPss
13833                                    + " from " + proc.initialIdlePss + ")", true);
13834                        }
13835                    }
13836                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13837                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13838                    proc.notCachedSinceIdle = true;
13839                    proc.initialIdlePss = 0;
13840                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13841                            mTestPssMode, isSleepingLocked(), now);
13842                }
13843            }
13844
13845            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13846            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13847        }
13848    }
13849
13850    @Override
13851    public void sendIdleJobTrigger() {
13852        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13853                != PackageManager.PERMISSION_GRANTED) {
13854            throw new SecurityException("Requires permission "
13855                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13856        }
13857
13858        final long ident = Binder.clearCallingIdentity();
13859        try {
13860            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13861                    .setPackage("android")
13862                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13863            broadcastIntent(null, intent, null, null, 0, null, null, null,
13864                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13865        } finally {
13866            Binder.restoreCallingIdentity(ident);
13867        }
13868    }
13869
13870    private void retrieveSettings() {
13871        final ContentResolver resolver = mContext.getContentResolver();
13872        final boolean freeformWindowManagement =
13873                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13874                        || Settings.Global.getInt(
13875                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13876
13877        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
13878        final boolean supportsPictureInPicture = supportsMultiWindow &&
13879                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13880        final boolean supportsSplitScreenMultiWindow =
13881                ActivityManager.supportsSplitScreenMultiWindow(mContext);
13882        final boolean supportsMultiDisplay = mContext.getPackageManager()
13883                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
13884        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13885        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13886        final boolean alwaysFinishActivities =
13887                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13888        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13889        final boolean forceResizable = Settings.Global.getInt(
13890                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13891        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
13892                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
13893        final boolean supportsLeanbackOnly =
13894                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13895
13896        // Transfer any global setting for forcing RTL layout, into a System Property
13897        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13898
13899        final Configuration configuration = new Configuration();
13900        Settings.System.getConfiguration(resolver, configuration);
13901        if (forceRtl) {
13902            // This will take care of setting the correct layout direction flags
13903            configuration.setLayoutDirection(configuration.locale);
13904        }
13905
13906        synchronized (this) {
13907            mDebugApp = mOrigDebugApp = debugApp;
13908            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13909            mAlwaysFinishActivities = alwaysFinishActivities;
13910            mSupportsLeanbackOnly = supportsLeanbackOnly;
13911            mForceResizableActivities = forceResizable;
13912            final boolean multiWindowFormEnabled = freeformWindowManagement
13913                    || supportsSplitScreenMultiWindow
13914                    || supportsPictureInPicture
13915                    || supportsMultiDisplay;
13916            if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
13917                mSupportsMultiWindow = true;
13918                mSupportsFreeformWindowManagement = freeformWindowManagement;
13919                mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
13920                mSupportsPictureInPicture = supportsPictureInPicture;
13921                mSupportsMultiDisplay = supportsMultiDisplay;
13922            } else {
13923                mSupportsMultiWindow = false;
13924                mSupportsFreeformWindowManagement = false;
13925                mSupportsSplitScreenMultiWindow = false;
13926                mSupportsPictureInPicture = false;
13927                mSupportsMultiDisplay = false;
13928            }
13929            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13930            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13931            // This happens before any activities are started, so we can change global configuration
13932            // in-place.
13933            updateConfigurationLocked(configuration, null, true);
13934            final Configuration globalConfig = getGlobalConfiguration();
13935            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13936
13937            // Load resources only after the current configuration has been set.
13938            final Resources res = mContext.getResources();
13939            mThumbnailWidth = res.getDimensionPixelSize(
13940                    com.android.internal.R.dimen.thumbnail_width);
13941            mThumbnailHeight = res.getDimensionPixelSize(
13942                    com.android.internal.R.dimen.thumbnail_height);
13943            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13944                    com.android.internal.R.string.config_appsNotReportingCrashes));
13945            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13946                    com.android.internal.R.bool.config_customUserSwitchUi);
13947            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13948                mFullscreenThumbnailScale = (float) res
13949                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13950                    (float) globalConfig.screenWidthDp;
13951            } else {
13952                mFullscreenThumbnailScale = res.getFraction(
13953                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13954            }
13955            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
13956        }
13957    }
13958
13959    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
13960        traceLog.traceBegin("PhaseActivityManagerReady");
13961        synchronized(this) {
13962            if (mSystemReady) {
13963                // If we're done calling all the receivers, run the next "boot phase" passed in
13964                // by the SystemServer
13965                if (goingCallback != null) {
13966                    goingCallback.run();
13967                }
13968                return;
13969            }
13970
13971            mLocalDeviceIdleController
13972                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13973            mAssistUtils = new AssistUtils(mContext);
13974            mVrController.onSystemReady();
13975            // Make sure we have the current profile info, since it is needed for security checks.
13976            mUserController.onSystemReady();
13977            mRecentTasks.onSystemReadyLocked();
13978            mAppOpsService.systemReady();
13979            mSystemReady = true;
13980        }
13981
13982        try {
13983            sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
13984                    ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
13985                    .getSerial();
13986        } catch (RemoteException e) {}
13987
13988        ArrayList<ProcessRecord> procsToKill = null;
13989        synchronized(mPidsSelfLocked) {
13990            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13991                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13992                if (!isAllowedWhileBooting(proc.info)){
13993                    if (procsToKill == null) {
13994                        procsToKill = new ArrayList<ProcessRecord>();
13995                    }
13996                    procsToKill.add(proc);
13997                }
13998            }
13999        }
14000
14001        synchronized(this) {
14002            if (procsToKill != null) {
14003                for (int i=procsToKill.size()-1; i>=0; i--) {
14004                    ProcessRecord proc = procsToKill.get(i);
14005                    Slog.i(TAG, "Removing system update proc: " + proc);
14006                    removeProcessLocked(proc, true, false, "system update done");
14007                }
14008            }
14009
14010            // Now that we have cleaned up any update processes, we
14011            // are ready to start launching real processes and know that
14012            // we won't trample on them any more.
14013            mProcessesReady = true;
14014        }
14015
14016        Slog.i(TAG, "System now ready");
14017        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14018            SystemClock.uptimeMillis());
14019
14020        synchronized(this) {
14021            // Make sure we have no pre-ready processes sitting around.
14022
14023            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14024                ResolveInfo ri = mContext.getPackageManager()
14025                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14026                                STOCK_PM_FLAGS);
14027                CharSequence errorMsg = null;
14028                if (ri != null) {
14029                    ActivityInfo ai = ri.activityInfo;
14030                    ApplicationInfo app = ai.applicationInfo;
14031                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14032                        mTopAction = Intent.ACTION_FACTORY_TEST;
14033                        mTopData = null;
14034                        mTopComponent = new ComponentName(app.packageName,
14035                                ai.name);
14036                    } else {
14037                        errorMsg = mContext.getResources().getText(
14038                                com.android.internal.R.string.factorytest_not_system);
14039                    }
14040                } else {
14041                    errorMsg = mContext.getResources().getText(
14042                            com.android.internal.R.string.factorytest_no_action);
14043                }
14044                if (errorMsg != null) {
14045                    mTopAction = null;
14046                    mTopData = null;
14047                    mTopComponent = null;
14048                    Message msg = Message.obtain();
14049                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14050                    msg.getData().putCharSequence("msg", errorMsg);
14051                    mUiHandler.sendMessage(msg);
14052                }
14053            }
14054        }
14055
14056        retrieveSettings();
14057        final int currentUserId = mUserController.getCurrentUserId();
14058        synchronized (this) {
14059            readGrantedUriPermissionsLocked();
14060        }
14061
14062        if (goingCallback != null) goingCallback.run();
14063        traceLog.traceBegin("ActivityManagerStartApps");
14064        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14065                Integer.toString(currentUserId), currentUserId);
14066        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14067                Integer.toString(currentUserId), currentUserId);
14068        mSystemServiceManager.startUser(currentUserId);
14069
14070        synchronized (this) {
14071            // Only start up encryption-aware persistent apps; once user is
14072            // unlocked we'll come back around and start unaware apps
14073            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14074
14075            // Start up initial activity.
14076            mBooting = true;
14077            // Enable home activity for system user, so that the system can always boot. We don't
14078            // do this when the system user is not setup since the setup wizard should be the one
14079            // to handle home activity in this case.
14080            if (UserManager.isSplitSystemUser() &&
14081                    Settings.Secure.getInt(mContext.getContentResolver(),
14082                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14083                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14084                try {
14085                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14086                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14087                            UserHandle.USER_SYSTEM);
14088                } catch (RemoteException e) {
14089                    throw e.rethrowAsRuntimeException();
14090                }
14091            }
14092            startHomeActivityLocked(currentUserId, "systemReady");
14093
14094            try {
14095                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14096                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14097                            + " data partition or your device will be unstable.");
14098                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14099                }
14100            } catch (RemoteException e) {
14101            }
14102
14103            if (!Build.isBuildConsistent()) {
14104                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14105                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14106            }
14107
14108            long ident = Binder.clearCallingIdentity();
14109            try {
14110                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14111                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14112                        | Intent.FLAG_RECEIVER_FOREGROUND);
14113                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14114                broadcastIntentLocked(null, null, intent,
14115                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14116                        null, false, false, MY_PID, SYSTEM_UID,
14117                        currentUserId);
14118                intent = new Intent(Intent.ACTION_USER_STARTING);
14119                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14120                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14121                broadcastIntentLocked(null, null, intent,
14122                        null, new IIntentReceiver.Stub() {
14123                            @Override
14124                            public void performReceive(Intent intent, int resultCode, String data,
14125                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14126                                    throws RemoteException {
14127                            }
14128                        }, 0, null, null,
14129                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14130                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14131            } catch (Throwable t) {
14132                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14133            } finally {
14134                Binder.restoreCallingIdentity(ident);
14135            }
14136            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14137            mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
14138
14139            BinderInternal.nSetBinderProxyCountEnabled(true);
14140            BinderInternal.setBinderProxyCountCallback(
14141                    new BinderInternal.BinderProxyLimitListener() {
14142                        @Override
14143                        public void onLimitReached(int uid) {
14144                            Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
14145                                    + Process.myUid());
14146                            if (uid == Process.SYSTEM_UID) {
14147                                Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
14148                            } else {
14149                                killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
14150                                        "Too many Binders sent to SYSTEM");
14151                            }
14152                        }
14153                    }, mHandler);
14154
14155            traceLog.traceEnd(); // ActivityManagerStartApps
14156            traceLog.traceEnd(); // PhaseActivityManagerReady
14157        }
14158    }
14159
14160    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14161        synchronized (this) {
14162            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14163        }
14164    }
14165
14166    void skipCurrentReceiverLocked(ProcessRecord app) {
14167        for (BroadcastQueue queue : mBroadcastQueues) {
14168            queue.skipCurrentReceiverLocked(app);
14169        }
14170    }
14171
14172    /**
14173     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14174     * The application process will exit immediately after this call returns.
14175     * @param app object of the crashing app, null for the system server
14176     * @param crashInfo describing the exception
14177     */
14178    public void handleApplicationCrash(IBinder app,
14179            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14180        ProcessRecord r = findAppProcess(app, "Crash");
14181        final String processName = app == null ? "system_server"
14182                : (r == null ? "unknown" : r.processName);
14183
14184        handleApplicationCrashInner("crash", r, processName, crashInfo);
14185    }
14186
14187    /* Native crash reporting uses this inner version because it needs to be somewhat
14188     * decoupled from the AM-managed cleanup lifecycle
14189     */
14190    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14191            ApplicationErrorReport.CrashInfo crashInfo) {
14192        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14193                UserHandle.getUserId(Binder.getCallingUid()), processName,
14194                r == null ? -1 : r.info.flags,
14195                crashInfo.exceptionClassName,
14196                crashInfo.exceptionMessage,
14197                crashInfo.throwFileName,
14198                crashInfo.throwLineNumber);
14199
14200        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14201
14202        mAppErrors.crashApplication(r, crashInfo);
14203    }
14204
14205    public void handleApplicationStrictModeViolation(
14206            IBinder app,
14207            int violationMask,
14208            StrictMode.ViolationInfo info) {
14209        ProcessRecord r = findAppProcess(app, "StrictMode");
14210        if (r == null) {
14211            return;
14212        }
14213
14214        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14215            Integer stackFingerprint = info.hashCode();
14216            boolean logIt = true;
14217            synchronized (mAlreadyLoggedViolatedStacks) {
14218                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14219                    logIt = false;
14220                    // TODO: sub-sample into EventLog for these, with
14221                    // the info.durationMillis?  Then we'd get
14222                    // the relative pain numbers, without logging all
14223                    // the stack traces repeatedly.  We'd want to do
14224                    // likewise in the client code, which also does
14225                    // dup suppression, before the Binder call.
14226                } else {
14227                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14228                        mAlreadyLoggedViolatedStacks.clear();
14229                    }
14230                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14231                }
14232            }
14233            if (logIt) {
14234                logStrictModeViolationToDropBox(r, info);
14235            }
14236        }
14237
14238        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14239            AppErrorResult result = new AppErrorResult();
14240            synchronized (this) {
14241                final long origId = Binder.clearCallingIdentity();
14242
14243                Message msg = Message.obtain();
14244                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14245                HashMap<String, Object> data = new HashMap<String, Object>();
14246                data.put("result", result);
14247                data.put("app", r);
14248                data.put("violationMask", violationMask);
14249                data.put("info", info);
14250                msg.obj = data;
14251                mUiHandler.sendMessage(msg);
14252
14253                Binder.restoreCallingIdentity(origId);
14254            }
14255            int res = result.get();
14256            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14257        }
14258    }
14259
14260    // Depending on the policy in effect, there could be a bunch of
14261    // these in quick succession so we try to batch these together to
14262    // minimize disk writes, number of dropbox entries, and maximize
14263    // compression, by having more fewer, larger records.
14264    private void logStrictModeViolationToDropBox(
14265            ProcessRecord process,
14266            StrictMode.ViolationInfo info) {
14267        if (info == null) {
14268            return;
14269        }
14270        final boolean isSystemApp = process == null ||
14271                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14272                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14273        final String processName = process == null ? "unknown" : process.processName;
14274        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14275        final DropBoxManager dbox = (DropBoxManager)
14276                mContext.getSystemService(Context.DROPBOX_SERVICE);
14277
14278        // Exit early if the dropbox isn't configured to accept this report type.
14279        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14280
14281        boolean bufferWasEmpty;
14282        boolean needsFlush;
14283        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14284        synchronized (sb) {
14285            bufferWasEmpty = sb.length() == 0;
14286            appendDropBoxProcessHeaders(process, processName, sb);
14287            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14288            sb.append("System-App: ").append(isSystemApp).append("\n");
14289            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14290            if (info.violationNumThisLoop != 0) {
14291                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14292            }
14293            if (info.numAnimationsRunning != 0) {
14294                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14295            }
14296            if (info.broadcastIntentAction != null) {
14297                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14298            }
14299            if (info.durationMillis != -1) {
14300                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14301            }
14302            if (info.numInstances != -1) {
14303                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14304            }
14305            if (info.tags != null) {
14306                for (String tag : info.tags) {
14307                    sb.append("Span-Tag: ").append(tag).append("\n");
14308                }
14309            }
14310            sb.append("\n");
14311            if (info.hasStackTrace()) {
14312                sb.append(info.getStackTrace());
14313                sb.append("\n");
14314            }
14315            if (info.getViolationDetails() != null) {
14316                sb.append(info.getViolationDetails());
14317                sb.append("\n");
14318            }
14319
14320            // Only buffer up to ~64k.  Various logging bits truncate
14321            // things at 128k.
14322            needsFlush = (sb.length() > 64 * 1024);
14323        }
14324
14325        // Flush immediately if the buffer's grown too large, or this
14326        // is a non-system app.  Non-system apps are isolated with a
14327        // different tag & policy and not batched.
14328        //
14329        // Batching is useful during internal testing with
14330        // StrictMode settings turned up high.  Without batching,
14331        // thousands of separate files could be created on boot.
14332        if (!isSystemApp || needsFlush) {
14333            new Thread("Error dump: " + dropboxTag) {
14334                @Override
14335                public void run() {
14336                    String report;
14337                    synchronized (sb) {
14338                        report = sb.toString();
14339                        sb.delete(0, sb.length());
14340                        sb.trimToSize();
14341                    }
14342                    if (report.length() != 0) {
14343                        dbox.addText(dropboxTag, report);
14344                    }
14345                }
14346            }.start();
14347            return;
14348        }
14349
14350        // System app batching:
14351        if (!bufferWasEmpty) {
14352            // An existing dropbox-writing thread is outstanding, so
14353            // we don't need to start it up.  The existing thread will
14354            // catch the buffer appends we just did.
14355            return;
14356        }
14357
14358        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14359        // (After this point, we shouldn't access AMS internal data structures.)
14360        new Thread("Error dump: " + dropboxTag) {
14361            @Override
14362            public void run() {
14363                // 5 second sleep to let stacks arrive and be batched together
14364                try {
14365                    Thread.sleep(5000);  // 5 seconds
14366                } catch (InterruptedException e) {}
14367
14368                String errorReport;
14369                synchronized (mStrictModeBuffer) {
14370                    errorReport = mStrictModeBuffer.toString();
14371                    if (errorReport.length() == 0) {
14372                        return;
14373                    }
14374                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14375                    mStrictModeBuffer.trimToSize();
14376                }
14377                dbox.addText(dropboxTag, errorReport);
14378            }
14379        }.start();
14380    }
14381
14382    /**
14383     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14384     * @param app object of the crashing app, null for the system server
14385     * @param tag reported by the caller
14386     * @param system whether this wtf is coming from the system
14387     * @param crashInfo describing the context of the error
14388     * @return true if the process should exit immediately (WTF is fatal)
14389     */
14390    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14391            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14392        final int callingUid = Binder.getCallingUid();
14393        final int callingPid = Binder.getCallingPid();
14394
14395        if (system) {
14396            // If this is coming from the system, we could very well have low-level
14397            // system locks held, so we want to do this all asynchronously.  And we
14398            // never want this to become fatal, so there is that too.
14399            mHandler.post(new Runnable() {
14400                @Override public void run() {
14401                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14402                }
14403            });
14404            return false;
14405        }
14406
14407        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14408                crashInfo);
14409
14410        final boolean isFatal = Build.IS_ENG || Settings.Global
14411                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14412        final boolean isSystem = (r == null) || r.persistent;
14413
14414        if (isFatal && !isSystem) {
14415            mAppErrors.crashApplication(r, crashInfo);
14416            return true;
14417        } else {
14418            return false;
14419        }
14420    }
14421
14422    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14423            final ApplicationErrorReport.CrashInfo crashInfo) {
14424        final ProcessRecord r = findAppProcess(app, "WTF");
14425        final String processName = app == null ? "system_server"
14426                : (r == null ? "unknown" : r.processName);
14427
14428        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14429                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14430
14431        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14432
14433        return r;
14434    }
14435
14436    /**
14437     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14438     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14439     */
14440    private ProcessRecord findAppProcess(IBinder app, String reason) {
14441        if (app == null) {
14442            return null;
14443        }
14444
14445        synchronized (this) {
14446            final int NP = mProcessNames.getMap().size();
14447            for (int ip=0; ip<NP; ip++) {
14448                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14449                final int NA = apps.size();
14450                for (int ia=0; ia<NA; ia++) {
14451                    ProcessRecord p = apps.valueAt(ia);
14452                    if (p.thread != null && p.thread.asBinder() == app) {
14453                        return p;
14454                    }
14455                }
14456            }
14457
14458            Slog.w(TAG, "Can't find mystery application for " + reason
14459                    + " from pid=" + Binder.getCallingPid()
14460                    + " uid=" + Binder.getCallingUid() + ": " + app);
14461            return null;
14462        }
14463    }
14464
14465    /**
14466     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14467     * to append various headers to the dropbox log text.
14468     */
14469    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14470            StringBuilder sb) {
14471        // Watchdog thread ends up invoking this function (with
14472        // a null ProcessRecord) to add the stack file to dropbox.
14473        // Do not acquire a lock on this (am) in such cases, as it
14474        // could cause a potential deadlock, if and when watchdog
14475        // is invoked due to unavailability of lock on am and it
14476        // would prevent watchdog from killing system_server.
14477        if (process == null) {
14478            sb.append("Process: ").append(processName).append("\n");
14479            return;
14480        }
14481        // Note: ProcessRecord 'process' is guarded by the service
14482        // instance.  (notably process.pkgList, which could otherwise change
14483        // concurrently during execution of this method)
14484        synchronized (this) {
14485            sb.append("Process: ").append(processName).append("\n");
14486            sb.append("PID: ").append(process.pid).append("\n");
14487            int flags = process.info.flags;
14488            IPackageManager pm = AppGlobals.getPackageManager();
14489            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14490            for (int ip=0; ip<process.pkgList.size(); ip++) {
14491                String pkg = process.pkgList.keyAt(ip);
14492                sb.append("Package: ").append(pkg);
14493                try {
14494                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14495                    if (pi != null) {
14496                        sb.append(" v").append(pi.versionCode);
14497                        if (pi.versionName != null) {
14498                            sb.append(" (").append(pi.versionName).append(")");
14499                        }
14500                    }
14501                } catch (RemoteException e) {
14502                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14503                }
14504                sb.append("\n");
14505            }
14506            if (process.info.isInstantApp()) {
14507                sb.append("Instant-App: true\n");
14508            }
14509        }
14510    }
14511
14512    private static String processClass(ProcessRecord process) {
14513        if (process == null || process.pid == MY_PID) {
14514            return "system_server";
14515        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14516            return "system_app";
14517        } else {
14518            return "data_app";
14519        }
14520    }
14521
14522    private volatile long mWtfClusterStart;
14523    private volatile int mWtfClusterCount;
14524
14525    /**
14526     * Write a description of an error (crash, WTF, ANR) to the drop box.
14527     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14528     * @param process which caused the error, null means the system server
14529     * @param activity which triggered the error, null if unknown
14530     * @param parent activity related to the error, null if unknown
14531     * @param subject line related to the error, null if absent
14532     * @param report in long form describing the error, null if absent
14533     * @param dataFile text file to include in the report, null if none
14534     * @param crashInfo giving an application stack trace, null if absent
14535     */
14536    public void addErrorToDropBox(String eventType,
14537            ProcessRecord process, String processName, ActivityRecord activity,
14538            ActivityRecord parent, String subject,
14539            final String report, final File dataFile,
14540            final ApplicationErrorReport.CrashInfo crashInfo) {
14541        // NOTE -- this must never acquire the ActivityManagerService lock,
14542        // otherwise the watchdog may be prevented from resetting the system.
14543
14544        // Bail early if not published yet
14545        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14546        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14547
14548        // Exit early if the dropbox isn't configured to accept this report type.
14549        final String dropboxTag = processClass(process) + "_" + eventType;
14550        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14551
14552        // Rate-limit how often we're willing to do the heavy lifting below to
14553        // collect and record logs; currently 5 logs per 10 second period.
14554        final long now = SystemClock.elapsedRealtime();
14555        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14556            mWtfClusterStart = now;
14557            mWtfClusterCount = 1;
14558        } else {
14559            if (mWtfClusterCount++ >= 5) return;
14560        }
14561
14562        final StringBuilder sb = new StringBuilder(1024);
14563        appendDropBoxProcessHeaders(process, processName, sb);
14564        if (process != null) {
14565            sb.append("Foreground: ")
14566                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14567                    .append("\n");
14568        }
14569        if (activity != null) {
14570            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14571        }
14572        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14573            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14574        }
14575        if (parent != null && parent != activity) {
14576            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14577        }
14578        if (subject != null) {
14579            sb.append("Subject: ").append(subject).append("\n");
14580        }
14581        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14582        if (Debug.isDebuggerConnected()) {
14583            sb.append("Debugger: Connected\n");
14584        }
14585        sb.append("\n");
14586
14587        // Do the rest in a worker thread to avoid blocking the caller on I/O
14588        // (After this point, we shouldn't access AMS internal data structures.)
14589        Thread worker = new Thread("Error dump: " + dropboxTag) {
14590            @Override
14591            public void run() {
14592                if (report != null) {
14593                    sb.append(report);
14594                }
14595
14596                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14597                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14598                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14599                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14600
14601                if (dataFile != null && maxDataFileSize > 0) {
14602                    try {
14603                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14604                                    "\n\n[[TRUNCATED]]"));
14605                    } catch (IOException e) {
14606                        Slog.e(TAG, "Error reading " + dataFile, e);
14607                    }
14608                }
14609                if (crashInfo != null && crashInfo.stackTrace != null) {
14610                    sb.append(crashInfo.stackTrace);
14611                }
14612
14613                if (lines > 0) {
14614                    sb.append("\n");
14615
14616                    // Merge several logcat streams, and take the last N lines
14617                    InputStreamReader input = null;
14618                    try {
14619                        java.lang.Process logcat = new ProcessBuilder(
14620                                "/system/bin/timeout", "-k", "15s", "10s",
14621                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14622                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14623                                        .redirectErrorStream(true).start();
14624
14625                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14626                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14627                        input = new InputStreamReader(logcat.getInputStream());
14628
14629                        int num;
14630                        char[] buf = new char[8192];
14631                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14632                    } catch (IOException e) {
14633                        Slog.e(TAG, "Error running logcat", e);
14634                    } finally {
14635                        if (input != null) try { input.close(); } catch (IOException e) {}
14636                    }
14637                }
14638
14639                dbox.addText(dropboxTag, sb.toString());
14640            }
14641        };
14642
14643        if (process == null) {
14644            // If process is null, we are being called from some internal code
14645            // and may be about to die -- run this synchronously.
14646            worker.run();
14647        } else {
14648            worker.start();
14649        }
14650    }
14651
14652    @Override
14653    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14654        enforceNotIsolatedCaller("getProcessesInErrorState");
14655        // assume our apps are happy - lazy create the list
14656        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14657
14658        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14659                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14660        int userId = UserHandle.getUserId(Binder.getCallingUid());
14661
14662        synchronized (this) {
14663
14664            // iterate across all processes
14665            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14666                ProcessRecord app = mLruProcesses.get(i);
14667                if (!allUsers && app.userId != userId) {
14668                    continue;
14669                }
14670                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14671                    // This one's in trouble, so we'll generate a report for it
14672                    // crashes are higher priority (in case there's a crash *and* an anr)
14673                    ActivityManager.ProcessErrorStateInfo report = null;
14674                    if (app.crashing) {
14675                        report = app.crashingReport;
14676                    } else if (app.notResponding) {
14677                        report = app.notRespondingReport;
14678                    }
14679
14680                    if (report != null) {
14681                        if (errList == null) {
14682                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14683                        }
14684                        errList.add(report);
14685                    } else {
14686                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14687                                " crashing = " + app.crashing +
14688                                " notResponding = " + app.notResponding);
14689                    }
14690                }
14691            }
14692        }
14693
14694        return errList;
14695    }
14696
14697    static int procStateToImportance(int procState, int memAdj,
14698            ActivityManager.RunningAppProcessInfo currApp,
14699            int clientTargetSdk) {
14700        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14701                procState, clientTargetSdk);
14702        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14703            currApp.lru = memAdj;
14704        } else {
14705            currApp.lru = 0;
14706        }
14707        return imp;
14708    }
14709
14710    private void fillInProcMemInfo(ProcessRecord app,
14711            ActivityManager.RunningAppProcessInfo outInfo,
14712            int clientTargetSdk) {
14713        outInfo.pid = app.pid;
14714        outInfo.uid = app.info.uid;
14715        if (mHeavyWeightProcess == app) {
14716            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14717        }
14718        if (app.persistent) {
14719            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14720        }
14721        if (app.activities.size() > 0) {
14722            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14723        }
14724        outInfo.lastTrimLevel = app.trimMemoryLevel;
14725        int adj = app.curAdj;
14726        int procState = app.curProcState;
14727        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14728        outInfo.importanceReasonCode = app.adjTypeCode;
14729        outInfo.processState = app.curProcState;
14730    }
14731
14732    @Override
14733    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14734        enforceNotIsolatedCaller("getRunningAppProcesses");
14735
14736        final int callingUid = Binder.getCallingUid();
14737        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14738
14739        // Lazy instantiation of list
14740        List<ActivityManager.RunningAppProcessInfo> runList = null;
14741        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14742                callingUid) == PackageManager.PERMISSION_GRANTED;
14743        final int userId = UserHandle.getUserId(callingUid);
14744        final boolean allUids = isGetTasksAllowed(
14745                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14746
14747        synchronized (this) {
14748            // Iterate across all processes
14749            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14750                ProcessRecord app = mLruProcesses.get(i);
14751                if ((!allUsers && app.userId != userId)
14752                        || (!allUids && app.uid != callingUid)) {
14753                    continue;
14754                }
14755                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14756                    // Generate process state info for running application
14757                    ActivityManager.RunningAppProcessInfo currApp =
14758                        new ActivityManager.RunningAppProcessInfo(app.processName,
14759                                app.pid, app.getPackageList());
14760                    fillInProcMemInfo(app, currApp, clientTargetSdk);
14761                    if (app.adjSource instanceof ProcessRecord) {
14762                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14763                        currApp.importanceReasonImportance =
14764                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14765                                        app.adjSourceProcState);
14766                    } else if (app.adjSource instanceof ActivityRecord) {
14767                        ActivityRecord r = (ActivityRecord)app.adjSource;
14768                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14769                    }
14770                    if (app.adjTarget instanceof ComponentName) {
14771                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14772                    }
14773                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14774                    //        + " lru=" + currApp.lru);
14775                    if (runList == null) {
14776                        runList = new ArrayList<>();
14777                    }
14778                    runList.add(currApp);
14779                }
14780            }
14781        }
14782        return runList;
14783    }
14784
14785    @Override
14786    public List<ApplicationInfo> getRunningExternalApplications() {
14787        enforceNotIsolatedCaller("getRunningExternalApplications");
14788        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14789        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14790        if (runningApps != null && runningApps.size() > 0) {
14791            Set<String> extList = new HashSet<String>();
14792            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14793                if (app.pkgList != null) {
14794                    for (String pkg : app.pkgList) {
14795                        extList.add(pkg);
14796                    }
14797                }
14798            }
14799            IPackageManager pm = AppGlobals.getPackageManager();
14800            for (String pkg : extList) {
14801                try {
14802                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14803                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14804                        retList.add(info);
14805                    }
14806                } catch (RemoteException e) {
14807                }
14808            }
14809        }
14810        return retList;
14811    }
14812
14813    @Override
14814    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14815        enforceNotIsolatedCaller("getMyMemoryState");
14816
14817        final int callingUid = Binder.getCallingUid();
14818        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14819
14820        synchronized (this) {
14821            ProcessRecord proc;
14822            synchronized (mPidsSelfLocked) {
14823                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14824            }
14825            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14826        }
14827    }
14828
14829    @Override
14830    public int getMemoryTrimLevel() {
14831        enforceNotIsolatedCaller("getMyMemoryState");
14832        synchronized (this) {
14833            return mLastMemoryLevel;
14834        }
14835    }
14836
14837    @Override
14838    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14839            FileDescriptor err, String[] args, ShellCallback callback,
14840            ResultReceiver resultReceiver) {
14841        (new ActivityManagerShellCommand(this, false)).exec(
14842                this, in, out, err, args, callback, resultReceiver);
14843    }
14844
14845    SleepToken acquireSleepToken(String tag, int displayId) {
14846        synchronized (this) {
14847            final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
14848            updateSleepIfNeededLocked();
14849            return token;
14850        }
14851    }
14852
14853    @Override
14854    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14855        PriorityDump.dump(mPriorityDumper, fd, pw, args);
14856    }
14857
14858    /**
14859     * Wrapper function to print out debug data filtered by specified arguments.
14860    */
14861    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
14862        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14863
14864        boolean dumpAll = false;
14865        boolean dumpClient = false;
14866        boolean dumpCheckin = false;
14867        boolean dumpCheckinFormat = false;
14868        boolean dumpVisibleStacksOnly = false;
14869        boolean dumpFocusedStackOnly = false;
14870        String dumpPackage = null;
14871
14872        int opti = 0;
14873        while (opti < args.length) {
14874            String opt = args[opti];
14875            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14876                break;
14877            }
14878            opti++;
14879            if ("-a".equals(opt)) {
14880                dumpAll = true;
14881            } else if ("-c".equals(opt)) {
14882                dumpClient = true;
14883            } else if ("-v".equals(opt)) {
14884                dumpVisibleStacksOnly = true;
14885            } else if ("-f".equals(opt)) {
14886                dumpFocusedStackOnly = true;
14887            } else if ("-p".equals(opt)) {
14888                if (opti < args.length) {
14889                    dumpPackage = args[opti];
14890                    opti++;
14891                } else {
14892                    pw.println("Error: -p option requires package argument");
14893                    return;
14894                }
14895                dumpClient = true;
14896            } else if ("--checkin".equals(opt)) {
14897                dumpCheckin = dumpCheckinFormat = true;
14898            } else if ("-C".equals(opt)) {
14899                dumpCheckinFormat = true;
14900            } else if ("-h".equals(opt)) {
14901                ActivityManagerShellCommand.dumpHelp(pw, true);
14902                return;
14903            } else {
14904                pw.println("Unknown argument: " + opt + "; use -h for help");
14905            }
14906        }
14907
14908        long origId = Binder.clearCallingIdentity();
14909
14910        if (useProto) {
14911            final ProtoOutputStream proto = new ProtoOutputStream(fd);
14912            String cmd = opti < args.length ? args[opti] : "";
14913            opti++;
14914
14915            if ("activities".equals(cmd) || "a".equals(cmd)) {
14916                // output proto is ActivityStackSupervisorProto
14917                synchronized (this) {
14918                    writeActivitiesToProtoLocked(proto);
14919                }
14920            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14921                // output proto is BroadcastProto
14922                synchronized (this) {
14923                    writeBroadcastsToProtoLocked(proto);
14924                }
14925            } else {
14926                // default option, dump everything, output is ActivityManagerServiceProto
14927                synchronized (this) {
14928                    long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
14929                    writeActivitiesToProtoLocked(proto);
14930                    proto.end(activityToken);
14931
14932                    long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
14933                    writeBroadcastsToProtoLocked(proto);
14934                    proto.end(broadcastToken);
14935                }
14936            }
14937            proto.flush();
14938            Binder.restoreCallingIdentity(origId);
14939            return;
14940        }
14941
14942        boolean more = false;
14943        // Is the caller requesting to dump a particular piece of data?
14944        if (opti < args.length) {
14945            String cmd = args[opti];
14946            opti++;
14947            if ("activities".equals(cmd) || "a".equals(cmd)) {
14948                synchronized (this) {
14949                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14950                }
14951            } else if ("lastanr".equals(cmd)) {
14952                synchronized (this) {
14953                    dumpLastANRLocked(pw);
14954                }
14955            } else if ("starter".equals(cmd)) {
14956                synchronized (this) {
14957                    dumpActivityStarterLocked(pw, dumpPackage);
14958                }
14959            } else if ("containers".equals(cmd)) {
14960                synchronized (this) {
14961                    dumpActivityContainersLocked(pw);
14962                }
14963            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14964                synchronized (this) {
14965                    if (mRecentTasks != null) {
14966                        mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
14967                    }
14968                }
14969            } else if ("binder-proxies".equals(cmd)) {
14970                if (opti >= args.length) {
14971                    dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
14972                            "Counts of Binder Proxies held by SYSTEM");
14973                } else {
14974                    String uid = args[opti];
14975                    opti++;
14976                    // Ensure Binder Proxy Count is as up to date as possible
14977                    System.gc();
14978                    System.runFinalization();
14979                    System.gc();
14980                    pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
14981                }
14982            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14983                String[] newArgs;
14984                String name;
14985                if (opti >= args.length) {
14986                    name = null;
14987                    newArgs = EMPTY_STRING_ARRAY;
14988                } else {
14989                    dumpPackage = args[opti];
14990                    opti++;
14991                    newArgs = new String[args.length - opti];
14992                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14993                            args.length - opti);
14994                }
14995                synchronized (this) {
14996                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14997                }
14998            } else if ("broadcast-stats".equals(cmd)) {
14999                String[] newArgs;
15000                String name;
15001                if (opti >= args.length) {
15002                    name = null;
15003                    newArgs = EMPTY_STRING_ARRAY;
15004                } else {
15005                    dumpPackage = args[opti];
15006                    opti++;
15007                    newArgs = new String[args.length - opti];
15008                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15009                            args.length - opti);
15010                }
15011                synchronized (this) {
15012                    if (dumpCheckinFormat) {
15013                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15014                                dumpPackage);
15015                    } else {
15016                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15017                    }
15018                }
15019            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15020                String[] newArgs;
15021                String name;
15022                if (opti >= args.length) {
15023                    name = null;
15024                    newArgs = EMPTY_STRING_ARRAY;
15025                } else {
15026                    dumpPackage = args[opti];
15027                    opti++;
15028                    newArgs = new String[args.length - opti];
15029                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15030                            args.length - opti);
15031                }
15032                synchronized (this) {
15033                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15034                }
15035            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15036                String[] newArgs;
15037                String name;
15038                if (opti >= args.length) {
15039                    name = null;
15040                    newArgs = EMPTY_STRING_ARRAY;
15041                } else {
15042                    dumpPackage = args[opti];
15043                    opti++;
15044                    newArgs = new String[args.length - opti];
15045                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15046                            args.length - opti);
15047                }
15048                synchronized (this) {
15049                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15050                }
15051            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15052                synchronized (this) {
15053                    dumpOomLocked(fd, pw, args, opti, true);
15054                }
15055            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15056                synchronized (this) {
15057                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
15058                }
15059            } else if ("provider".equals(cmd)) {
15060                String[] newArgs;
15061                String name;
15062                if (opti >= args.length) {
15063                    name = null;
15064                    newArgs = EMPTY_STRING_ARRAY;
15065                } else {
15066                    name = args[opti];
15067                    opti++;
15068                    newArgs = new String[args.length - opti];
15069                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15070                }
15071                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15072                    pw.println("No providers match: " + name);
15073                    pw.println("Use -h for help.");
15074                }
15075            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15076                synchronized (this) {
15077                    dumpProvidersLocked(fd, pw, args, opti, true, null);
15078                }
15079            } else if ("service".equals(cmd)) {
15080                String[] newArgs;
15081                String name;
15082                if (opti >= args.length) {
15083                    name = null;
15084                    newArgs = EMPTY_STRING_ARRAY;
15085                } else {
15086                    name = args[opti];
15087                    opti++;
15088                    newArgs = new String[args.length - opti];
15089                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15090                            args.length - opti);
15091                }
15092                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15093                    pw.println("No services match: " + name);
15094                    pw.println("Use -h for help.");
15095                }
15096            } else if ("package".equals(cmd)) {
15097                String[] newArgs;
15098                if (opti >= args.length) {
15099                    pw.println("package: no package name specified");
15100                    pw.println("Use -h for help.");
15101                } else {
15102                    dumpPackage = args[opti];
15103                    opti++;
15104                    newArgs = new String[args.length - opti];
15105                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15106                            args.length - opti);
15107                    args = newArgs;
15108                    opti = 0;
15109                    more = true;
15110                }
15111            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15112                synchronized (this) {
15113                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15114                }
15115            } else if ("settings".equals(cmd)) {
15116                synchronized (this) {
15117                    mConstants.dump(pw);
15118                }
15119            } else if ("services".equals(cmd) || "s".equals(cmd)) {
15120                if (dumpClient) {
15121                    ActiveServices.ServiceDumper dumper;
15122                    synchronized (this) {
15123                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15124                                dumpPackage);
15125                    }
15126                    dumper.dumpWithClient();
15127                } else {
15128                    synchronized (this) {
15129                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15130                                dumpPackage).dumpLocked();
15131                    }
15132                }
15133            } else if ("locks".equals(cmd)) {
15134                LockGuard.dump(fd, pw, args);
15135            } else {
15136                // Dumping a single activity?
15137                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15138                        dumpFocusedStackOnly)) {
15139                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15140                    int res = shell.exec(this, null, fd, null, args, null,
15141                            new ResultReceiver(null));
15142                    if (res < 0) {
15143                        pw.println("Bad activity command, or no activities match: " + cmd);
15144                        pw.println("Use -h for help.");
15145                    }
15146                }
15147            }
15148            if (!more) {
15149                Binder.restoreCallingIdentity(origId);
15150                return;
15151            }
15152        }
15153
15154        // No piece of data specified, dump everything.
15155        if (dumpCheckinFormat) {
15156            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15157        } else if (dumpClient) {
15158            ActiveServices.ServiceDumper sdumper;
15159            synchronized (this) {
15160                mConstants.dump(pw);
15161                pw.println();
15162                if (dumpAll) {
15163                    pw.println("-------------------------------------------------------------------------------");
15164                }
15165                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15166                pw.println();
15167                if (dumpAll) {
15168                    pw.println("-------------------------------------------------------------------------------");
15169                }
15170                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15171                pw.println();
15172                if (dumpAll) {
15173                    pw.println("-------------------------------------------------------------------------------");
15174                }
15175                if (dumpAll || dumpPackage != null) {
15176                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15177                    pw.println();
15178                    if (dumpAll) {
15179                        pw.println("-------------------------------------------------------------------------------");
15180                    }
15181                }
15182                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15183                pw.println();
15184                if (dumpAll) {
15185                    pw.println("-------------------------------------------------------------------------------");
15186                }
15187                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15188                pw.println();
15189                if (dumpAll) {
15190                    pw.println("-------------------------------------------------------------------------------");
15191                }
15192                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15193                        dumpPackage);
15194            }
15195            sdumper.dumpWithClient();
15196            pw.println();
15197            synchronized (this) {
15198                if (dumpAll) {
15199                    pw.println("-------------------------------------------------------------------------------");
15200                }
15201                if (mRecentTasks != null) {
15202                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
15203                }
15204                pw.println();
15205                if (dumpAll) {
15206                    pw.println("-------------------------------------------------------------------------------");
15207                }
15208                dumpLastANRLocked(pw);
15209                pw.println();
15210                if (dumpAll) {
15211                    pw.println("-------------------------------------------------------------------------------");
15212                }
15213                dumpActivityStarterLocked(pw, dumpPackage);
15214                pw.println();
15215                if (dumpAll) {
15216                    pw.println("-------------------------------------------------------------------------------");
15217                }
15218                dumpActivityContainersLocked(pw);
15219                pw.println();
15220                if (dumpAll) {
15221                    pw.println("-------------------------------------------------------------------------------");
15222                }
15223                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15224                if (mAssociations.size() > 0) {
15225                    pw.println();
15226                    if (dumpAll) {
15227                        pw.println("-------------------------------------------------------------------------------");
15228                    }
15229                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15230                }
15231                pw.println();
15232                if (dumpAll) {
15233                    pw.println("-------------------------------------------------------------------------------");
15234                }
15235                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15236            }
15237
15238        } else {
15239            synchronized (this) {
15240                mConstants.dump(pw);
15241                pw.println();
15242                if (dumpAll) {
15243                    pw.println("-------------------------------------------------------------------------------");
15244                }
15245                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15246                pw.println();
15247                if (dumpAll) {
15248                    pw.println("-------------------------------------------------------------------------------");
15249                }
15250                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15251                pw.println();
15252                if (dumpAll) {
15253                    pw.println("-------------------------------------------------------------------------------");
15254                }
15255                if (dumpAll || dumpPackage != null) {
15256                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15257                    pw.println();
15258                    if (dumpAll) {
15259                        pw.println("-------------------------------------------------------------------------------");
15260                    }
15261                }
15262                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15263                pw.println();
15264                if (dumpAll) {
15265                    pw.println("-------------------------------------------------------------------------------");
15266                }
15267                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15268                pw.println();
15269                if (dumpAll) {
15270                    pw.println("-------------------------------------------------------------------------------");
15271                }
15272                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15273                        .dumpLocked();
15274                pw.println();
15275                if (dumpAll) {
15276                    pw.println("-------------------------------------------------------------------------------");
15277                }
15278                if (mRecentTasks != null) {
15279                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
15280                }
15281                pw.println();
15282                if (dumpAll) {
15283                    pw.println("-------------------------------------------------------------------------------");
15284                }
15285                dumpLastANRLocked(pw);
15286                pw.println();
15287                if (dumpAll) {
15288                    pw.println("-------------------------------------------------------------------------------");
15289                }
15290                dumpActivityStarterLocked(pw, dumpPackage);
15291                pw.println();
15292                if (dumpAll) {
15293                    pw.println("-------------------------------------------------------------------------------");
15294                }
15295                dumpActivityContainersLocked(pw);
15296                pw.println();
15297                if (dumpAll) {
15298                    pw.println("-------------------------------------------------------------------------------");
15299                }
15300                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15301                if (mAssociations.size() > 0) {
15302                    pw.println();
15303                    if (dumpAll) {
15304                        pw.println("-------------------------------------------------------------------------------");
15305                    }
15306                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15307                }
15308                pw.println();
15309                if (dumpAll) {
15310                    pw.println("-------------------------------------------------------------------------------");
15311                }
15312                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15313            }
15314        }
15315        Binder.restoreCallingIdentity(origId);
15316    }
15317
15318    private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
15319        // The output proto of "activity --proto activities" is ActivityStackSupervisorProto
15320        mStackSupervisor.writeToProto(proto);
15321    }
15322
15323    private void dumpLastANRLocked(PrintWriter pw) {
15324        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15325        if (mLastANRState == null) {
15326            pw.println("  <no ANR has occurred since boot>");
15327        } else {
15328            pw.println(mLastANRState);
15329        }
15330    }
15331
15332    private void dumpActivityContainersLocked(PrintWriter pw) {
15333        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
15334        mStackSupervisor.dumpChildrenNames(pw, " ");
15335        pw.println(" ");
15336    }
15337
15338    private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15339        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15340        mActivityStarter.dump(pw, "", dumpPackage);
15341    }
15342
15343    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15344            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15345        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15346                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15347    }
15348
15349    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15350            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15351        pw.println(header);
15352
15353        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15354                dumpPackage);
15355        boolean needSep = printedAnything;
15356
15357        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15358                mStackSupervisor.getResumedActivityLocked(),
15359                dumpPackage, needSep, "  ResumedActivity: ");
15360        if (printed) {
15361            printedAnything = true;
15362            needSep = false;
15363        }
15364
15365        if (dumpPackage == null) {
15366            if (needSep) {
15367                pw.println();
15368            }
15369            printedAnything = true;
15370            mStackSupervisor.dump(pw, "  ");
15371        }
15372
15373        if (!printedAnything) {
15374            pw.println("  (nothing)");
15375        }
15376    }
15377
15378    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15379            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15380        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15381
15382        int dumpUid = 0;
15383        if (dumpPackage != null) {
15384            IPackageManager pm = AppGlobals.getPackageManager();
15385            try {
15386                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15387            } catch (RemoteException e) {
15388            }
15389        }
15390
15391        boolean printedAnything = false;
15392
15393        final long now = SystemClock.uptimeMillis();
15394
15395        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15396            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15397                    = mAssociations.valueAt(i1);
15398            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15399                SparseArray<ArrayMap<String, Association>> sourceUids
15400                        = targetComponents.valueAt(i2);
15401                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15402                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15403                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15404                        Association ass = sourceProcesses.valueAt(i4);
15405                        if (dumpPackage != null) {
15406                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15407                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15408                                continue;
15409                            }
15410                        }
15411                        printedAnything = true;
15412                        pw.print("  ");
15413                        pw.print(ass.mTargetProcess);
15414                        pw.print("/");
15415                        UserHandle.formatUid(pw, ass.mTargetUid);
15416                        pw.print(" <- ");
15417                        pw.print(ass.mSourceProcess);
15418                        pw.print("/");
15419                        UserHandle.formatUid(pw, ass.mSourceUid);
15420                        pw.println();
15421                        pw.print("    via ");
15422                        pw.print(ass.mTargetComponent.flattenToShortString());
15423                        pw.println();
15424                        pw.print("    ");
15425                        long dur = ass.mTime;
15426                        if (ass.mNesting > 0) {
15427                            dur += now - ass.mStartTime;
15428                        }
15429                        TimeUtils.formatDuration(dur, pw);
15430                        pw.print(" (");
15431                        pw.print(ass.mCount);
15432                        pw.print(" times)");
15433                        pw.print("  ");
15434                        for (int i=0; i<ass.mStateTimes.length; i++) {
15435                            long amt = ass.mStateTimes[i];
15436                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15437                                amt += now - ass.mLastStateUptime;
15438                            }
15439                            if (amt != 0) {
15440                                pw.print(" ");
15441                                pw.print(ProcessList.makeProcStateString(
15442                                            i + ActivityManager.MIN_PROCESS_STATE));
15443                                pw.print("=");
15444                                TimeUtils.formatDuration(amt, pw);
15445                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15446                                    pw.print("*");
15447                                }
15448                            }
15449                        }
15450                        pw.println();
15451                        if (ass.mNesting > 0) {
15452                            pw.print("    Currently active: ");
15453                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
15454                            pw.println();
15455                        }
15456                    }
15457                }
15458            }
15459
15460        }
15461
15462        if (!printedAnything) {
15463            pw.println("  (nothing)");
15464        }
15465    }
15466
15467    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15468            String header, boolean needSep) {
15469        boolean printed = false;
15470        int whichAppId = -1;
15471        if (dumpPackage != null) {
15472            try {
15473                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15474                        dumpPackage, 0);
15475                whichAppId = UserHandle.getAppId(info.uid);
15476            } catch (NameNotFoundException e) {
15477                e.printStackTrace();
15478            }
15479        }
15480        for (int i=0; i<uids.size(); i++) {
15481            UidRecord uidRec = uids.valueAt(i);
15482            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15483                continue;
15484            }
15485            if (!printed) {
15486                printed = true;
15487                if (needSep) {
15488                    pw.println();
15489                }
15490                pw.print("  ");
15491                pw.println(header);
15492                needSep = true;
15493            }
15494            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15495            pw.print(": "); pw.println(uidRec);
15496        }
15497        return printed;
15498    }
15499
15500    boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
15501        if(counts != null) {
15502            pw.println(header);
15503            for (int i = 0; i < counts.size(); i++) {
15504                final int uid = counts.keyAt(i);
15505                final int binderCount = counts.valueAt(i);
15506                pw.print("    UID ");
15507                pw.print(uid);
15508                pw.print(", binder count = ");
15509                pw.print(binderCount);
15510                pw.print(", package(s)= ");
15511                final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
15512                if (pkgNames != null) {
15513                    for (int j = 0; j < pkgNames.length; j++) {
15514                        pw.print(pkgNames[j]);
15515                        pw.print("; ");
15516                    }
15517                } else {
15518                    pw.print("NO PACKAGE NAME FOUND");
15519                }
15520                pw.println();
15521            }
15522            pw.println();
15523            return true;
15524        }
15525        return false;
15526    }
15527
15528    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15529            int opti, boolean dumpAll, String dumpPackage) {
15530        boolean needSep = false;
15531        boolean printedAnything = false;
15532        int numPers = 0;
15533
15534        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15535
15536        if (dumpAll) {
15537            final int NP = mProcessNames.getMap().size();
15538            for (int ip=0; ip<NP; ip++) {
15539                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15540                final int NA = procs.size();
15541                for (int ia=0; ia<NA; ia++) {
15542                    ProcessRecord r = procs.valueAt(ia);
15543                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15544                        continue;
15545                    }
15546                    if (!needSep) {
15547                        pw.println("  All known processes:");
15548                        needSep = true;
15549                        printedAnything = true;
15550                    }
15551                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15552                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15553                        pw.print(" "); pw.println(r);
15554                    r.dump(pw, "    ");
15555                    if (r.persistent) {
15556                        numPers++;
15557                    }
15558                }
15559            }
15560        }
15561
15562        if (mIsolatedProcesses.size() > 0) {
15563            boolean printed = false;
15564            for (int i=0; i<mIsolatedProcesses.size(); i++) {
15565                ProcessRecord r = mIsolatedProcesses.valueAt(i);
15566                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15567                    continue;
15568                }
15569                if (!printed) {
15570                    if (needSep) {
15571                        pw.println();
15572                    }
15573                    pw.println("  Isolated process list (sorted by uid):");
15574                    printedAnything = true;
15575                    printed = true;
15576                    needSep = true;
15577                }
15578                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15579                pw.println(r);
15580            }
15581        }
15582
15583        if (mActiveInstrumentation.size() > 0) {
15584            boolean printed = false;
15585            for (int i=0; i<mActiveInstrumentation.size(); i++) {
15586                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15587                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15588                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15589                    continue;
15590                }
15591                if (!printed) {
15592                    if (needSep) {
15593                        pw.println();
15594                    }
15595                    pw.println("  Active instrumentation:");
15596                    printedAnything = true;
15597                    printed = true;
15598                    needSep = true;
15599                }
15600                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15601                pw.println(ai);
15602                ai.dump(pw, "      ");
15603            }
15604        }
15605
15606        if (mActiveUids.size() > 0) {
15607            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15608                printedAnything = needSep = true;
15609            }
15610        }
15611        if (dumpAll) {
15612            if (mValidateUids.size() > 0) {
15613                if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15614                    printedAnything = needSep = true;
15615                }
15616            }
15617        }
15618
15619        if (mLruProcesses.size() > 0) {
15620            if (needSep) {
15621                pw.println();
15622            }
15623            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15624                    pw.print(" total, non-act at ");
15625                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15626                    pw.print(", non-svc at ");
15627                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15628                    pw.println("):");
15629            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15630            needSep = true;
15631            printedAnything = true;
15632        }
15633
15634        if (dumpAll || dumpPackage != null) {
15635            synchronized (mPidsSelfLocked) {
15636                boolean printed = false;
15637                for (int i=0; i<mPidsSelfLocked.size(); i++) {
15638                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
15639                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15640                        continue;
15641                    }
15642                    if (!printed) {
15643                        if (needSep) pw.println();
15644                        needSep = true;
15645                        pw.println("  PID mappings:");
15646                        printed = true;
15647                        printedAnything = true;
15648                    }
15649                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15650                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15651                }
15652            }
15653        }
15654
15655        if (mImportantProcesses.size() > 0) {
15656            synchronized (mPidsSelfLocked) {
15657                boolean printed = false;
15658                for (int i = 0; i< mImportantProcesses.size(); i++) {
15659                    ProcessRecord r = mPidsSelfLocked.get(
15660                            mImportantProcesses.valueAt(i).pid);
15661                    if (dumpPackage != null && (r == null
15662                            || !r.pkgList.containsKey(dumpPackage))) {
15663                        continue;
15664                    }
15665                    if (!printed) {
15666                        if (needSep) pw.println();
15667                        needSep = true;
15668                        pw.println("  Foreground Processes:");
15669                        printed = true;
15670                        printedAnything = true;
15671                    }
15672                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15673                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15674                }
15675            }
15676        }
15677
15678        if (mPersistentStartingProcesses.size() > 0) {
15679            if (needSep) pw.println();
15680            needSep = true;
15681            printedAnything = true;
15682            pw.println("  Persisent processes that are starting:");
15683            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15684                    "Starting Norm", "Restarting PERS", dumpPackage);
15685        }
15686
15687        if (mRemovedProcesses.size() > 0) {
15688            if (needSep) pw.println();
15689            needSep = true;
15690            printedAnything = true;
15691            pw.println("  Processes that are being removed:");
15692            dumpProcessList(pw, this, mRemovedProcesses, "    ",
15693                    "Removed Norm", "Removed PERS", dumpPackage);
15694        }
15695
15696        if (mProcessesOnHold.size() > 0) {
15697            if (needSep) pw.println();
15698            needSep = true;
15699            printedAnything = true;
15700            pw.println("  Processes that are on old until the system is ready:");
15701            dumpProcessList(pw, this, mProcessesOnHold, "    ",
15702                    "OnHold Norm", "OnHold PERS", dumpPackage);
15703        }
15704
15705        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15706
15707        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15708        if (needSep) {
15709            printedAnything = true;
15710        }
15711
15712        if (dumpPackage == null) {
15713            pw.println();
15714            needSep = false;
15715            mUserController.dump(pw, dumpAll);
15716        }
15717        if (mHomeProcess != null && (dumpPackage == null
15718                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15719            if (needSep) {
15720                pw.println();
15721                needSep = false;
15722            }
15723            pw.println("  mHomeProcess: " + mHomeProcess);
15724        }
15725        if (mPreviousProcess != null && (dumpPackage == null
15726                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15727            if (needSep) {
15728                pw.println();
15729                needSep = false;
15730            }
15731            pw.println("  mPreviousProcess: " + mPreviousProcess);
15732        }
15733        if (dumpAll && (mPreviousProcess == null || dumpPackage == null
15734                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15735            StringBuilder sb = new StringBuilder(128);
15736            sb.append("  mPreviousProcessVisibleTime: ");
15737            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15738            pw.println(sb);
15739        }
15740        if (mHeavyWeightProcess != null && (dumpPackage == null
15741                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15742            if (needSep) {
15743                pw.println();
15744                needSep = false;
15745            }
15746            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15747        }
15748        if (dumpPackage == null) {
15749            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15750            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15751        }
15752        if (dumpAll) {
15753            if (dumpPackage == null) {
15754                pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15755            }
15756            if (mCompatModePackages.getPackages().size() > 0) {
15757                boolean printed = false;
15758                for (Map.Entry<String, Integer> entry
15759                        : mCompatModePackages.getPackages().entrySet()) {
15760                    String pkg = entry.getKey();
15761                    int mode = entry.getValue();
15762                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15763                        continue;
15764                    }
15765                    if (!printed) {
15766                        pw.println("  mScreenCompatPackages:");
15767                        printed = true;
15768                    }
15769                    pw.print("    "); pw.print(pkg); pw.print(": ");
15770                            pw.print(mode); pw.println();
15771                }
15772            }
15773            final int NI = mUidObservers.getRegisteredCallbackCount();
15774            boolean printed = false;
15775            for (int i=0; i<NI; i++) {
15776                final UidObserverRegistration reg = (UidObserverRegistration)
15777                        mUidObservers.getRegisteredCallbackCookie(i);
15778                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15779                    if (!printed) {
15780                        pw.println("  mUidObservers:");
15781                        printed = true;
15782                    }
15783                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15784                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
15785                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15786                        pw.print(" IDLE");
15787                    }
15788                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15789                        pw.print(" ACT" );
15790                    }
15791                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15792                        pw.print(" GONE");
15793                    }
15794                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15795                        pw.print(" STATE");
15796                        pw.print(" (cut="); pw.print(reg.cutpoint);
15797                        pw.print(")");
15798                    }
15799                    pw.println();
15800                    if (reg.lastProcStates != null) {
15801                        final int NJ = reg.lastProcStates.size();
15802                        for (int j=0; j<NJ; j++) {
15803                            pw.print("      Last ");
15804                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15805                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15806                        }
15807                    }
15808                }
15809            }
15810            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15811            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15812            if (mPendingTempWhitelist.size() > 0) {
15813                pw.println("  mPendingTempWhitelist:");
15814                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15815                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15816                    pw.print("    ");
15817                    UserHandle.formatUid(pw, ptw.targetUid);
15818                    pw.print(": ");
15819                    TimeUtils.formatDuration(ptw.duration, pw);
15820                    pw.print(" ");
15821                    pw.println(ptw.tag);
15822                }
15823            }
15824        }
15825        if (dumpPackage == null) {
15826            pw.println("  mWakefulness="
15827                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
15828            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
15829            pw.println("  mSleeping=" + mSleeping);
15830            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15831            if (mRunningVoice != null) {
15832                pw.println("  mRunningVoice=" + mRunningVoice);
15833                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15834            }
15835            pw.println("  mVrController=" + mVrController);
15836        }
15837        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15838                || mOrigWaitForDebugger) {
15839            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15840                    || dumpPackage.equals(mOrigDebugApp)) {
15841                if (needSep) {
15842                    pw.println();
15843                    needSep = false;
15844                }
15845                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15846                        + " mDebugTransient=" + mDebugTransient
15847                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15848            }
15849        }
15850        if (mCurAppTimeTracker != null) {
15851            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15852        }
15853        if (mMemWatchProcesses.getMap().size() > 0) {
15854            pw.println("  Mem watch processes:");
15855            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15856                    = mMemWatchProcesses.getMap();
15857            for (int i=0; i<procs.size(); i++) {
15858                final String proc = procs.keyAt(i);
15859                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15860                for (int j=0; j<uids.size(); j++) {
15861                    if (needSep) {
15862                        pw.println();
15863                        needSep = false;
15864                    }
15865                    StringBuilder sb = new StringBuilder();
15866                    sb.append("    ").append(proc).append('/');
15867                    UserHandle.formatUid(sb, uids.keyAt(j));
15868                    Pair<Long, String> val = uids.valueAt(j);
15869                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15870                    if (val.second != null) {
15871                        sb.append(", report to ").append(val.second);
15872                    }
15873                    pw.println(sb.toString());
15874                }
15875            }
15876            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15877            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15878            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15879                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15880        }
15881        if (mTrackAllocationApp != null) {
15882            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15883                if (needSep) {
15884                    pw.println();
15885                    needSep = false;
15886                }
15887                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15888            }
15889        }
15890        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
15891                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
15892            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15893                if (needSep) {
15894                    pw.println();
15895                    needSep = false;
15896                }
15897                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15898                if (mProfilerInfo != null) {
15899                    pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
15900                            mProfilerInfo.profileFd);
15901                    pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
15902                            " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
15903                            " mStreamingOutput=" + mProfilerInfo.streamingOutput);
15904                    pw.println("  mProfileType=" + mProfileType);
15905                }
15906            }
15907        }
15908        if (mNativeDebuggingApp != null) {
15909            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15910                if (needSep) {
15911                    pw.println();
15912                    needSep = false;
15913                }
15914                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15915            }
15916        }
15917        if (dumpPackage == null) {
15918            if (mAlwaysFinishActivities) {
15919                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15920            }
15921            if (mController != null) {
15922                pw.println("  mController=" + mController
15923                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15924            }
15925            if (dumpAll) {
15926                pw.println("  Total persistent processes: " + numPers);
15927                pw.println("  mProcessesReady=" + mProcessesReady
15928                        + " mSystemReady=" + mSystemReady
15929                        + " mBooted=" + mBooted
15930                        + " mFactoryTest=" + mFactoryTest);
15931                pw.println("  mBooting=" + mBooting
15932                        + " mCallFinishBooting=" + mCallFinishBooting
15933                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15934                pw.print("  mLastPowerCheckUptime=");
15935                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15936                        pw.println("");
15937                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15938                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15939                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15940                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15941                        + " (" + mLruProcesses.size() + " total)"
15942                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15943                        + " mNumServiceProcs=" + mNumServiceProcs
15944                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15945                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15946                        + " mLastMemoryLevel=" + mLastMemoryLevel
15947                        + " mLastNumProcesses=" + mLastNumProcesses);
15948                long now = SystemClock.uptimeMillis();
15949                pw.print("  mLastIdleTime=");
15950                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15951                        pw.print(" mLowRamSinceLastIdle=");
15952                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15953                        pw.println();
15954            }
15955        }
15956
15957        if (!printedAnything) {
15958            pw.println("  (nothing)");
15959        }
15960    }
15961
15962    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15963            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15964        if (mProcessesToGc.size() > 0) {
15965            boolean printed = false;
15966            long now = SystemClock.uptimeMillis();
15967            for (int i=0; i<mProcessesToGc.size(); i++) {
15968                ProcessRecord proc = mProcessesToGc.get(i);
15969                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15970                    continue;
15971                }
15972                if (!printed) {
15973                    if (needSep) pw.println();
15974                    needSep = true;
15975                    pw.println("  Processes that are waiting to GC:");
15976                    printed = true;
15977                }
15978                pw.print("    Process "); pw.println(proc);
15979                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15980                        pw.print(", last gced=");
15981                        pw.print(now-proc.lastRequestedGc);
15982                        pw.print(" ms ago, last lowMem=");
15983                        pw.print(now-proc.lastLowMemory);
15984                        pw.println(" ms ago");
15985
15986            }
15987        }
15988        return needSep;
15989    }
15990
15991    void printOomLevel(PrintWriter pw, String name, int adj) {
15992        pw.print("    ");
15993        if (adj >= 0) {
15994            pw.print(' ');
15995            if (adj < 10) pw.print(' ');
15996        } else {
15997            if (adj > -10) pw.print(' ');
15998        }
15999        pw.print(adj);
16000        pw.print(": ");
16001        pw.print(name);
16002        pw.print(" (");
16003        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16004        pw.println(")");
16005    }
16006
16007    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16008            int opti, boolean dumpAll) {
16009        boolean needSep = false;
16010
16011        if (mLruProcesses.size() > 0) {
16012            if (needSep) pw.println();
16013            needSep = true;
16014            pw.println("  OOM levels:");
16015            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16016            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16017            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16018            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16019            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16020            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16021            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16022            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16023            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16024            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16025            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16026            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16027            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16028            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16029
16030            if (needSep) pw.println();
16031            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16032                    pw.print(" total, non-act at ");
16033                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16034                    pw.print(", non-svc at ");
16035                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16036                    pw.println("):");
16037            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16038            needSep = true;
16039        }
16040
16041        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16042
16043        pw.println();
16044        pw.println("  mHomeProcess: " + mHomeProcess);
16045        pw.println("  mPreviousProcess: " + mPreviousProcess);
16046        if (mHeavyWeightProcess != null) {
16047            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16048        }
16049
16050        return true;
16051    }
16052
16053    /**
16054     * There are three ways to call this:
16055     *  - no provider specified: dump all the providers
16056     *  - a flattened component name that matched an existing provider was specified as the
16057     *    first arg: dump that one provider
16058     *  - the first arg isn't the flattened component name of an existing provider:
16059     *    dump all providers whose component contains the first arg as a substring
16060     */
16061    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16062            int opti, boolean dumpAll) {
16063        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16064    }
16065
16066    static class ItemMatcher {
16067        ArrayList<ComponentName> components;
16068        ArrayList<String> strings;
16069        ArrayList<Integer> objects;
16070        boolean all;
16071
16072        ItemMatcher() {
16073            all = true;
16074        }
16075
16076        void build(String name) {
16077            ComponentName componentName = ComponentName.unflattenFromString(name);
16078            if (componentName != null) {
16079                if (components == null) {
16080                    components = new ArrayList<ComponentName>();
16081                }
16082                components.add(componentName);
16083                all = false;
16084            } else {
16085                int objectId = 0;
16086                // Not a '/' separated full component name; maybe an object ID?
16087                try {
16088                    objectId = Integer.parseInt(name, 16);
16089                    if (objects == null) {
16090                        objects = new ArrayList<Integer>();
16091                    }
16092                    objects.add(objectId);
16093                    all = false;
16094                } catch (RuntimeException e) {
16095                    // Not an integer; just do string match.
16096                    if (strings == null) {
16097                        strings = new ArrayList<String>();
16098                    }
16099                    strings.add(name);
16100                    all = false;
16101                }
16102            }
16103        }
16104
16105        int build(String[] args, int opti) {
16106            for (; opti<args.length; opti++) {
16107                String name = args[opti];
16108                if ("--".equals(name)) {
16109                    return opti+1;
16110                }
16111                build(name);
16112            }
16113            return opti;
16114        }
16115
16116        boolean match(Object object, ComponentName comp) {
16117            if (all) {
16118                return true;
16119            }
16120            if (components != null) {
16121                for (int i=0; i<components.size(); i++) {
16122                    if (components.get(i).equals(comp)) {
16123                        return true;
16124                    }
16125                }
16126            }
16127            if (objects != null) {
16128                for (int i=0; i<objects.size(); i++) {
16129                    if (System.identityHashCode(object) == objects.get(i)) {
16130                        return true;
16131                    }
16132                }
16133            }
16134            if (strings != null) {
16135                String flat = comp.flattenToString();
16136                for (int i=0; i<strings.size(); i++) {
16137                    if (flat.contains(strings.get(i))) {
16138                        return true;
16139                    }
16140                }
16141            }
16142            return false;
16143        }
16144    }
16145
16146    /**
16147     * There are three things that cmd can be:
16148     *  - a flattened component name that matches an existing activity
16149     *  - the cmd arg isn't the flattened component name of an existing activity:
16150     *    dump all activity whose component contains the cmd as a substring
16151     *  - A hex number of the ActivityRecord object instance.
16152     *
16153     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16154     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16155     */
16156    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16157            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16158        ArrayList<ActivityRecord> activities;
16159
16160        synchronized (this) {
16161            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16162                    dumpFocusedStackOnly);
16163        }
16164
16165        if (activities.size() <= 0) {
16166            return false;
16167        }
16168
16169        String[] newArgs = new String[args.length - opti];
16170        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16171
16172        TaskRecord lastTask = null;
16173        boolean needSep = false;
16174        for (int i=activities.size()-1; i>=0; i--) {
16175            ActivityRecord r = activities.get(i);
16176            if (needSep) {
16177                pw.println();
16178            }
16179            needSep = true;
16180            synchronized (this) {
16181                final TaskRecord task = r.getTask();
16182                if (lastTask != task) {
16183                    lastTask = task;
16184                    pw.print("TASK "); pw.print(lastTask.affinity);
16185                            pw.print(" id="); pw.print(lastTask.taskId);
16186                            pw.print(" userId="); pw.println(lastTask.userId);
16187                    if (dumpAll) {
16188                        lastTask.dump(pw, "  ");
16189                    }
16190                }
16191            }
16192            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16193        }
16194        return true;
16195    }
16196
16197    /**
16198     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16199     * there is a thread associated with the activity.
16200     */
16201    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16202            final ActivityRecord r, String[] args, boolean dumpAll) {
16203        String innerPrefix = prefix + "  ";
16204        synchronized (this) {
16205            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16206                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16207                    pw.print(" pid=");
16208                    if (r.app != null) pw.println(r.app.pid);
16209                    else pw.println("(not running)");
16210            if (dumpAll) {
16211                r.dump(pw, innerPrefix);
16212            }
16213        }
16214        if (r.app != null && r.app.thread != null) {
16215            // flush anything that is already in the PrintWriter since the thread is going
16216            // to write to the file descriptor directly
16217            pw.flush();
16218            try {
16219                TransferPipe tp = new TransferPipe();
16220                try {
16221                    r.app.thread.dumpActivity(tp.getWriteFd(),
16222                            r.appToken, innerPrefix, args);
16223                    tp.go(fd);
16224                } finally {
16225                    tp.kill();
16226                }
16227            } catch (IOException e) {
16228                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16229            } catch (RemoteException e) {
16230                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16231            }
16232        }
16233    }
16234
16235    void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
16236        if (mRegisteredReceivers.size() > 0) {
16237            Iterator it = mRegisteredReceivers.values().iterator();
16238            while (it.hasNext()) {
16239                ReceiverList r = (ReceiverList)it.next();
16240                r.writeToProto(proto, BroadcastProto.RECEIVER_LIST);
16241            }
16242        }
16243        mReceiverResolver.writeToProto(proto, BroadcastProto.RECEIVER_RESOLVER);
16244        for (BroadcastQueue q : mBroadcastQueues) {
16245            q.writeToProto(proto, BroadcastProto.BROADCAST_QUEUE);
16246        }
16247        for (int user=0; user<mStickyBroadcasts.size(); user++) {
16248            long token = proto.start(BroadcastProto.STICKY_BROADCASTS);
16249            proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
16250            for (Map.Entry<String, ArrayList<Intent>> ent
16251                    : mStickyBroadcasts.valueAt(user).entrySet()) {
16252                long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
16253                proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
16254                for (Intent intent : ent.getValue()) {
16255                    intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
16256                            false, true, true, false);
16257                }
16258                proto.end(actionToken);
16259            }
16260            proto.end(token);
16261        }
16262
16263        long handlerToken = proto.start(BroadcastProto.HANDLER);
16264        proto.write(BroadcastProto.MainHandler.HANDLER, mHandler.toString());
16265        mHandler.getLooper().writeToProto(proto, BroadcastProto.MainHandler.LOOPER);
16266        proto.end(handlerToken);
16267    }
16268
16269    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16270            int opti, boolean dumpAll, String dumpPackage) {
16271        boolean needSep = false;
16272        boolean onlyHistory = false;
16273        boolean printedAnything = false;
16274
16275        if ("history".equals(dumpPackage)) {
16276            if (opti < args.length && "-s".equals(args[opti])) {
16277                dumpAll = false;
16278            }
16279            onlyHistory = true;
16280            dumpPackage = null;
16281        }
16282
16283        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16284        if (!onlyHistory && dumpAll) {
16285            if (mRegisteredReceivers.size() > 0) {
16286                boolean printed = false;
16287                Iterator it = mRegisteredReceivers.values().iterator();
16288                while (it.hasNext()) {
16289                    ReceiverList r = (ReceiverList)it.next();
16290                    if (dumpPackage != null && (r.app == null ||
16291                            !dumpPackage.equals(r.app.info.packageName))) {
16292                        continue;
16293                    }
16294                    if (!printed) {
16295                        pw.println("  Registered Receivers:");
16296                        needSep = true;
16297                        printed = true;
16298                        printedAnything = true;
16299                    }
16300                    pw.print("  * "); pw.println(r);
16301                    r.dump(pw, "    ");
16302                }
16303            }
16304
16305            if (mReceiverResolver.dump(pw, needSep ?
16306                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16307                    "    ", dumpPackage, false, false)) {
16308                needSep = true;
16309                printedAnything = true;
16310            }
16311        }
16312
16313        for (BroadcastQueue q : mBroadcastQueues) {
16314            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16315            printedAnything |= needSep;
16316        }
16317
16318        needSep = true;
16319
16320        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16321            for (int user=0; user<mStickyBroadcasts.size(); user++) {
16322                if (needSep) {
16323                    pw.println();
16324                }
16325                needSep = true;
16326                printedAnything = true;
16327                pw.print("  Sticky broadcasts for user ");
16328                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16329                StringBuilder sb = new StringBuilder(128);
16330                for (Map.Entry<String, ArrayList<Intent>> ent
16331                        : mStickyBroadcasts.valueAt(user).entrySet()) {
16332                    pw.print("  * Sticky action "); pw.print(ent.getKey());
16333                    if (dumpAll) {
16334                        pw.println(":");
16335                        ArrayList<Intent> intents = ent.getValue();
16336                        final int N = intents.size();
16337                        for (int i=0; i<N; i++) {
16338                            sb.setLength(0);
16339                            sb.append("    Intent: ");
16340                            intents.get(i).toShortString(sb, false, true, false, false);
16341                            pw.println(sb.toString());
16342                            Bundle bundle = intents.get(i).getExtras();
16343                            if (bundle != null) {
16344                                pw.print("      ");
16345                                pw.println(bundle.toString());
16346                            }
16347                        }
16348                    } else {
16349                        pw.println("");
16350                    }
16351                }
16352            }
16353        }
16354
16355        if (!onlyHistory && dumpAll) {
16356            pw.println();
16357            for (BroadcastQueue queue : mBroadcastQueues) {
16358                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16359                        + queue.mBroadcastsScheduled);
16360            }
16361            pw.println("  mHandler:");
16362            mHandler.dump(new PrintWriterPrinter(pw), "    ");
16363            needSep = true;
16364            printedAnything = true;
16365        }
16366
16367        if (!printedAnything) {
16368            pw.println("  (nothing)");
16369        }
16370    }
16371
16372    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16373            int opti, boolean dumpAll, String dumpPackage) {
16374        if (mCurBroadcastStats == null) {
16375            return;
16376        }
16377
16378        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16379        final long now = SystemClock.elapsedRealtime();
16380        if (mLastBroadcastStats != null) {
16381            pw.print("  Last stats (from ");
16382            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16383            pw.print(" to ");
16384            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16385            pw.print(", ");
16386            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16387                    - mLastBroadcastStats.mStartUptime, pw);
16388            pw.println(" uptime):");
16389            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16390                pw.println("    (nothing)");
16391            }
16392            pw.println();
16393        }
16394        pw.print("  Current stats (from ");
16395        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16396        pw.print(" to now, ");
16397        TimeUtils.formatDuration(SystemClock.uptimeMillis()
16398                - mCurBroadcastStats.mStartUptime, pw);
16399        pw.println(" uptime):");
16400        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16401            pw.println("    (nothing)");
16402        }
16403    }
16404
16405    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16406            int opti, boolean fullCheckin, String dumpPackage) {
16407        if (mCurBroadcastStats == null) {
16408            return;
16409        }
16410
16411        if (mLastBroadcastStats != null) {
16412            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16413            if (fullCheckin) {
16414                mLastBroadcastStats = null;
16415                return;
16416            }
16417        }
16418        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16419        if (fullCheckin) {
16420            mCurBroadcastStats = null;
16421        }
16422    }
16423
16424    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16425            int opti, boolean dumpAll, String dumpPackage) {
16426        boolean needSep;
16427        boolean printedAnything = false;
16428
16429        ItemMatcher matcher = new ItemMatcher();
16430        matcher.build(args, opti);
16431
16432        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16433
16434        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16435        printedAnything |= needSep;
16436
16437        if (mLaunchingProviders.size() > 0) {
16438            boolean printed = false;
16439            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16440                ContentProviderRecord r = mLaunchingProviders.get(i);
16441                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16442                    continue;
16443                }
16444                if (!printed) {
16445                    if (needSep) pw.println();
16446                    needSep = true;
16447                    pw.println("  Launching content providers:");
16448                    printed = true;
16449                    printedAnything = true;
16450                }
16451                pw.print("  Launching #"); pw.print(i); pw.print(": ");
16452                        pw.println(r);
16453            }
16454        }
16455
16456        if (!printedAnything) {
16457            pw.println("  (nothing)");
16458        }
16459    }
16460
16461    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16462            int opti, boolean dumpAll, String dumpPackage) {
16463        boolean needSep = false;
16464        boolean printedAnything = false;
16465
16466        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16467
16468        if (mGrantedUriPermissions.size() > 0) {
16469            boolean printed = false;
16470            int dumpUid = -2;
16471            if (dumpPackage != null) {
16472                try {
16473                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16474                            MATCH_ANY_USER, 0);
16475                } catch (NameNotFoundException e) {
16476                    dumpUid = -1;
16477                }
16478            }
16479            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16480                int uid = mGrantedUriPermissions.keyAt(i);
16481                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16482                    continue;
16483                }
16484                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16485                if (!printed) {
16486                    if (needSep) pw.println();
16487                    needSep = true;
16488                    pw.println("  Granted Uri Permissions:");
16489                    printed = true;
16490                    printedAnything = true;
16491                }
16492                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16493                for (UriPermission perm : perms.values()) {
16494                    pw.print("    "); pw.println(perm);
16495                    if (dumpAll) {
16496                        perm.dump(pw, "      ");
16497                    }
16498                }
16499            }
16500        }
16501
16502        if (!printedAnything) {
16503            pw.println("  (nothing)");
16504        }
16505    }
16506
16507    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16508            int opti, boolean dumpAll, String dumpPackage) {
16509        boolean printed = false;
16510
16511        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16512
16513        if (mIntentSenderRecords.size() > 0) {
16514            // Organize these by package name, so they are easier to read.
16515            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16516            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16517            final Iterator<WeakReference<PendingIntentRecord>> it
16518                    = mIntentSenderRecords.values().iterator();
16519            while (it.hasNext()) {
16520                WeakReference<PendingIntentRecord> ref = it.next();
16521                PendingIntentRecord rec = ref != null ? ref.get() : null;
16522                if (rec == null) {
16523                    weakRefs.add(ref);
16524                    continue;
16525                }
16526                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16527                    continue;
16528                }
16529                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16530                if (list == null) {
16531                    list = new ArrayList<>();
16532                    byPackage.put(rec.key.packageName, list);
16533                }
16534                list.add(rec);
16535            }
16536            for (int i = 0; i < byPackage.size(); i++) {
16537                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16538                printed = true;
16539                pw.print("  * "); pw.print(byPackage.keyAt(i));
16540                pw.print(": "); pw.print(intents.size()); pw.println(" items");
16541                for (int j = 0; j < intents.size(); j++) {
16542                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16543                    if (dumpAll) {
16544                        intents.get(j).dump(pw, "      ");
16545                    }
16546                }
16547            }
16548            if (weakRefs.size() > 0) {
16549                printed = true;
16550                pw.println("  * WEAK REFS:");
16551                for (int i = 0; i < weakRefs.size(); i++) {
16552                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16553                }
16554            }
16555        }
16556
16557        if (!printed) {
16558            pw.println("  (nothing)");
16559        }
16560    }
16561
16562    private static final int dumpProcessList(PrintWriter pw,
16563            ActivityManagerService service, List list,
16564            String prefix, String normalLabel, String persistentLabel,
16565            String dumpPackage) {
16566        int numPers = 0;
16567        final int N = list.size()-1;
16568        for (int i=N; i>=0; i--) {
16569            ProcessRecord r = (ProcessRecord)list.get(i);
16570            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16571                continue;
16572            }
16573            pw.println(String.format("%s%s #%2d: %s",
16574                    prefix, (r.persistent ? persistentLabel : normalLabel),
16575                    i, r.toString()));
16576            if (r.persistent) {
16577                numPers++;
16578            }
16579        }
16580        return numPers;
16581    }
16582
16583    private static final boolean dumpProcessOomList(PrintWriter pw,
16584            ActivityManagerService service, List<ProcessRecord> origList,
16585            String prefix, String normalLabel, String persistentLabel,
16586            boolean inclDetails, String dumpPackage) {
16587
16588        ArrayList<Pair<ProcessRecord, Integer>> list
16589                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16590        for (int i=0; i<origList.size(); i++) {
16591            ProcessRecord r = origList.get(i);
16592            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16593                continue;
16594            }
16595            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16596        }
16597
16598        if (list.size() <= 0) {
16599            return false;
16600        }
16601
16602        Comparator<Pair<ProcessRecord, Integer>> comparator
16603                = new Comparator<Pair<ProcessRecord, Integer>>() {
16604            @Override
16605            public int compare(Pair<ProcessRecord, Integer> object1,
16606                    Pair<ProcessRecord, Integer> object2) {
16607                if (object1.first.setAdj != object2.first.setAdj) {
16608                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16609                }
16610                if (object1.first.setProcState != object2.first.setProcState) {
16611                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16612                }
16613                if (object1.second.intValue() != object2.second.intValue()) {
16614                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16615                }
16616                return 0;
16617            }
16618        };
16619
16620        Collections.sort(list, comparator);
16621
16622        final long curUptime = SystemClock.uptimeMillis();
16623        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16624
16625        for (int i=list.size()-1; i>=0; i--) {
16626            ProcessRecord r = list.get(i).first;
16627            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16628            char schedGroup;
16629            switch (r.setSchedGroup) {
16630                case ProcessList.SCHED_GROUP_BACKGROUND:
16631                    schedGroup = 'B';
16632                    break;
16633                case ProcessList.SCHED_GROUP_DEFAULT:
16634                    schedGroup = 'F';
16635                    break;
16636                case ProcessList.SCHED_GROUP_TOP_APP:
16637                    schedGroup = 'T';
16638                    break;
16639                default:
16640                    schedGroup = '?';
16641                    break;
16642            }
16643            char foreground;
16644            if (r.foregroundActivities) {
16645                foreground = 'A';
16646            } else if (r.foregroundServices) {
16647                foreground = 'S';
16648            } else {
16649                foreground = ' ';
16650            }
16651            String procState = ProcessList.makeProcStateString(r.curProcState);
16652            pw.print(prefix);
16653            pw.print(r.persistent ? persistentLabel : normalLabel);
16654            pw.print(" #");
16655            int num = (origList.size()-1)-list.get(i).second;
16656            if (num < 10) pw.print(' ');
16657            pw.print(num);
16658            pw.print(": ");
16659            pw.print(oomAdj);
16660            pw.print(' ');
16661            pw.print(schedGroup);
16662            pw.print('/');
16663            pw.print(foreground);
16664            pw.print('/');
16665            pw.print(procState);
16666            pw.print(" trm:");
16667            if (r.trimMemoryLevel < 10) pw.print(' ');
16668            pw.print(r.trimMemoryLevel);
16669            pw.print(' ');
16670            pw.print(r.toShortString());
16671            pw.print(" (");
16672            pw.print(r.adjType);
16673            pw.println(')');
16674            if (r.adjSource != null || r.adjTarget != null) {
16675                pw.print(prefix);
16676                pw.print("    ");
16677                if (r.adjTarget instanceof ComponentName) {
16678                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16679                } else if (r.adjTarget != null) {
16680                    pw.print(r.adjTarget.toString());
16681                } else {
16682                    pw.print("{null}");
16683                }
16684                pw.print("<=");
16685                if (r.adjSource instanceof ProcessRecord) {
16686                    pw.print("Proc{");
16687                    pw.print(((ProcessRecord)r.adjSource).toShortString());
16688                    pw.println("}");
16689                } else if (r.adjSource != null) {
16690                    pw.println(r.adjSource.toString());
16691                } else {
16692                    pw.println("{null}");
16693                }
16694            }
16695            if (inclDetails) {
16696                pw.print(prefix);
16697                pw.print("    ");
16698                pw.print("oom: max="); pw.print(r.maxAdj);
16699                pw.print(" curRaw="); pw.print(r.curRawAdj);
16700                pw.print(" setRaw="); pw.print(r.setRawAdj);
16701                pw.print(" cur="); pw.print(r.curAdj);
16702                pw.print(" set="); pw.println(r.setAdj);
16703                pw.print(prefix);
16704                pw.print("    ");
16705                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16706                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16707                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16708                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16709                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16710                pw.println();
16711                pw.print(prefix);
16712                pw.print("    ");
16713                pw.print("cached="); pw.print(r.cached);
16714                pw.print(" empty="); pw.print(r.empty);
16715                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16716
16717                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16718                    if (r.lastCpuTime != 0) {
16719                        long timeUsed = r.curCpuTime - r.lastCpuTime;
16720                        pw.print(prefix);
16721                        pw.print("    ");
16722                        pw.print("run cpu over ");
16723                        TimeUtils.formatDuration(uptimeSince, pw);
16724                        pw.print(" used ");
16725                        TimeUtils.formatDuration(timeUsed, pw);
16726                        pw.print(" (");
16727                        pw.print((timeUsed*100)/uptimeSince);
16728                        pw.println("%)");
16729                    }
16730                }
16731            }
16732        }
16733        return true;
16734    }
16735
16736    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16737            String[] args) {
16738        ArrayList<ProcessRecord> procs;
16739        synchronized (this) {
16740            if (args != null && args.length > start
16741                    && args[start].charAt(0) != '-') {
16742                procs = new ArrayList<ProcessRecord>();
16743                int pid = -1;
16744                try {
16745                    pid = Integer.parseInt(args[start]);
16746                } catch (NumberFormatException e) {
16747                }
16748                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16749                    ProcessRecord proc = mLruProcesses.get(i);
16750                    if (proc.pid == pid) {
16751                        procs.add(proc);
16752                    } else if (allPkgs && proc.pkgList != null
16753                            && proc.pkgList.containsKey(args[start])) {
16754                        procs.add(proc);
16755                    } else if (proc.processName.equals(args[start])) {
16756                        procs.add(proc);
16757                    }
16758                }
16759                if (procs.size() <= 0) {
16760                    return null;
16761                }
16762            } else {
16763                procs = new ArrayList<ProcessRecord>(mLruProcesses);
16764            }
16765        }
16766        return procs;
16767    }
16768
16769    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16770            PrintWriter pw, String[] args) {
16771        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16772        if (procs == null) {
16773            pw.println("No process found for: " + args[0]);
16774            return;
16775        }
16776
16777        long uptime = SystemClock.uptimeMillis();
16778        long realtime = SystemClock.elapsedRealtime();
16779        pw.println("Applications Graphics Acceleration Info:");
16780        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16781
16782        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16783            ProcessRecord r = procs.get(i);
16784            if (r.thread != null) {
16785                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16786                pw.flush();
16787                try {
16788                    TransferPipe tp = new TransferPipe();
16789                    try {
16790                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16791                        tp.go(fd);
16792                    } finally {
16793                        tp.kill();
16794                    }
16795                } catch (IOException e) {
16796                    pw.println("Failure while dumping the app: " + r);
16797                    pw.flush();
16798                } catch (RemoteException e) {
16799                    pw.println("Got a RemoteException while dumping the app " + r);
16800                    pw.flush();
16801                }
16802            }
16803        }
16804    }
16805
16806    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16807        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16808        if (procs == null) {
16809            pw.println("No process found for: " + args[0]);
16810            return;
16811        }
16812
16813        pw.println("Applications Database Info:");
16814
16815        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16816            ProcessRecord r = procs.get(i);
16817            if (r.thread != null) {
16818                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16819                pw.flush();
16820                try {
16821                    TransferPipe tp = new TransferPipe();
16822                    try {
16823                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
16824                        tp.go(fd);
16825                    } finally {
16826                        tp.kill();
16827                    }
16828                } catch (IOException e) {
16829                    pw.println("Failure while dumping the app: " + r);
16830                    pw.flush();
16831                } catch (RemoteException e) {
16832                    pw.println("Got a RemoteException while dumping the app " + r);
16833                    pw.flush();
16834                }
16835            }
16836        }
16837    }
16838
16839    final static class MemItem {
16840        final boolean isProc;
16841        final String label;
16842        final String shortLabel;
16843        final long pss;
16844        final long swapPss;
16845        final int id;
16846        final boolean hasActivities;
16847        ArrayList<MemItem> subitems;
16848
16849        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16850                boolean _hasActivities) {
16851            isProc = true;
16852            label = _label;
16853            shortLabel = _shortLabel;
16854            pss = _pss;
16855            swapPss = _swapPss;
16856            id = _id;
16857            hasActivities = _hasActivities;
16858        }
16859
16860        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16861            isProc = false;
16862            label = _label;
16863            shortLabel = _shortLabel;
16864            pss = _pss;
16865            swapPss = _swapPss;
16866            id = _id;
16867            hasActivities = false;
16868        }
16869    }
16870
16871    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16872            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16873        if (sort && !isCompact) {
16874            Collections.sort(items, new Comparator<MemItem>() {
16875                @Override
16876                public int compare(MemItem lhs, MemItem rhs) {
16877                    if (lhs.pss < rhs.pss) {
16878                        return 1;
16879                    } else if (lhs.pss > rhs.pss) {
16880                        return -1;
16881                    }
16882                    return 0;
16883                }
16884            });
16885        }
16886
16887        for (int i=0; i<items.size(); i++) {
16888            MemItem mi = items.get(i);
16889            if (!isCompact) {
16890                if (dumpSwapPss) {
16891                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16892                            mi.label, stringifyKBSize(mi.swapPss));
16893                } else {
16894                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16895                }
16896            } else if (mi.isProc) {
16897                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16898                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16899                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16900                pw.println(mi.hasActivities ? ",a" : ",e");
16901            } else {
16902                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16903                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16904            }
16905            if (mi.subitems != null) {
16906                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16907                        true, isCompact, dumpSwapPss);
16908            }
16909        }
16910    }
16911
16912    // These are in KB.
16913    static final long[] DUMP_MEM_BUCKETS = new long[] {
16914        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16915        120*1024, 160*1024, 200*1024,
16916        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16917        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16918    };
16919
16920    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16921            boolean stackLike) {
16922        int start = label.lastIndexOf('.');
16923        if (start >= 0) start++;
16924        else start = 0;
16925        int end = label.length();
16926        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16927            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16928                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16929                out.append(bucket);
16930                out.append(stackLike ? "MB." : "MB ");
16931                out.append(label, start, end);
16932                return;
16933            }
16934        }
16935        out.append(memKB/1024);
16936        out.append(stackLike ? "MB." : "MB ");
16937        out.append(label, start, end);
16938    }
16939
16940    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16941            ProcessList.NATIVE_ADJ,
16942            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16943            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16944            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16945            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16946            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16947            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16948    };
16949    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16950            "Native",
16951            "System", "Persistent", "Persistent Service", "Foreground",
16952            "Visible", "Perceptible",
16953            "Heavy Weight", "Backup",
16954            "A Services", "Home",
16955            "Previous", "B Services", "Cached"
16956    };
16957    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16958            "native",
16959            "sys", "pers", "persvc", "fore",
16960            "vis", "percept",
16961            "heavy", "backup",
16962            "servicea", "home",
16963            "prev", "serviceb", "cached"
16964    };
16965
16966    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16967            long realtime, boolean isCheckinRequest, boolean isCompact) {
16968        if (isCompact) {
16969            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16970        }
16971        if (isCheckinRequest || isCompact) {
16972            // short checkin version
16973            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16974        } else {
16975            pw.println("Applications Memory Usage (in Kilobytes):");
16976            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16977        }
16978    }
16979
16980    private static final int KSM_SHARED = 0;
16981    private static final int KSM_SHARING = 1;
16982    private static final int KSM_UNSHARED = 2;
16983    private static final int KSM_VOLATILE = 3;
16984
16985    private final long[] getKsmInfo() {
16986        long[] longOut = new long[4];
16987        final int[] SINGLE_LONG_FORMAT = new int[] {
16988            PROC_SPACE_TERM| PROC_OUT_LONG
16989        };
16990        long[] longTmp = new long[1];
16991        readProcFile("/sys/kernel/mm/ksm/pages_shared",
16992                SINGLE_LONG_FORMAT, null, longTmp, null);
16993        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16994        longTmp[0] = 0;
16995        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16996                SINGLE_LONG_FORMAT, null, longTmp, null);
16997        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16998        longTmp[0] = 0;
16999        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17000                SINGLE_LONG_FORMAT, null, longTmp, null);
17001        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17002        longTmp[0] = 0;
17003        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17004                SINGLE_LONG_FORMAT, null, longTmp, null);
17005        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17006        return longOut;
17007    }
17008
17009    private static String stringifySize(long size, int order) {
17010        Locale locale = Locale.US;
17011        switch (order) {
17012            case 1:
17013                return String.format(locale, "%,13d", size);
17014            case 1024:
17015                return String.format(locale, "%,9dK", size / 1024);
17016            case 1024 * 1024:
17017                return String.format(locale, "%,5dM", size / 1024 / 1024);
17018            case 1024 * 1024 * 1024:
17019                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17020            default:
17021                throw new IllegalArgumentException("Invalid size order");
17022        }
17023    }
17024
17025    private static String stringifyKBSize(long size) {
17026        return stringifySize(size * 1024, 1024);
17027    }
17028
17029    // Update this version number in case you change the 'compact' format
17030    private static final int MEMINFO_COMPACT_VERSION = 1;
17031
17032    final void dumpApplicationMemoryUsage(FileDescriptor fd,
17033            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17034        boolean dumpDetails = false;
17035        boolean dumpFullDetails = false;
17036        boolean dumpDalvik = false;
17037        boolean dumpSummaryOnly = false;
17038        boolean dumpUnreachable = false;
17039        boolean oomOnly = false;
17040        boolean isCompact = false;
17041        boolean localOnly = false;
17042        boolean packages = false;
17043        boolean isCheckinRequest = false;
17044        boolean dumpSwapPss = false;
17045
17046        int opti = 0;
17047        while (opti < args.length) {
17048            String opt = args[opti];
17049            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17050                break;
17051            }
17052            opti++;
17053            if ("-a".equals(opt)) {
17054                dumpDetails = true;
17055                dumpFullDetails = true;
17056                dumpDalvik = true;
17057                dumpSwapPss = true;
17058            } else if ("-d".equals(opt)) {
17059                dumpDalvik = true;
17060            } else if ("-c".equals(opt)) {
17061                isCompact = true;
17062            } else if ("-s".equals(opt)) {
17063                dumpDetails = true;
17064                dumpSummaryOnly = true;
17065            } else if ("-S".equals(opt)) {
17066                dumpSwapPss = true;
17067            } else if ("--unreachable".equals(opt)) {
17068                dumpUnreachable = true;
17069            } else if ("--oom".equals(opt)) {
17070                oomOnly = true;
17071            } else if ("--local".equals(opt)) {
17072                localOnly = true;
17073            } else if ("--package".equals(opt)) {
17074                packages = true;
17075            } else if ("--checkin".equals(opt)) {
17076                isCheckinRequest = true;
17077
17078            } else if ("-h".equals(opt)) {
17079                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17080                pw.println("  -a: include all available information for each process.");
17081                pw.println("  -d: include dalvik details.");
17082                pw.println("  -c: dump in a compact machine-parseable representation.");
17083                pw.println("  -s: dump only summary of application memory usage.");
17084                pw.println("  -S: dump also SwapPss.");
17085                pw.println("  --oom: only show processes organized by oom adj.");
17086                pw.println("  --local: only collect details locally, don't call process.");
17087                pw.println("  --package: interpret process arg as package, dumping all");
17088                pw.println("             processes that have loaded that package.");
17089                pw.println("  --checkin: dump data for a checkin");
17090                pw.println("If [process] is specified it can be the name or ");
17091                pw.println("pid of a specific process to dump.");
17092                return;
17093            } else {
17094                pw.println("Unknown argument: " + opt + "; use -h for help");
17095            }
17096        }
17097
17098        long uptime = SystemClock.uptimeMillis();
17099        long realtime = SystemClock.elapsedRealtime();
17100        final long[] tmpLong = new long[1];
17101
17102        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17103        if (procs == null) {
17104            // No Java processes.  Maybe they want to print a native process.
17105            if (args != null && args.length > opti
17106                    && args[opti].charAt(0) != '-') {
17107                ArrayList<ProcessCpuTracker.Stats> nativeProcs
17108                        = new ArrayList<ProcessCpuTracker.Stats>();
17109                updateCpuStatsNow();
17110                int findPid = -1;
17111                try {
17112                    findPid = Integer.parseInt(args[opti]);
17113                } catch (NumberFormatException e) {
17114                }
17115                synchronized (mProcessCpuTracker) {
17116                    final int N = mProcessCpuTracker.countStats();
17117                    for (int i=0; i<N; i++) {
17118                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17119                        if (st.pid == findPid || (st.baseName != null
17120                                && st.baseName.equals(args[opti]))) {
17121                            nativeProcs.add(st);
17122                        }
17123                    }
17124                }
17125                if (nativeProcs.size() > 0) {
17126                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17127                            isCompact);
17128                    Debug.MemoryInfo mi = null;
17129                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17130                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17131                        final int pid = r.pid;
17132                        if (!isCheckinRequest && dumpDetails) {
17133                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17134                        }
17135                        if (mi == null) {
17136                            mi = new Debug.MemoryInfo();
17137                        }
17138                        if (dumpDetails || (!brief && !oomOnly)) {
17139                            Debug.getMemoryInfo(pid, mi);
17140                        } else {
17141                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17142                            mi.dalvikPrivateDirty = (int)tmpLong[0];
17143                        }
17144                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17145                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17146                        if (isCheckinRequest) {
17147                            pw.println();
17148                        }
17149                    }
17150                    return;
17151                }
17152            }
17153            pw.println("No process found for: " + args[opti]);
17154            return;
17155        }
17156
17157        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17158            dumpDetails = true;
17159        }
17160
17161        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17162
17163        String[] innerArgs = new String[args.length-opti];
17164        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17165
17166        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17167        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17168        long nativePss = 0;
17169        long nativeSwapPss = 0;
17170        long dalvikPss = 0;
17171        long dalvikSwapPss = 0;
17172        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17173                EmptyArray.LONG;
17174        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17175                EmptyArray.LONG;
17176        long otherPss = 0;
17177        long otherSwapPss = 0;
17178        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17179        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17180
17181        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17182        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17183        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17184                new ArrayList[DUMP_MEM_OOM_LABEL.length];
17185
17186        long totalPss = 0;
17187        long totalSwapPss = 0;
17188        long cachedPss = 0;
17189        long cachedSwapPss = 0;
17190        boolean hasSwapPss = false;
17191
17192        Debug.MemoryInfo mi = null;
17193        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17194            final ProcessRecord r = procs.get(i);
17195            final IApplicationThread thread;
17196            final int pid;
17197            final int oomAdj;
17198            final boolean hasActivities;
17199            synchronized (this) {
17200                thread = r.thread;
17201                pid = r.pid;
17202                oomAdj = r.getSetAdjWithServices();
17203                hasActivities = r.activities.size() > 0;
17204            }
17205            if (thread != null) {
17206                if (!isCheckinRequest && dumpDetails) {
17207                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17208                }
17209                if (mi == null) {
17210                    mi = new Debug.MemoryInfo();
17211                }
17212                if (dumpDetails || (!brief && !oomOnly)) {
17213                    Debug.getMemoryInfo(pid, mi);
17214                    hasSwapPss = mi.hasSwappedOutPss;
17215                } else {
17216                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17217                    mi.dalvikPrivateDirty = (int)tmpLong[0];
17218                }
17219                if (dumpDetails) {
17220                    if (localOnly) {
17221                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17222                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17223                        if (isCheckinRequest) {
17224                            pw.println();
17225                        }
17226                    } else {
17227                        pw.flush();
17228                        try {
17229                            TransferPipe tp = new TransferPipe();
17230                            try {
17231                                thread.dumpMemInfo(tp.getWriteFd(),
17232                                        mi, isCheckinRequest, dumpFullDetails,
17233                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17234                                tp.go(fd);
17235                            } finally {
17236                                tp.kill();
17237                            }
17238                        } catch (IOException e) {
17239                            if (!isCheckinRequest) {
17240                                pw.println("Got IoException! " + e);
17241                                pw.flush();
17242                            }
17243                        } catch (RemoteException e) {
17244                            if (!isCheckinRequest) {
17245                                pw.println("Got RemoteException! " + e);
17246                                pw.flush();
17247                            }
17248                        }
17249                    }
17250                }
17251
17252                final long myTotalPss = mi.getTotalPss();
17253                final long myTotalUss = mi.getTotalUss();
17254                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17255
17256                synchronized (this) {
17257                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17258                        // Record this for posterity if the process has been stable.
17259                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17260                    }
17261                }
17262
17263                if (!isCheckinRequest && mi != null) {
17264                    totalPss += myTotalPss;
17265                    totalSwapPss += myTotalSwapPss;
17266                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17267                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17268                            myTotalSwapPss, pid, hasActivities);
17269                    procMems.add(pssItem);
17270                    procMemsMap.put(pid, pssItem);
17271
17272                    nativePss += mi.nativePss;
17273                    nativeSwapPss += mi.nativeSwappedOutPss;
17274                    dalvikPss += mi.dalvikPss;
17275                    dalvikSwapPss += mi.dalvikSwappedOutPss;
17276                    for (int j=0; j<dalvikSubitemPss.length; j++) {
17277                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17278                        dalvikSubitemSwapPss[j] +=
17279                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17280                    }
17281                    otherPss += mi.otherPss;
17282                    otherSwapPss += mi.otherSwappedOutPss;
17283                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17284                        long mem = mi.getOtherPss(j);
17285                        miscPss[j] += mem;
17286                        otherPss -= mem;
17287                        mem = mi.getOtherSwappedOutPss(j);
17288                        miscSwapPss[j] += mem;
17289                        otherSwapPss -= mem;
17290                    }
17291
17292                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17293                        cachedPss += myTotalPss;
17294                        cachedSwapPss += myTotalSwapPss;
17295                    }
17296
17297                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17298                        if (oomIndex == (oomPss.length - 1)
17299                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17300                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17301                            oomPss[oomIndex] += myTotalPss;
17302                            oomSwapPss[oomIndex] += myTotalSwapPss;
17303                            if (oomProcs[oomIndex] == null) {
17304                                oomProcs[oomIndex] = new ArrayList<MemItem>();
17305                            }
17306                            oomProcs[oomIndex].add(pssItem);
17307                            break;
17308                        }
17309                    }
17310                }
17311            }
17312        }
17313
17314        long nativeProcTotalPss = 0;
17315
17316        if (!isCheckinRequest && procs.size() > 1 && !packages) {
17317            // If we are showing aggregations, also look for native processes to
17318            // include so that our aggregations are more accurate.
17319            updateCpuStatsNow();
17320            mi = null;
17321            synchronized (mProcessCpuTracker) {
17322                final int N = mProcessCpuTracker.countStats();
17323                for (int i=0; i<N; i++) {
17324                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17325                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17326                        if (mi == null) {
17327                            mi = new Debug.MemoryInfo();
17328                        }
17329                        if (!brief && !oomOnly) {
17330                            Debug.getMemoryInfo(st.pid, mi);
17331                        } else {
17332                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17333                            mi.nativePrivateDirty = (int)tmpLong[0];
17334                        }
17335
17336                        final long myTotalPss = mi.getTotalPss();
17337                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17338                        totalPss += myTotalPss;
17339                        nativeProcTotalPss += myTotalPss;
17340
17341                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17342                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17343                        procMems.add(pssItem);
17344
17345                        nativePss += mi.nativePss;
17346                        nativeSwapPss += mi.nativeSwappedOutPss;
17347                        dalvikPss += mi.dalvikPss;
17348                        dalvikSwapPss += mi.dalvikSwappedOutPss;
17349                        for (int j=0; j<dalvikSubitemPss.length; j++) {
17350                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17351                            dalvikSubitemSwapPss[j] +=
17352                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17353                        }
17354                        otherPss += mi.otherPss;
17355                        otherSwapPss += mi.otherSwappedOutPss;
17356                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17357                            long mem = mi.getOtherPss(j);
17358                            miscPss[j] += mem;
17359                            otherPss -= mem;
17360                            mem = mi.getOtherSwappedOutPss(j);
17361                            miscSwapPss[j] += mem;
17362                            otherSwapPss -= mem;
17363                        }
17364                        oomPss[0] += myTotalPss;
17365                        oomSwapPss[0] += myTotalSwapPss;
17366                        if (oomProcs[0] == null) {
17367                            oomProcs[0] = new ArrayList<MemItem>();
17368                        }
17369                        oomProcs[0].add(pssItem);
17370                    }
17371                }
17372            }
17373
17374            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17375
17376            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17377            final int dalvikId = -2;
17378            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17379            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17380            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17381                String label = Debug.MemoryInfo.getOtherLabel(j);
17382                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17383            }
17384            if (dalvikSubitemPss.length > 0) {
17385                // Add dalvik subitems.
17386                for (MemItem memItem : catMems) {
17387                    int memItemStart = 0, memItemEnd = 0;
17388                    if (memItem.id == dalvikId) {
17389                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17390                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17391                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17392                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17393                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17394                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17395                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17396                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17397                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17398                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17399                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17400                    } else {
17401                        continue;  // No subitems, continue.
17402                    }
17403                    memItem.subitems = new ArrayList<MemItem>();
17404                    for (int j=memItemStart; j<=memItemEnd; j++) {
17405                        final String name = Debug.MemoryInfo.getOtherLabel(
17406                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
17407                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17408                                dalvikSubitemSwapPss[j], j));
17409                    }
17410                }
17411            }
17412
17413            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17414            for (int j=0; j<oomPss.length; j++) {
17415                if (oomPss[j] != 0) {
17416                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17417                            : DUMP_MEM_OOM_LABEL[j];
17418                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17419                            DUMP_MEM_OOM_ADJ[j]);
17420                    item.subitems = oomProcs[j];
17421                    oomMems.add(item);
17422                }
17423            }
17424
17425            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17426            if (!brief && !oomOnly && !isCompact) {
17427                pw.println();
17428                pw.println("Total PSS by process:");
17429                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17430                pw.println();
17431            }
17432            if (!isCompact) {
17433                pw.println("Total PSS by OOM adjustment:");
17434            }
17435            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17436            if (!brief && !oomOnly) {
17437                PrintWriter out = categoryPw != null ? categoryPw : pw;
17438                if (!isCompact) {
17439                    out.println();
17440                    out.println("Total PSS by category:");
17441                }
17442                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17443            }
17444            if (!isCompact) {
17445                pw.println();
17446            }
17447            MemInfoReader memInfo = new MemInfoReader();
17448            memInfo.readMemInfo();
17449            if (nativeProcTotalPss > 0) {
17450                synchronized (this) {
17451                    final long cachedKb = memInfo.getCachedSizeKb();
17452                    final long freeKb = memInfo.getFreeSizeKb();
17453                    final long zramKb = memInfo.getZramTotalSizeKb();
17454                    final long kernelKb = memInfo.getKernelUsedSizeKb();
17455                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17456                            kernelKb*1024, nativeProcTotalPss*1024);
17457                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17458                            nativeProcTotalPss);
17459                }
17460            }
17461            if (!brief) {
17462                if (!isCompact) {
17463                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17464                    pw.print(" (status ");
17465                    switch (mLastMemoryLevel) {
17466                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17467                            pw.println("normal)");
17468                            break;
17469                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17470                            pw.println("moderate)");
17471                            break;
17472                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
17473                            pw.println("low)");
17474                            break;
17475                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17476                            pw.println("critical)");
17477                            break;
17478                        default:
17479                            pw.print(mLastMemoryLevel);
17480                            pw.println(")");
17481                            break;
17482                    }
17483                    pw.print(" Free RAM: ");
17484                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17485                            + memInfo.getFreeSizeKb()));
17486                    pw.print(" (");
17487                    pw.print(stringifyKBSize(cachedPss));
17488                    pw.print(" cached pss + ");
17489                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17490                    pw.print(" cached kernel + ");
17491                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17492                    pw.println(" free)");
17493                } else {
17494                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17495                    pw.print(cachedPss + memInfo.getCachedSizeKb()
17496                            + memInfo.getFreeSizeKb()); pw.print(",");
17497                    pw.println(totalPss - cachedPss);
17498                }
17499            }
17500            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17501                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17502                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17503            if (!isCompact) {
17504                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17505                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17506                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17507                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17508                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17509            } else {
17510                pw.print("lostram,"); pw.println(lostRAM);
17511            }
17512            if (!brief) {
17513                if (memInfo.getZramTotalSizeKb() != 0) {
17514                    if (!isCompact) {
17515                        pw.print("     ZRAM: ");
17516                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17517                                pw.print(" physical used for ");
17518                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17519                                        - memInfo.getSwapFreeSizeKb()));
17520                                pw.print(" in swap (");
17521                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17522                                pw.println(" total swap)");
17523                    } else {
17524                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17525                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17526                                pw.println(memInfo.getSwapFreeSizeKb());
17527                    }
17528                }
17529                final long[] ksm = getKsmInfo();
17530                if (!isCompact) {
17531                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17532                            || ksm[KSM_VOLATILE] != 0) {
17533                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17534                                pw.print(" saved from shared ");
17535                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17536                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17537                                pw.print(" unshared; ");
17538                                pw.print(stringifyKBSize(
17539                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
17540                    }
17541                    pw.print("   Tuning: ");
17542                    pw.print(ActivityManager.staticGetMemoryClass());
17543                    pw.print(" (large ");
17544                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17545                    pw.print("), oom ");
17546                    pw.print(stringifySize(
17547                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17548                    pw.print(", restore limit ");
17549                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17550                    if (ActivityManager.isLowRamDeviceStatic()) {
17551                        pw.print(" (low-ram)");
17552                    }
17553                    if (ActivityManager.isHighEndGfx()) {
17554                        pw.print(" (high-end-gfx)");
17555                    }
17556                    pw.println();
17557                } else {
17558                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17559                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17560                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17561                    pw.print("tuning,");
17562                    pw.print(ActivityManager.staticGetMemoryClass());
17563                    pw.print(',');
17564                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17565                    pw.print(',');
17566                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17567                    if (ActivityManager.isLowRamDeviceStatic()) {
17568                        pw.print(",low-ram");
17569                    }
17570                    if (ActivityManager.isHighEndGfx()) {
17571                        pw.print(",high-end-gfx");
17572                    }
17573                    pw.println();
17574                }
17575            }
17576        }
17577    }
17578
17579    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17580            long memtrack, String name) {
17581        sb.append("  ");
17582        sb.append(ProcessList.makeOomAdjString(oomAdj));
17583        sb.append(' ');
17584        sb.append(ProcessList.makeProcStateString(procState));
17585        sb.append(' ');
17586        ProcessList.appendRamKb(sb, pss);
17587        sb.append(": ");
17588        sb.append(name);
17589        if (memtrack > 0) {
17590            sb.append(" (");
17591            sb.append(stringifyKBSize(memtrack));
17592            sb.append(" memtrack)");
17593        }
17594    }
17595
17596    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17597        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17598        sb.append(" (pid ");
17599        sb.append(mi.pid);
17600        sb.append(") ");
17601        sb.append(mi.adjType);
17602        sb.append('\n');
17603        if (mi.adjReason != null) {
17604            sb.append("                      ");
17605            sb.append(mi.adjReason);
17606            sb.append('\n');
17607        }
17608    }
17609
17610    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17611        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17612        for (int i=0, N=memInfos.size(); i<N; i++) {
17613            ProcessMemInfo mi = memInfos.get(i);
17614            infoMap.put(mi.pid, mi);
17615        }
17616        updateCpuStatsNow();
17617        long[] memtrackTmp = new long[1];
17618        final List<ProcessCpuTracker.Stats> stats;
17619        // Get a list of Stats that have vsize > 0
17620        synchronized (mProcessCpuTracker) {
17621            stats = mProcessCpuTracker.getStats((st) -> {
17622                return st.vsize > 0;
17623            });
17624        }
17625        final int statsCount = stats.size();
17626        for (int i = 0; i < statsCount; i++) {
17627            ProcessCpuTracker.Stats st = stats.get(i);
17628            long pss = Debug.getPss(st.pid, null, memtrackTmp);
17629            if (pss > 0) {
17630                if (infoMap.indexOfKey(st.pid) < 0) {
17631                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17632                            ProcessList.NATIVE_ADJ, -1, "native", null);
17633                    mi.pss = pss;
17634                    mi.memtrack = memtrackTmp[0];
17635                    memInfos.add(mi);
17636                }
17637            }
17638        }
17639
17640        long totalPss = 0;
17641        long totalMemtrack = 0;
17642        for (int i=0, N=memInfos.size(); i<N; i++) {
17643            ProcessMemInfo mi = memInfos.get(i);
17644            if (mi.pss == 0) {
17645                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17646                mi.memtrack = memtrackTmp[0];
17647            }
17648            totalPss += mi.pss;
17649            totalMemtrack += mi.memtrack;
17650        }
17651        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17652            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17653                if (lhs.oomAdj != rhs.oomAdj) {
17654                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17655                }
17656                if (lhs.pss != rhs.pss) {
17657                    return lhs.pss < rhs.pss ? 1 : -1;
17658                }
17659                return 0;
17660            }
17661        });
17662
17663        StringBuilder tag = new StringBuilder(128);
17664        StringBuilder stack = new StringBuilder(128);
17665        tag.append("Low on memory -- ");
17666        appendMemBucket(tag, totalPss, "total", false);
17667        appendMemBucket(stack, totalPss, "total", true);
17668
17669        StringBuilder fullNativeBuilder = new StringBuilder(1024);
17670        StringBuilder shortNativeBuilder = new StringBuilder(1024);
17671        StringBuilder fullJavaBuilder = new StringBuilder(1024);
17672
17673        boolean firstLine = true;
17674        int lastOomAdj = Integer.MIN_VALUE;
17675        long extraNativeRam = 0;
17676        long extraNativeMemtrack = 0;
17677        long cachedPss = 0;
17678        for (int i=0, N=memInfos.size(); i<N; i++) {
17679            ProcessMemInfo mi = memInfos.get(i);
17680
17681            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17682                cachedPss += mi.pss;
17683            }
17684
17685            if (mi.oomAdj != ProcessList.NATIVE_ADJ
17686                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
17687                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
17688                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17689                if (lastOomAdj != mi.oomAdj) {
17690                    lastOomAdj = mi.oomAdj;
17691                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17692                        tag.append(" / ");
17693                    }
17694                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17695                        if (firstLine) {
17696                            stack.append(":");
17697                            firstLine = false;
17698                        }
17699                        stack.append("\n\t at ");
17700                    } else {
17701                        stack.append("$");
17702                    }
17703                } else {
17704                    tag.append(" ");
17705                    stack.append("$");
17706                }
17707                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17708                    appendMemBucket(tag, mi.pss, mi.name, false);
17709                }
17710                appendMemBucket(stack, mi.pss, mi.name, true);
17711                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17712                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17713                    stack.append("(");
17714                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17715                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17716                            stack.append(DUMP_MEM_OOM_LABEL[k]);
17717                            stack.append(":");
17718                            stack.append(DUMP_MEM_OOM_ADJ[k]);
17719                        }
17720                    }
17721                    stack.append(")");
17722                }
17723            }
17724
17725            appendMemInfo(fullNativeBuilder, mi);
17726            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17727                // The short form only has native processes that are >= 512K.
17728                if (mi.pss >= 512) {
17729                    appendMemInfo(shortNativeBuilder, mi);
17730                } else {
17731                    extraNativeRam += mi.pss;
17732                    extraNativeMemtrack += mi.memtrack;
17733                }
17734            } else {
17735                // Short form has all other details, but if we have collected RAM
17736                // from smaller native processes let's dump a summary of that.
17737                if (extraNativeRam > 0) {
17738                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17739                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17740                    shortNativeBuilder.append('\n');
17741                    extraNativeRam = 0;
17742                }
17743                appendMemInfo(fullJavaBuilder, mi);
17744            }
17745        }
17746
17747        fullJavaBuilder.append("           ");
17748        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17749        fullJavaBuilder.append(": TOTAL");
17750        if (totalMemtrack > 0) {
17751            fullJavaBuilder.append(" (");
17752            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17753            fullJavaBuilder.append(" memtrack)");
17754        } else {
17755        }
17756        fullJavaBuilder.append("\n");
17757
17758        MemInfoReader memInfo = new MemInfoReader();
17759        memInfo.readMemInfo();
17760        final long[] infos = memInfo.getRawInfo();
17761
17762        StringBuilder memInfoBuilder = new StringBuilder(1024);
17763        Debug.getMemInfo(infos);
17764        memInfoBuilder.append("  MemInfo: ");
17765        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17766        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17767        memInfoBuilder.append(stringifyKBSize(
17768                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17769        memInfoBuilder.append(stringifyKBSize(
17770                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17771        memInfoBuilder.append(stringifyKBSize(
17772                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17773        memInfoBuilder.append("           ");
17774        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17775        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17776        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17777        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17778        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17779            memInfoBuilder.append("  ZRAM: ");
17780            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17781            memInfoBuilder.append(" RAM, ");
17782            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17783            memInfoBuilder.append(" swap total, ");
17784            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17785            memInfoBuilder.append(" swap free\n");
17786        }
17787        final long[] ksm = getKsmInfo();
17788        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17789                || ksm[KSM_VOLATILE] != 0) {
17790            memInfoBuilder.append("  KSM: ");
17791            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17792            memInfoBuilder.append(" saved from shared ");
17793            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17794            memInfoBuilder.append("\n       ");
17795            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17796            memInfoBuilder.append(" unshared; ");
17797            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17798            memInfoBuilder.append(" volatile\n");
17799        }
17800        memInfoBuilder.append("  Free RAM: ");
17801        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17802                + memInfo.getFreeSizeKb()));
17803        memInfoBuilder.append("\n");
17804        memInfoBuilder.append("  Used RAM: ");
17805        memInfoBuilder.append(stringifyKBSize(
17806                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17807        memInfoBuilder.append("\n");
17808        memInfoBuilder.append("  Lost RAM: ");
17809        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17810                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17811                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17812        memInfoBuilder.append("\n");
17813        Slog.i(TAG, "Low on memory:");
17814        Slog.i(TAG, shortNativeBuilder.toString());
17815        Slog.i(TAG, fullJavaBuilder.toString());
17816        Slog.i(TAG, memInfoBuilder.toString());
17817
17818        StringBuilder dropBuilder = new StringBuilder(1024);
17819        /*
17820        StringWriter oomSw = new StringWriter();
17821        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17822        StringWriter catSw = new StringWriter();
17823        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17824        String[] emptyArgs = new String[] { };
17825        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17826        oomPw.flush();
17827        String oomString = oomSw.toString();
17828        */
17829        dropBuilder.append("Low on memory:");
17830        dropBuilder.append(stack);
17831        dropBuilder.append('\n');
17832        dropBuilder.append(fullNativeBuilder);
17833        dropBuilder.append(fullJavaBuilder);
17834        dropBuilder.append('\n');
17835        dropBuilder.append(memInfoBuilder);
17836        dropBuilder.append('\n');
17837        /*
17838        dropBuilder.append(oomString);
17839        dropBuilder.append('\n');
17840        */
17841        StringWriter catSw = new StringWriter();
17842        synchronized (ActivityManagerService.this) {
17843            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17844            String[] emptyArgs = new String[] { };
17845            catPw.println();
17846            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17847            catPw.println();
17848            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17849                    false, null).dumpLocked();
17850            catPw.println();
17851            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17852            catPw.flush();
17853        }
17854        dropBuilder.append(catSw.toString());
17855        addErrorToDropBox("lowmem", null, "system_server", null,
17856                null, tag.toString(), dropBuilder.toString(), null, null);
17857        //Slog.i(TAG, "Sent to dropbox:");
17858        //Slog.i(TAG, dropBuilder.toString());
17859        synchronized (ActivityManagerService.this) {
17860            long now = SystemClock.uptimeMillis();
17861            if (mLastMemUsageReportTime < now) {
17862                mLastMemUsageReportTime = now;
17863            }
17864        }
17865    }
17866
17867    /**
17868     * Searches array of arguments for the specified string
17869     * @param args array of argument strings
17870     * @param value value to search for
17871     * @return true if the value is contained in the array
17872     */
17873    private static boolean scanArgs(String[] args, String value) {
17874        if (args != null) {
17875            for (String arg : args) {
17876                if (value.equals(arg)) {
17877                    return true;
17878                }
17879            }
17880        }
17881        return false;
17882    }
17883
17884    private final boolean removeDyingProviderLocked(ProcessRecord proc,
17885            ContentProviderRecord cpr, boolean always) {
17886        final boolean inLaunching = mLaunchingProviders.contains(cpr);
17887
17888        if (!inLaunching || always) {
17889            synchronized (cpr) {
17890                cpr.launchingApp = null;
17891                cpr.notifyAll();
17892            }
17893            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17894            String names[] = cpr.info.authority.split(";");
17895            for (int j = 0; j < names.length; j++) {
17896                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17897            }
17898        }
17899
17900        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17901            ContentProviderConnection conn = cpr.connections.get(i);
17902            if (conn.waiting) {
17903                // If this connection is waiting for the provider, then we don't
17904                // need to mess with its process unless we are always removing
17905                // or for some reason the provider is not currently launching.
17906                if (inLaunching && !always) {
17907                    continue;
17908                }
17909            }
17910            ProcessRecord capp = conn.client;
17911            conn.dead = true;
17912            if (conn.stableCount > 0) {
17913                if (!capp.persistent && capp.thread != null
17914                        && capp.pid != 0
17915                        && capp.pid != MY_PID) {
17916                    capp.kill("depends on provider "
17917                            + cpr.name.flattenToShortString()
17918                            + " in dying proc " + (proc != null ? proc.processName : "??")
17919                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17920                }
17921            } else if (capp.thread != null && conn.provider.provider != null) {
17922                try {
17923                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17924                } catch (RemoteException e) {
17925                }
17926                // In the protocol here, we don't expect the client to correctly
17927                // clean up this connection, we'll just remove it.
17928                cpr.connections.remove(i);
17929                if (conn.client.conProviders.remove(conn)) {
17930                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17931                }
17932            }
17933        }
17934
17935        if (inLaunching && always) {
17936            mLaunchingProviders.remove(cpr);
17937        }
17938        return inLaunching;
17939    }
17940
17941    /**
17942     * Main code for cleaning up a process when it has gone away.  This is
17943     * called both as a result of the process dying, or directly when stopping
17944     * a process when running in single process mode.
17945     *
17946     * @return Returns true if the given process has been restarted, so the
17947     * app that was passed in must remain on the process lists.
17948     */
17949    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17950            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17951        if (index >= 0) {
17952            removeLruProcessLocked(app);
17953            ProcessList.remove(app.pid);
17954        }
17955
17956        mProcessesToGc.remove(app);
17957        mPendingPssProcesses.remove(app);
17958
17959        // Dismiss any open dialogs.
17960        if (app.crashDialog != null && !app.forceCrashReport) {
17961            app.crashDialog.dismiss();
17962            app.crashDialog = null;
17963        }
17964        if (app.anrDialog != null) {
17965            app.anrDialog.dismiss();
17966            app.anrDialog = null;
17967        }
17968        if (app.waitDialog != null) {
17969            app.waitDialog.dismiss();
17970            app.waitDialog = null;
17971        }
17972
17973        app.crashing = false;
17974        app.notResponding = false;
17975
17976        app.resetPackageList(mProcessStats);
17977        app.unlinkDeathRecipient();
17978        app.makeInactive(mProcessStats);
17979        app.waitingToKill = null;
17980        app.forcingToImportant = null;
17981        updateProcessForegroundLocked(app, false, false);
17982        app.foregroundActivities = false;
17983        app.hasShownUi = false;
17984        app.treatLikeActivity = false;
17985        app.hasAboveClient = false;
17986        app.hasClientActivities = false;
17987
17988        mServices.killServicesLocked(app, allowRestart);
17989
17990        boolean restart = false;
17991
17992        // Remove published content providers.
17993        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17994            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17995            final boolean always = app.bad || !allowRestart;
17996            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17997            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17998                // We left the provider in the launching list, need to
17999                // restart it.
18000                restart = true;
18001            }
18002
18003            cpr.provider = null;
18004            cpr.proc = null;
18005        }
18006        app.pubProviders.clear();
18007
18008        // Take care of any launching providers waiting for this process.
18009        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18010            restart = true;
18011        }
18012
18013        // Unregister from connected content providers.
18014        if (!app.conProviders.isEmpty()) {
18015            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18016                ContentProviderConnection conn = app.conProviders.get(i);
18017                conn.provider.connections.remove(conn);
18018                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18019                        conn.provider.name);
18020            }
18021            app.conProviders.clear();
18022        }
18023
18024        // At this point there may be remaining entries in mLaunchingProviders
18025        // where we were the only one waiting, so they are no longer of use.
18026        // Look for these and clean up if found.
18027        // XXX Commented out for now.  Trying to figure out a way to reproduce
18028        // the actual situation to identify what is actually going on.
18029        if (false) {
18030            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18031                ContentProviderRecord cpr = mLaunchingProviders.get(i);
18032                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18033                    synchronized (cpr) {
18034                        cpr.launchingApp = null;
18035                        cpr.notifyAll();
18036                    }
18037                }
18038            }
18039        }
18040
18041        skipCurrentReceiverLocked(app);
18042
18043        // Unregister any receivers.
18044        for (int i = app.receivers.size() - 1; i >= 0; i--) {
18045            removeReceiverLocked(app.receivers.valueAt(i));
18046        }
18047        app.receivers.clear();
18048
18049        // If the app is undergoing backup, tell the backup manager about it
18050        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18051            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18052                    + mBackupTarget.appInfo + " died during backup");
18053            mHandler.post(new Runnable() {
18054                @Override
18055                public void run(){
18056                    try {
18057                        IBackupManager bm = IBackupManager.Stub.asInterface(
18058                                ServiceManager.getService(Context.BACKUP_SERVICE));
18059                        bm.agentDisconnected(app.info.packageName);
18060                    } catch (RemoteException e) {
18061                        // can't happen; backup manager is local
18062                    }
18063                }
18064            });
18065        }
18066
18067        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18068            ProcessChangeItem item = mPendingProcessChanges.get(i);
18069            if (item.pid == app.pid) {
18070                mPendingProcessChanges.remove(i);
18071                mAvailProcessChanges.add(item);
18072            }
18073        }
18074        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18075                null).sendToTarget();
18076
18077        // If the caller is restarting this app, then leave it in its
18078        // current lists and let the caller take care of it.
18079        if (restarting) {
18080            return false;
18081        }
18082
18083        if (!app.persistent || app.isolated) {
18084            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18085                    "Removing non-persistent process during cleanup: " + app);
18086            if (!replacingPid) {
18087                removeProcessNameLocked(app.processName, app.uid, app);
18088            }
18089            if (mHeavyWeightProcess == app) {
18090                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18091                        mHeavyWeightProcess.userId, 0));
18092                mHeavyWeightProcess = null;
18093            }
18094        } else if (!app.removed) {
18095            // This app is persistent, so we need to keep its record around.
18096            // If it is not already on the pending app list, add it there
18097            // and start a new process for it.
18098            if (mPersistentStartingProcesses.indexOf(app) < 0) {
18099                mPersistentStartingProcesses.add(app);
18100                restart = true;
18101            }
18102        }
18103        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18104                TAG_CLEANUP, "Clean-up removing on hold: " + app);
18105        mProcessesOnHold.remove(app);
18106
18107        if (app == mHomeProcess) {
18108            mHomeProcess = null;
18109        }
18110        if (app == mPreviousProcess) {
18111            mPreviousProcess = null;
18112        }
18113
18114        if (restart && !app.isolated) {
18115            // We have components that still need to be running in the
18116            // process, so re-launch it.
18117            if (index < 0) {
18118                ProcessList.remove(app.pid);
18119            }
18120            addProcessNameLocked(app);
18121            startProcessLocked(app, "restart", app.processName);
18122            return true;
18123        } else if (app.pid > 0 && app.pid != MY_PID) {
18124            // Goodbye!
18125            boolean removed;
18126            synchronized (mPidsSelfLocked) {
18127                mPidsSelfLocked.remove(app.pid);
18128                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18129            }
18130            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18131            if (app.isolated) {
18132                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18133            }
18134            app.setPid(0);
18135        }
18136        return false;
18137    }
18138
18139    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18140        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18141            ContentProviderRecord cpr = mLaunchingProviders.get(i);
18142            if (cpr.launchingApp == app) {
18143                return true;
18144            }
18145        }
18146        return false;
18147    }
18148
18149    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18150        // Look through the content providers we are waiting to have launched,
18151        // and if any run in this process then either schedule a restart of
18152        // the process or kill the client waiting for it if this process has
18153        // gone bad.
18154        boolean restart = false;
18155        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18156            ContentProviderRecord cpr = mLaunchingProviders.get(i);
18157            if (cpr.launchingApp == app) {
18158                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18159                    restart = true;
18160                } else {
18161                    removeDyingProviderLocked(app, cpr, true);
18162                }
18163            }
18164        }
18165        return restart;
18166    }
18167
18168    // =========================================================
18169    // SERVICES
18170    // =========================================================
18171
18172    @Override
18173    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
18174        enforceNotIsolatedCaller("getServices");
18175
18176        final int callingUid = Binder.getCallingUid();
18177        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18178            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18179        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18180            callingUid);
18181        synchronized (this) {
18182            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18183                allowed, canInteractAcrossUsers);
18184        }
18185    }
18186
18187    @Override
18188    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18189        enforceNotIsolatedCaller("getRunningServiceControlPanel");
18190        synchronized (this) {
18191            return mServices.getRunningServiceControlPanelLocked(name);
18192        }
18193    }
18194
18195    @Override
18196    public ComponentName startService(IApplicationThread caller, Intent service,
18197            String resolvedType, boolean requireForeground, String callingPackage, int userId)
18198            throws TransactionTooLargeException {
18199        enforceNotIsolatedCaller("startService");
18200        // Refuse possible leaked file descriptors
18201        if (service != null && service.hasFileDescriptors() == true) {
18202            throw new IllegalArgumentException("File descriptors passed in Intent");
18203        }
18204
18205        if (callingPackage == null) {
18206            throw new IllegalArgumentException("callingPackage cannot be null");
18207        }
18208
18209        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18210                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18211        synchronized(this) {
18212            final int callingPid = Binder.getCallingPid();
18213            final int callingUid = Binder.getCallingUid();
18214            final long origId = Binder.clearCallingIdentity();
18215            ComponentName res;
18216            try {
18217                res = mServices.startServiceLocked(caller, service,
18218                        resolvedType, callingPid, callingUid,
18219                        requireForeground, callingPackage, userId);
18220            } finally {
18221                Binder.restoreCallingIdentity(origId);
18222            }
18223            return res;
18224        }
18225    }
18226
18227    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18228            boolean fgRequired, String callingPackage, int userId)
18229            throws TransactionTooLargeException {
18230        synchronized(this) {
18231            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18232                    "startServiceInPackage: " + service + " type=" + resolvedType);
18233            final long origId = Binder.clearCallingIdentity();
18234            ComponentName res;
18235            try {
18236                res = mServices.startServiceLocked(null, service,
18237                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
18238            } finally {
18239                Binder.restoreCallingIdentity(origId);
18240            }
18241            return res;
18242        }
18243    }
18244
18245    @Override
18246    public int stopService(IApplicationThread caller, Intent service,
18247            String resolvedType, int userId) {
18248        enforceNotIsolatedCaller("stopService");
18249        // Refuse possible leaked file descriptors
18250        if (service != null && service.hasFileDescriptors() == true) {
18251            throw new IllegalArgumentException("File descriptors passed in Intent");
18252        }
18253
18254        synchronized(this) {
18255            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18256        }
18257    }
18258
18259    @Override
18260    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18261        enforceNotIsolatedCaller("peekService");
18262        // Refuse possible leaked file descriptors
18263        if (service != null && service.hasFileDescriptors() == true) {
18264            throw new IllegalArgumentException("File descriptors passed in Intent");
18265        }
18266
18267        if (callingPackage == null) {
18268            throw new IllegalArgumentException("callingPackage cannot be null");
18269        }
18270
18271        synchronized(this) {
18272            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18273        }
18274    }
18275
18276    @Override
18277    public boolean stopServiceToken(ComponentName className, IBinder token,
18278            int startId) {
18279        synchronized(this) {
18280            return mServices.stopServiceTokenLocked(className, token, startId);
18281        }
18282    }
18283
18284    @Override
18285    public void setServiceForeground(ComponentName className, IBinder token,
18286            int id, Notification notification, int flags) {
18287        synchronized(this) {
18288            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18289        }
18290    }
18291
18292    @Override
18293    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18294            boolean requireFull, String name, String callerPackage) {
18295        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18296                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18297    }
18298
18299    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18300            String className, int flags) {
18301        boolean result = false;
18302        // For apps that don't have pre-defined UIDs, check for permission
18303        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18304            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18305                if (ActivityManager.checkUidPermission(
18306                        INTERACT_ACROSS_USERS,
18307                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18308                    ComponentName comp = new ComponentName(aInfo.packageName, className);
18309                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
18310                            + " requests FLAG_SINGLE_USER, but app does not hold "
18311                            + INTERACT_ACROSS_USERS;
18312                    Slog.w(TAG, msg);
18313                    throw new SecurityException(msg);
18314                }
18315                // Permission passed
18316                result = true;
18317            }
18318        } else if ("system".equals(componentProcessName)) {
18319            result = true;
18320        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18321            // Phone app and persistent apps are allowed to export singleuser providers.
18322            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18323                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18324        }
18325        if (DEBUG_MU) Slog.v(TAG_MU,
18326                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18327                + Integer.toHexString(flags) + ") = " + result);
18328        return result;
18329    }
18330
18331    /**
18332     * Checks to see if the caller is in the same app as the singleton
18333     * component, or the component is in a special app. It allows special apps
18334     * to export singleton components but prevents exporting singleton
18335     * components for regular apps.
18336     */
18337    boolean isValidSingletonCall(int callingUid, int componentUid) {
18338        int componentAppId = UserHandle.getAppId(componentUid);
18339        return UserHandle.isSameApp(callingUid, componentUid)
18340                || componentAppId == SYSTEM_UID
18341                || componentAppId == PHONE_UID
18342                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18343                        == PackageManager.PERMISSION_GRANTED;
18344    }
18345
18346    public int bindService(IApplicationThread caller, IBinder token, Intent service,
18347            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18348            int userId) throws TransactionTooLargeException {
18349        enforceNotIsolatedCaller("bindService");
18350
18351        // Refuse possible leaked file descriptors
18352        if (service != null && service.hasFileDescriptors() == true) {
18353            throw new IllegalArgumentException("File descriptors passed in Intent");
18354        }
18355
18356        if (callingPackage == null) {
18357            throw new IllegalArgumentException("callingPackage cannot be null");
18358        }
18359
18360        synchronized(this) {
18361            return mServices.bindServiceLocked(caller, token, service,
18362                    resolvedType, connection, flags, callingPackage, userId);
18363        }
18364    }
18365
18366    public boolean unbindService(IServiceConnection connection) {
18367        synchronized (this) {
18368            return mServices.unbindServiceLocked(connection);
18369        }
18370    }
18371
18372    public void publishService(IBinder token, Intent intent, IBinder service) {
18373        // Refuse possible leaked file descriptors
18374        if (intent != null && intent.hasFileDescriptors() == true) {
18375            throw new IllegalArgumentException("File descriptors passed in Intent");
18376        }
18377
18378        synchronized(this) {
18379            if (!(token instanceof ServiceRecord)) {
18380                throw new IllegalArgumentException("Invalid service token");
18381            }
18382            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18383        }
18384    }
18385
18386    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18387        // Refuse possible leaked file descriptors
18388        if (intent != null && intent.hasFileDescriptors() == true) {
18389            throw new IllegalArgumentException("File descriptors passed in Intent");
18390        }
18391
18392        synchronized(this) {
18393            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18394        }
18395    }
18396
18397    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18398        synchronized(this) {
18399            if (!(token instanceof ServiceRecord)) {
18400                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18401                throw new IllegalArgumentException("Invalid service token");
18402            }
18403            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18404        }
18405    }
18406
18407    // =========================================================
18408    // BACKUP AND RESTORE
18409    // =========================================================
18410
18411    // Cause the target app to be launched if necessary and its backup agent
18412    // instantiated.  The backup agent will invoke backupAgentCreated() on the
18413    // activity manager to announce its creation.
18414    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18415        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18416        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18417
18418        IPackageManager pm = AppGlobals.getPackageManager();
18419        ApplicationInfo app = null;
18420        try {
18421            app = pm.getApplicationInfo(packageName, 0, userId);
18422        } catch (RemoteException e) {
18423            // can't happen; package manager is process-local
18424        }
18425        if (app == null) {
18426            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18427            return false;
18428        }
18429
18430        int oldBackupUid;
18431        int newBackupUid;
18432
18433        synchronized(this) {
18434            // !!! TODO: currently no check here that we're already bound
18435            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18436            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18437            synchronized (stats) {
18438                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18439            }
18440
18441            // Backup agent is now in use, its package can't be stopped.
18442            try {
18443                AppGlobals.getPackageManager().setPackageStoppedState(
18444                        app.packageName, false, UserHandle.getUserId(app.uid));
18445            } catch (RemoteException e) {
18446            } catch (IllegalArgumentException e) {
18447                Slog.w(TAG, "Failed trying to unstop package "
18448                        + app.packageName + ": " + e);
18449            }
18450
18451            BackupRecord r = new BackupRecord(ss, app, backupMode);
18452            ComponentName hostingName =
18453                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18454                            ? new ComponentName(app.packageName, app.backupAgentName)
18455                            : new ComponentName("android", "FullBackupAgent");
18456            // startProcessLocked() returns existing proc's record if it's already running
18457            ProcessRecord proc = startProcessLocked(app.processName, app,
18458                    false, 0, "backup", hostingName, false, false, false);
18459            if (proc == null) {
18460                Slog.e(TAG, "Unable to start backup agent process " + r);
18461                return false;
18462            }
18463
18464            // If the app is a regular app (uid >= 10000) and not the system server or phone
18465            // process, etc, then mark it as being in full backup so that certain calls to the
18466            // process can be blocked. This is not reset to false anywhere because we kill the
18467            // process after the full backup is done and the ProcessRecord will vaporize anyway.
18468            if (UserHandle.isApp(app.uid) &&
18469                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18470                proc.inFullBackup = true;
18471            }
18472            r.app = proc;
18473            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18474            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18475            mBackupTarget = r;
18476            mBackupAppName = app.packageName;
18477
18478            // Try not to kill the process during backup
18479            updateOomAdjLocked(proc, true);
18480
18481            // If the process is already attached, schedule the creation of the backup agent now.
18482            // If it is not yet live, this will be done when it attaches to the framework.
18483            if (proc.thread != null) {
18484                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18485                try {
18486                    proc.thread.scheduleCreateBackupAgent(app,
18487                            compatibilityInfoForPackageLocked(app), backupMode);
18488                } catch (RemoteException e) {
18489                    // Will time out on the backup manager side
18490                }
18491            } else {
18492                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18493            }
18494            // Invariants: at this point, the target app process exists and the application
18495            // is either already running or in the process of coming up.  mBackupTarget and
18496            // mBackupAppName describe the app, so that when it binds back to the AM we
18497            // know that it's scheduled for a backup-agent operation.
18498        }
18499
18500        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18501        if (oldBackupUid != -1) {
18502            js.removeBackingUpUid(oldBackupUid);
18503        }
18504        if (newBackupUid != -1) {
18505            js.addBackingUpUid(newBackupUid);
18506        }
18507
18508        return true;
18509    }
18510
18511    @Override
18512    public void clearPendingBackup() {
18513        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18514        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18515
18516        synchronized (this) {
18517            mBackupTarget = null;
18518            mBackupAppName = null;
18519        }
18520
18521        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18522        js.clearAllBackingUpUids();
18523    }
18524
18525    // A backup agent has just come up
18526    public void backupAgentCreated(String agentPackageName, IBinder agent) {
18527        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18528                + " = " + agent);
18529
18530        synchronized(this) {
18531            if (!agentPackageName.equals(mBackupAppName)) {
18532                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18533                return;
18534            }
18535        }
18536
18537        long oldIdent = Binder.clearCallingIdentity();
18538        try {
18539            IBackupManager bm = IBackupManager.Stub.asInterface(
18540                    ServiceManager.getService(Context.BACKUP_SERVICE));
18541            bm.agentConnected(agentPackageName, agent);
18542        } catch (RemoteException e) {
18543            // can't happen; the backup manager service is local
18544        } catch (Exception e) {
18545            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18546            e.printStackTrace();
18547        } finally {
18548            Binder.restoreCallingIdentity(oldIdent);
18549        }
18550    }
18551
18552    // done with this agent
18553    public void unbindBackupAgent(ApplicationInfo appInfo) {
18554        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18555        if (appInfo == null) {
18556            Slog.w(TAG, "unbind backup agent for null app");
18557            return;
18558        }
18559
18560        int oldBackupUid;
18561
18562        synchronized(this) {
18563            try {
18564                if (mBackupAppName == null) {
18565                    Slog.w(TAG, "Unbinding backup agent with no active backup");
18566                    return;
18567                }
18568
18569                if (!mBackupAppName.equals(appInfo.packageName)) {
18570                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18571                    return;
18572                }
18573
18574                // Not backing this app up any more; reset its OOM adjustment
18575                final ProcessRecord proc = mBackupTarget.app;
18576                updateOomAdjLocked(proc, true);
18577                proc.inFullBackup = false;
18578
18579                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18580
18581                // If the app crashed during backup, 'thread' will be null here
18582                if (proc.thread != null) {
18583                    try {
18584                        proc.thread.scheduleDestroyBackupAgent(appInfo,
18585                                compatibilityInfoForPackageLocked(appInfo));
18586                    } catch (Exception e) {
18587                        Slog.e(TAG, "Exception when unbinding backup agent:");
18588                        e.printStackTrace();
18589                    }
18590                }
18591            } finally {
18592                mBackupTarget = null;
18593                mBackupAppName = null;
18594            }
18595        }
18596
18597        if (oldBackupUid != -1) {
18598            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18599            js.removeBackingUpUid(oldBackupUid);
18600        }
18601    }
18602
18603    // =========================================================
18604    // BROADCASTS
18605    // =========================================================
18606
18607    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18608        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18609            return false;
18610        }
18611        // Easy case -- we have the app's ProcessRecord.
18612        if (record != null) {
18613            return record.info.isInstantApp();
18614        }
18615        // Otherwise check with PackageManager.
18616        if (callerPackage == null) {
18617            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18618            throw new IllegalArgumentException("Calling application did not provide package name");
18619        }
18620        mAppOpsService.checkPackage(uid, callerPackage);
18621        try {
18622            IPackageManager pm = AppGlobals.getPackageManager();
18623            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18624        } catch (RemoteException e) {
18625            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18626            return true;
18627        }
18628    }
18629
18630    boolean isPendingBroadcastProcessLocked(int pid) {
18631        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18632                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18633    }
18634
18635    void skipPendingBroadcastLocked(int pid) {
18636            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18637            for (BroadcastQueue queue : mBroadcastQueues) {
18638                queue.skipPendingBroadcastLocked(pid);
18639            }
18640    }
18641
18642    // The app just attached; send any pending broadcasts that it should receive
18643    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18644        boolean didSomething = false;
18645        for (BroadcastQueue queue : mBroadcastQueues) {
18646            didSomething |= queue.sendPendingBroadcastsLocked(app);
18647        }
18648        return didSomething;
18649    }
18650
18651    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18652            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18653            int flags) {
18654        enforceNotIsolatedCaller("registerReceiver");
18655        ArrayList<Intent> stickyIntents = null;
18656        ProcessRecord callerApp = null;
18657        final boolean visibleToInstantApps
18658                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18659        int callingUid;
18660        int callingPid;
18661        boolean instantApp;
18662        synchronized(this) {
18663            if (caller != null) {
18664                callerApp = getRecordForAppLocked(caller);
18665                if (callerApp == null) {
18666                    throw new SecurityException(
18667                            "Unable to find app for caller " + caller
18668                            + " (pid=" + Binder.getCallingPid()
18669                            + ") when registering receiver " + receiver);
18670                }
18671                if (callerApp.info.uid != SYSTEM_UID &&
18672                        !callerApp.pkgList.containsKey(callerPackage) &&
18673                        !"android".equals(callerPackage)) {
18674                    throw new SecurityException("Given caller package " + callerPackage
18675                            + " is not running in process " + callerApp);
18676                }
18677                callingUid = callerApp.info.uid;
18678                callingPid = callerApp.pid;
18679            } else {
18680                callerPackage = null;
18681                callingUid = Binder.getCallingUid();
18682                callingPid = Binder.getCallingPid();
18683            }
18684
18685            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18686            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18687                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18688
18689            Iterator<String> actions = filter.actionsIterator();
18690            if (actions == null) {
18691                ArrayList<String> noAction = new ArrayList<String>(1);
18692                noAction.add(null);
18693                actions = noAction.iterator();
18694            }
18695
18696            // Collect stickies of users
18697            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18698            while (actions.hasNext()) {
18699                String action = actions.next();
18700                for (int id : userIds) {
18701                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18702                    if (stickies != null) {
18703                        ArrayList<Intent> intents = stickies.get(action);
18704                        if (intents != null) {
18705                            if (stickyIntents == null) {
18706                                stickyIntents = new ArrayList<Intent>();
18707                            }
18708                            stickyIntents.addAll(intents);
18709                        }
18710                    }
18711                }
18712            }
18713        }
18714
18715        ArrayList<Intent> allSticky = null;
18716        if (stickyIntents != null) {
18717            final ContentResolver resolver = mContext.getContentResolver();
18718            // Look for any matching sticky broadcasts...
18719            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18720                Intent intent = stickyIntents.get(i);
18721                // Don't provided intents that aren't available to instant apps.
18722                if (instantApp &&
18723                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18724                    continue;
18725                }
18726                // If intent has scheme "content", it will need to acccess
18727                // provider that needs to lock mProviderMap in ActivityThread
18728                // and also it may need to wait application response, so we
18729                // cannot lock ActivityManagerService here.
18730                if (filter.match(resolver, intent, true, TAG) >= 0) {
18731                    if (allSticky == null) {
18732                        allSticky = new ArrayList<Intent>();
18733                    }
18734                    allSticky.add(intent);
18735                }
18736            }
18737        }
18738
18739        // The first sticky in the list is returned directly back to the client.
18740        Intent sticky = allSticky != null ? allSticky.get(0) : null;
18741        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18742        if (receiver == null) {
18743            return sticky;
18744        }
18745
18746        synchronized (this) {
18747            if (callerApp != null && (callerApp.thread == null
18748                    || callerApp.thread.asBinder() != caller.asBinder())) {
18749                // Original caller already died
18750                return null;
18751            }
18752            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18753            if (rl == null) {
18754                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18755                        userId, receiver);
18756                if (rl.app != null) {
18757                    rl.app.receivers.add(rl);
18758                } else {
18759                    try {
18760                        receiver.asBinder().linkToDeath(rl, 0);
18761                    } catch (RemoteException e) {
18762                        return sticky;
18763                    }
18764                    rl.linkedToDeath = true;
18765                }
18766                mRegisteredReceivers.put(receiver.asBinder(), rl);
18767            } else if (rl.uid != callingUid) {
18768                throw new IllegalArgumentException(
18769                        "Receiver requested to register for uid " + callingUid
18770                        + " was previously registered for uid " + rl.uid
18771                        + " callerPackage is " + callerPackage);
18772            } else if (rl.pid != callingPid) {
18773                throw new IllegalArgumentException(
18774                        "Receiver requested to register for pid " + callingPid
18775                        + " was previously registered for pid " + rl.pid
18776                        + " callerPackage is " + callerPackage);
18777            } else if (rl.userId != userId) {
18778                throw new IllegalArgumentException(
18779                        "Receiver requested to register for user " + userId
18780                        + " was previously registered for user " + rl.userId
18781                        + " callerPackage is " + callerPackage);
18782            }
18783            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18784                    permission, callingUid, userId, instantApp, visibleToInstantApps);
18785            rl.add(bf);
18786            if (!bf.debugCheck()) {
18787                Slog.w(TAG, "==> For Dynamic broadcast");
18788            }
18789            mReceiverResolver.addFilter(bf);
18790
18791            // Enqueue broadcasts for all existing stickies that match
18792            // this filter.
18793            if (allSticky != null) {
18794                ArrayList receivers = new ArrayList();
18795                receivers.add(bf);
18796
18797                final int stickyCount = allSticky.size();
18798                for (int i = 0; i < stickyCount; i++) {
18799                    Intent intent = allSticky.get(i);
18800                    BroadcastQueue queue = broadcastQueueForIntent(intent);
18801                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18802                            null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18803                            null, 0, null, null, false, true, true, -1);
18804                    queue.enqueueParallelBroadcastLocked(r);
18805                    queue.scheduleBroadcastsLocked();
18806                }
18807            }
18808
18809            return sticky;
18810        }
18811    }
18812
18813    public void unregisterReceiver(IIntentReceiver receiver) {
18814        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18815
18816        final long origId = Binder.clearCallingIdentity();
18817        try {
18818            boolean doTrim = false;
18819
18820            synchronized(this) {
18821                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18822                if (rl != null) {
18823                    final BroadcastRecord r = rl.curBroadcast;
18824                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18825                        final boolean doNext = r.queue.finishReceiverLocked(
18826                                r, r.resultCode, r.resultData, r.resultExtras,
18827                                r.resultAbort, false);
18828                        if (doNext) {
18829                            doTrim = true;
18830                            r.queue.processNextBroadcast(false);
18831                        }
18832                    }
18833
18834                    if (rl.app != null) {
18835                        rl.app.receivers.remove(rl);
18836                    }
18837                    removeReceiverLocked(rl);
18838                    if (rl.linkedToDeath) {
18839                        rl.linkedToDeath = false;
18840                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
18841                    }
18842                }
18843            }
18844
18845            // If we actually concluded any broadcasts, we might now be able
18846            // to trim the recipients' apps from our working set
18847            if (doTrim) {
18848                trimApplications();
18849                return;
18850            }
18851
18852        } finally {
18853            Binder.restoreCallingIdentity(origId);
18854        }
18855    }
18856
18857    void removeReceiverLocked(ReceiverList rl) {
18858        mRegisteredReceivers.remove(rl.receiver.asBinder());
18859        for (int i = rl.size() - 1; i >= 0; i--) {
18860            mReceiverResolver.removeFilter(rl.get(i));
18861        }
18862    }
18863
18864    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18865        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18866            ProcessRecord r = mLruProcesses.get(i);
18867            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18868                try {
18869                    r.thread.dispatchPackageBroadcast(cmd, packages);
18870                } catch (RemoteException ex) {
18871                }
18872            }
18873        }
18874    }
18875
18876    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18877            int callingUid, int[] users) {
18878        // TODO: come back and remove this assumption to triage all broadcasts
18879        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18880
18881        List<ResolveInfo> receivers = null;
18882        try {
18883            HashSet<ComponentName> singleUserReceivers = null;
18884            boolean scannedFirstReceivers = false;
18885            for (int user : users) {
18886                // Skip users that have Shell restrictions, with exception of always permitted
18887                // Shell broadcasts
18888                if (callingUid == SHELL_UID
18889                        && mUserController.hasUserRestriction(
18890                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18891                        && !isPermittedShellBroadcast(intent)) {
18892                    continue;
18893                }
18894                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18895                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18896                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18897                    // If this is not the system user, we need to check for
18898                    // any receivers that should be filtered out.
18899                    for (int i=0; i<newReceivers.size(); i++) {
18900                        ResolveInfo ri = newReceivers.get(i);
18901                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18902                            newReceivers.remove(i);
18903                            i--;
18904                        }
18905                    }
18906                }
18907                if (newReceivers != null && newReceivers.size() == 0) {
18908                    newReceivers = null;
18909                }
18910                if (receivers == null) {
18911                    receivers = newReceivers;
18912                } else if (newReceivers != null) {
18913                    // We need to concatenate the additional receivers
18914                    // found with what we have do far.  This would be easy,
18915                    // but we also need to de-dup any receivers that are
18916                    // singleUser.
18917                    if (!scannedFirstReceivers) {
18918                        // Collect any single user receivers we had already retrieved.
18919                        scannedFirstReceivers = true;
18920                        for (int i=0; i<receivers.size(); i++) {
18921                            ResolveInfo ri = receivers.get(i);
18922                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18923                                ComponentName cn = new ComponentName(
18924                                        ri.activityInfo.packageName, ri.activityInfo.name);
18925                                if (singleUserReceivers == null) {
18926                                    singleUserReceivers = new HashSet<ComponentName>();
18927                                }
18928                                singleUserReceivers.add(cn);
18929                            }
18930                        }
18931                    }
18932                    // Add the new results to the existing results, tracking
18933                    // and de-dupping single user receivers.
18934                    for (int i=0; i<newReceivers.size(); i++) {
18935                        ResolveInfo ri = newReceivers.get(i);
18936                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18937                            ComponentName cn = new ComponentName(
18938                                    ri.activityInfo.packageName, ri.activityInfo.name);
18939                            if (singleUserReceivers == null) {
18940                                singleUserReceivers = new HashSet<ComponentName>();
18941                            }
18942                            if (!singleUserReceivers.contains(cn)) {
18943                                singleUserReceivers.add(cn);
18944                                receivers.add(ri);
18945                            }
18946                        } else {
18947                            receivers.add(ri);
18948                        }
18949                    }
18950                }
18951            }
18952        } catch (RemoteException ex) {
18953            // pm is in same process, this will never happen.
18954        }
18955        return receivers;
18956    }
18957
18958    private boolean isPermittedShellBroadcast(Intent intent) {
18959        // remote bugreport should always be allowed to be taken
18960        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18961    }
18962
18963    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18964            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18965        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18966            // Don't yell about broadcasts sent via shell
18967            return;
18968        }
18969
18970        final String action = intent.getAction();
18971        if (isProtectedBroadcast
18972                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18973                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18974                || Intent.ACTION_MEDIA_BUTTON.equals(action)
18975                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18976                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18977                || Intent.ACTION_MASTER_CLEAR.equals(action)
18978                || Intent.ACTION_FACTORY_RESET.equals(action)
18979                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18980                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18981                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18982                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18983                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18984                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18985                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18986            // Broadcast is either protected, or it's a public action that
18987            // we've relaxed, so it's fine for system internals to send.
18988            return;
18989        }
18990
18991        // This broadcast may be a problem...  but there are often system components that
18992        // want to send an internal broadcast to themselves, which is annoying to have to
18993        // explicitly list each action as a protected broadcast, so we will check for that
18994        // one safe case and allow it: an explicit broadcast, only being received by something
18995        // that has protected itself.
18996        if (receivers != null && receivers.size() > 0
18997                && (intent.getPackage() != null || intent.getComponent() != null)) {
18998            boolean allProtected = true;
18999            for (int i = receivers.size()-1; i >= 0; i--) {
19000                Object target = receivers.get(i);
19001                if (target instanceof ResolveInfo) {
19002                    ResolveInfo ri = (ResolveInfo)target;
19003                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19004                        allProtected = false;
19005                        break;
19006                    }
19007                } else {
19008                    BroadcastFilter bf = (BroadcastFilter)target;
19009                    if (bf.requiredPermission == null) {
19010                        allProtected = false;
19011                        break;
19012                    }
19013                }
19014            }
19015            if (allProtected) {
19016                // All safe!
19017                return;
19018            }
19019        }
19020
19021        // The vast majority of broadcasts sent from system internals
19022        // should be protected to avoid security holes, so yell loudly
19023        // to ensure we examine these cases.
19024        if (callerApp != null) {
19025            Log.wtf(TAG, "Sending non-protected broadcast " + action
19026                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19027                    new Throwable());
19028        } else {
19029            Log.wtf(TAG, "Sending non-protected broadcast " + action
19030                            + " from system uid " + UserHandle.formatUid(callingUid)
19031                            + " pkg " + callerPackage,
19032                    new Throwable());
19033        }
19034    }
19035
19036    final int broadcastIntentLocked(ProcessRecord callerApp,
19037            String callerPackage, Intent intent, String resolvedType,
19038            IIntentReceiver resultTo, int resultCode, String resultData,
19039            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19040            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19041        intent = new Intent(intent);
19042
19043        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19044        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19045        if (callerInstantApp) {
19046            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19047        }
19048
19049        // By default broadcasts do not go to stopped apps.
19050        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19051
19052        // If we have not finished booting, don't allow this to launch new processes.
19053        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19054            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19055        }
19056
19057        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19058                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19059                + " ordered=" + ordered + " userid=" + userId);
19060        if ((resultTo != null) && !ordered) {
19061            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19062        }
19063
19064        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19065                ALLOW_NON_FULL, "broadcast", callerPackage);
19066
19067        // Make sure that the user who is receiving this broadcast is running.
19068        // If not, we will just skip it. Make an exception for shutdown broadcasts
19069        // and upgrade steps.
19070
19071        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunning(userId, 0)) {
19072            if ((callingUid != SYSTEM_UID
19073                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19074                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19075                Slog.w(TAG, "Skipping broadcast of " + intent
19076                        + ": user " + userId + " is stopped");
19077                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19078            }
19079        }
19080
19081        BroadcastOptions brOptions = null;
19082        if (bOptions != null) {
19083            brOptions = new BroadcastOptions(bOptions);
19084            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19085                // See if the caller is allowed to do this.  Note we are checking against
19086                // the actual real caller (not whoever provided the operation as say a
19087                // PendingIntent), because that who is actually supplied the arguments.
19088                if (checkComponentPermission(
19089                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19090                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19091                        != PackageManager.PERMISSION_GRANTED) {
19092                    String msg = "Permission Denial: " + intent.getAction()
19093                            + " broadcast from " + callerPackage + " (pid=" + callingPid
19094                            + ", uid=" + callingUid + ")"
19095                            + " requires "
19096                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19097                    Slog.w(TAG, msg);
19098                    throw new SecurityException(msg);
19099                }
19100            }
19101        }
19102
19103        // Verify that protected broadcasts are only being sent by system code,
19104        // and that system code is only sending protected broadcasts.
19105        final String action = intent.getAction();
19106        final boolean isProtectedBroadcast;
19107        try {
19108            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19109        } catch (RemoteException e) {
19110            Slog.w(TAG, "Remote exception", e);
19111            return ActivityManager.BROADCAST_SUCCESS;
19112        }
19113
19114        final boolean isCallerSystem;
19115        switch (UserHandle.getAppId(callingUid)) {
19116            case ROOT_UID:
19117            case SYSTEM_UID:
19118            case PHONE_UID:
19119            case BLUETOOTH_UID:
19120            case NFC_UID:
19121                isCallerSystem = true;
19122                break;
19123            default:
19124                isCallerSystem = (callerApp != null) && callerApp.persistent;
19125                break;
19126        }
19127
19128        // First line security check before anything else: stop non-system apps from
19129        // sending protected broadcasts.
19130        if (!isCallerSystem) {
19131            if (isProtectedBroadcast) {
19132                String msg = "Permission Denial: not allowed to send broadcast "
19133                        + action + " from pid="
19134                        + callingPid + ", uid=" + callingUid;
19135                Slog.w(TAG, msg);
19136                throw new SecurityException(msg);
19137
19138            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19139                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19140                // Special case for compatibility: we don't want apps to send this,
19141                // but historically it has not been protected and apps may be using it
19142                // to poke their own app widget.  So, instead of making it protected,
19143                // just limit it to the caller.
19144                if (callerPackage == null) {
19145                    String msg = "Permission Denial: not allowed to send broadcast "
19146                            + action + " from unknown caller.";
19147                    Slog.w(TAG, msg);
19148                    throw new SecurityException(msg);
19149                } else if (intent.getComponent() != null) {
19150                    // They are good enough to send to an explicit component...  verify
19151                    // it is being sent to the calling app.
19152                    if (!intent.getComponent().getPackageName().equals(
19153                            callerPackage)) {
19154                        String msg = "Permission Denial: not allowed to send broadcast "
19155                                + action + " to "
19156                                + intent.getComponent().getPackageName() + " from "
19157                                + callerPackage;
19158                        Slog.w(TAG, msg);
19159                        throw new SecurityException(msg);
19160                    }
19161                } else {
19162                    // Limit broadcast to their own package.
19163                    intent.setPackage(callerPackage);
19164                }
19165            }
19166        }
19167
19168        if (action != null) {
19169            if (getBackgroundLaunchBroadcasts().contains(action)) {
19170                if (DEBUG_BACKGROUND_CHECK) {
19171                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19172                }
19173                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19174            }
19175
19176            switch (action) {
19177                case Intent.ACTION_UID_REMOVED:
19178                case Intent.ACTION_PACKAGE_REMOVED:
19179                case Intent.ACTION_PACKAGE_CHANGED:
19180                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19181                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19182                case Intent.ACTION_PACKAGES_SUSPENDED:
19183                case Intent.ACTION_PACKAGES_UNSUSPENDED:
19184                    // Handle special intents: if this broadcast is from the package
19185                    // manager about a package being removed, we need to remove all of
19186                    // its activities from the history stack.
19187                    if (checkComponentPermission(
19188                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19189                            callingPid, callingUid, -1, true)
19190                            != PackageManager.PERMISSION_GRANTED) {
19191                        String msg = "Permission Denial: " + intent.getAction()
19192                                + " broadcast from " + callerPackage + " (pid=" + callingPid
19193                                + ", uid=" + callingUid + ")"
19194                                + " requires "
19195                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19196                        Slog.w(TAG, msg);
19197                        throw new SecurityException(msg);
19198                    }
19199                    switch (action) {
19200                        case Intent.ACTION_UID_REMOVED:
19201                            final int uid = getUidFromIntent(intent);
19202                            if (uid >= 0) {
19203                                mBatteryStatsService.removeUid(uid);
19204                                mAppOpsService.uidRemoved(uid);
19205                            }
19206                            break;
19207                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19208                            // If resources are unavailable just force stop all those packages
19209                            // and flush the attribute cache as well.
19210                            String list[] =
19211                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19212                            if (list != null && list.length > 0) {
19213                                for (int i = 0; i < list.length; i++) {
19214                                    forceStopPackageLocked(list[i], -1, false, true, true,
19215                                            false, false, userId, "storage unmount");
19216                                }
19217                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19218                                sendPackageBroadcastLocked(
19219                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19220                                        list, userId);
19221                            }
19222                            break;
19223                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19224                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19225                            break;
19226                        case Intent.ACTION_PACKAGE_REMOVED:
19227                        case Intent.ACTION_PACKAGE_CHANGED:
19228                            Uri data = intent.getData();
19229                            String ssp;
19230                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19231                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19232                                final boolean replacing =
19233                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19234                                final boolean killProcess =
19235                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19236                                final boolean fullUninstall = removed && !replacing;
19237                                if (removed) {
19238                                    if (killProcess) {
19239                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
19240                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
19241                                                false, true, true, false, fullUninstall, userId,
19242                                                removed ? "pkg removed" : "pkg changed");
19243                                    }
19244                                    final int cmd = killProcess
19245                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
19246                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19247                                    sendPackageBroadcastLocked(cmd,
19248                                            new String[] {ssp}, userId);
19249                                    if (fullUninstall) {
19250                                        mAppOpsService.packageRemoved(
19251                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19252
19253                                        // Remove all permissions granted from/to this package
19254                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
19255
19256                                        mRecentTasks.removeTasksByPackageName(ssp, userId);
19257
19258                                        mServices.forceStopPackageLocked(ssp, userId);
19259
19260                                        // Hide the "unsupported display" dialog if necessary.
19261                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19262                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19263                                            mUnsupportedDisplaySizeDialog.dismiss();
19264                                            mUnsupportedDisplaySizeDialog = null;
19265                                        }
19266                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
19267                                        mBatteryStatsService.notePackageUninstalled(ssp);
19268                                    }
19269                                } else {
19270                                    if (killProcess) {
19271                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
19272                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
19273                                                userId, ProcessList.INVALID_ADJ,
19274                                                false, true, true, false, "change " + ssp);
19275                                    }
19276                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19277                                            intent.getStringArrayExtra(
19278                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19279                                }
19280                            }
19281                            break;
19282                        case Intent.ACTION_PACKAGES_SUSPENDED:
19283                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
19284                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19285                                    intent.getAction());
19286                            final String[] packageNames = intent.getStringArrayExtra(
19287                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
19288                            final int userHandle = intent.getIntExtra(
19289                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19290
19291                            synchronized(ActivityManagerService.this) {
19292                                mRecentTasks.onPackagesSuspendedChanged(
19293                                        packageNames, suspended, userHandle);
19294                            }
19295                            break;
19296                    }
19297                    break;
19298                case Intent.ACTION_PACKAGE_REPLACED:
19299                {
19300                    final Uri data = intent.getData();
19301                    final String ssp;
19302                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19303                        ApplicationInfo aInfo = null;
19304                        try {
19305                            aInfo = AppGlobals.getPackageManager()
19306                                    .getApplicationInfo(ssp, 0 /*flags*/, userId);
19307                        } catch (RemoteException ignore) {}
19308                        if (aInfo == null) {
19309                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19310                                    + " ssp=" + ssp + " data=" + data);
19311                            return ActivityManager.BROADCAST_SUCCESS;
19312                        }
19313                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19314                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19315                                new String[] {ssp}, userId);
19316                    }
19317                    break;
19318                }
19319                case Intent.ACTION_PACKAGE_ADDED:
19320                {
19321                    // Special case for adding a package: by default turn on compatibility mode.
19322                    Uri data = intent.getData();
19323                    String ssp;
19324                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19325                        final boolean replacing =
19326                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19327                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19328
19329                        try {
19330                            ApplicationInfo ai = AppGlobals.getPackageManager().
19331                                    getApplicationInfo(ssp, 0, 0);
19332                            mBatteryStatsService.notePackageInstalled(ssp,
19333                                    ai != null ? ai.versionCode : 0);
19334                        } catch (RemoteException e) {
19335                        }
19336                    }
19337                    break;
19338                }
19339                case Intent.ACTION_PACKAGE_DATA_CLEARED:
19340                {
19341                    Uri data = intent.getData();
19342                    String ssp;
19343                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19344                        // Hide the "unsupported display" dialog if necessary.
19345                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19346                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19347                            mUnsupportedDisplaySizeDialog.dismiss();
19348                            mUnsupportedDisplaySizeDialog = null;
19349                        }
19350                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
19351                    }
19352                    break;
19353                }
19354                case Intent.ACTION_TIMEZONE_CHANGED:
19355                    // If this is the time zone changed action, queue up a message that will reset
19356                    // the timezone of all currently running processes. This message will get
19357                    // queued up before the broadcast happens.
19358                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19359                    break;
19360                case Intent.ACTION_TIME_CHANGED:
19361                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19362                    // the tri-state value it may contain and "unknown".
19363                    // For convenience we re-use the Intent extra values.
19364                    final int NO_EXTRA_VALUE_FOUND = -1;
19365                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19366                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19367                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
19368                    // Only send a message if the time preference is available.
19369                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19370                        Message updateTimePreferenceMsg =
19371                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19372                                        timeFormatPreferenceMsgValue, 0);
19373                        mHandler.sendMessage(updateTimePreferenceMsg);
19374                    }
19375                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19376                    synchronized (stats) {
19377                        stats.noteCurrentTimeChangedLocked();
19378                    }
19379                    break;
19380                case Intent.ACTION_CLEAR_DNS_CACHE:
19381                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19382                    break;
19383                case Proxy.PROXY_CHANGE_ACTION:
19384                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19385                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19386                    break;
19387                case android.hardware.Camera.ACTION_NEW_PICTURE:
19388                case android.hardware.Camera.ACTION_NEW_VIDEO:
19389                    // In N we just turned these off; in O we are turing them back on partly,
19390                    // only for registered receivers.  This will still address the main problem
19391                    // (a spam of apps waking up when a picture is taken putting significant
19392                    // memory pressure on the system at a bad point), while still allowing apps
19393                    // that are already actively running to know about this happening.
19394                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19395                    break;
19396                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19397                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19398                    break;
19399                case "com.android.launcher.action.INSTALL_SHORTCUT":
19400                    // As of O, we no longer support this broadcasts, even for pre-O apps.
19401                    // Apps should now be using ShortcutManager.pinRequestShortcut().
19402                    Log.w(TAG, "Broadcast " + action
19403                            + " no longer supported. It will not be delivered.");
19404                    return ActivityManager.BROADCAST_SUCCESS;
19405            }
19406
19407            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19408                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19409                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19410                final int uid = getUidFromIntent(intent);
19411                if (uid != -1) {
19412                    final UidRecord uidRec = mActiveUids.get(uid);
19413                    if (uidRec != null) {
19414                        uidRec.updateHasInternetPermission();
19415                    }
19416                }
19417            }
19418        }
19419
19420        // Add to the sticky list if requested.
19421        if (sticky) {
19422            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19423                    callingPid, callingUid)
19424                    != PackageManager.PERMISSION_GRANTED) {
19425                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19426                        + callingPid + ", uid=" + callingUid
19427                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19428                Slog.w(TAG, msg);
19429                throw new SecurityException(msg);
19430            }
19431            if (requiredPermissions != null && requiredPermissions.length > 0) {
19432                Slog.w(TAG, "Can't broadcast sticky intent " + intent
19433                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
19434                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19435            }
19436            if (intent.getComponent() != null) {
19437                throw new SecurityException(
19438                        "Sticky broadcasts can't target a specific component");
19439            }
19440            // We use userId directly here, since the "all" target is maintained
19441            // as a separate set of sticky broadcasts.
19442            if (userId != UserHandle.USER_ALL) {
19443                // But first, if this is not a broadcast to all users, then
19444                // make sure it doesn't conflict with an existing broadcast to
19445                // all users.
19446                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19447                        UserHandle.USER_ALL);
19448                if (stickies != null) {
19449                    ArrayList<Intent> list = stickies.get(intent.getAction());
19450                    if (list != null) {
19451                        int N = list.size();
19452                        int i;
19453                        for (i=0; i<N; i++) {
19454                            if (intent.filterEquals(list.get(i))) {
19455                                throw new IllegalArgumentException(
19456                                        "Sticky broadcast " + intent + " for user "
19457                                        + userId + " conflicts with existing global broadcast");
19458                            }
19459                        }
19460                    }
19461                }
19462            }
19463            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19464            if (stickies == null) {
19465                stickies = new ArrayMap<>();
19466                mStickyBroadcasts.put(userId, stickies);
19467            }
19468            ArrayList<Intent> list = stickies.get(intent.getAction());
19469            if (list == null) {
19470                list = new ArrayList<>();
19471                stickies.put(intent.getAction(), list);
19472            }
19473            final int stickiesCount = list.size();
19474            int i;
19475            for (i = 0; i < stickiesCount; i++) {
19476                if (intent.filterEquals(list.get(i))) {
19477                    // This sticky already exists, replace it.
19478                    list.set(i, new Intent(intent));
19479                    break;
19480                }
19481            }
19482            if (i >= stickiesCount) {
19483                list.add(new Intent(intent));
19484            }
19485        }
19486
19487        int[] users;
19488        if (userId == UserHandle.USER_ALL) {
19489            // Caller wants broadcast to go to all started users.
19490            users = mUserController.getStartedUserArray();
19491        } else {
19492            // Caller wants broadcast to go to one specific user.
19493            users = new int[] {userId};
19494        }
19495
19496        // Figure out who all will receive this broadcast.
19497        List receivers = null;
19498        List<BroadcastFilter> registeredReceivers = null;
19499        // Need to resolve the intent to interested receivers...
19500        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19501                 == 0) {
19502            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19503        }
19504        if (intent.getComponent() == null) {
19505            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19506                // Query one target user at a time, excluding shell-restricted users
19507                for (int i = 0; i < users.length; i++) {
19508                    if (mUserController.hasUserRestriction(
19509                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19510                        continue;
19511                    }
19512                    List<BroadcastFilter> registeredReceiversForUser =
19513                            mReceiverResolver.queryIntent(intent,
19514                                    resolvedType, false /*defaultOnly*/, users[i]);
19515                    if (registeredReceivers == null) {
19516                        registeredReceivers = registeredReceiversForUser;
19517                    } else if (registeredReceiversForUser != null) {
19518                        registeredReceivers.addAll(registeredReceiversForUser);
19519                    }
19520                }
19521            } else {
19522                registeredReceivers = mReceiverResolver.queryIntent(intent,
19523                        resolvedType, false /*defaultOnly*/, userId);
19524            }
19525        }
19526
19527        final boolean replacePending =
19528                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19529
19530        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19531                + " replacePending=" + replacePending);
19532
19533        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19534        if (!ordered && NR > 0) {
19535            // If we are not serializing this broadcast, then send the
19536            // registered receivers separately so they don't wait for the
19537            // components to be launched.
19538            if (isCallerSystem) {
19539                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19540                        isProtectedBroadcast, registeredReceivers);
19541            }
19542            final BroadcastQueue queue = broadcastQueueForIntent(intent);
19543            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19544                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19545                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19546                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19547            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19548            final boolean replaced = replacePending
19549                    && (queue.replaceParallelBroadcastLocked(r) != null);
19550            // Note: We assume resultTo is null for non-ordered broadcasts.
19551            if (!replaced) {
19552                queue.enqueueParallelBroadcastLocked(r);
19553                queue.scheduleBroadcastsLocked();
19554            }
19555            registeredReceivers = null;
19556            NR = 0;
19557        }
19558
19559        // Merge into one list.
19560        int ir = 0;
19561        if (receivers != null) {
19562            // A special case for PACKAGE_ADDED: do not allow the package
19563            // being added to see this broadcast.  This prevents them from
19564            // using this as a back door to get run as soon as they are
19565            // installed.  Maybe in the future we want to have a special install
19566            // broadcast or such for apps, but we'd like to deliberately make
19567            // this decision.
19568            String skipPackages[] = null;
19569            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19570                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19571                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19572                Uri data = intent.getData();
19573                if (data != null) {
19574                    String pkgName = data.getSchemeSpecificPart();
19575                    if (pkgName != null) {
19576                        skipPackages = new String[] { pkgName };
19577                    }
19578                }
19579            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19580                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19581            }
19582            if (skipPackages != null && (skipPackages.length > 0)) {
19583                for (String skipPackage : skipPackages) {
19584                    if (skipPackage != null) {
19585                        int NT = receivers.size();
19586                        for (int it=0; it<NT; it++) {
19587                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
19588                            if (curt.activityInfo.packageName.equals(skipPackage)) {
19589                                receivers.remove(it);
19590                                it--;
19591                                NT--;
19592                            }
19593                        }
19594                    }
19595                }
19596            }
19597
19598            int NT = receivers != null ? receivers.size() : 0;
19599            int it = 0;
19600            ResolveInfo curt = null;
19601            BroadcastFilter curr = null;
19602            while (it < NT && ir < NR) {
19603                if (curt == null) {
19604                    curt = (ResolveInfo)receivers.get(it);
19605                }
19606                if (curr == null) {
19607                    curr = registeredReceivers.get(ir);
19608                }
19609                if (curr.getPriority() >= curt.priority) {
19610                    // Insert this broadcast record into the final list.
19611                    receivers.add(it, curr);
19612                    ir++;
19613                    curr = null;
19614                    it++;
19615                    NT++;
19616                } else {
19617                    // Skip to the next ResolveInfo in the final list.
19618                    it++;
19619                    curt = null;
19620                }
19621            }
19622        }
19623        while (ir < NR) {
19624            if (receivers == null) {
19625                receivers = new ArrayList();
19626            }
19627            receivers.add(registeredReceivers.get(ir));
19628            ir++;
19629        }
19630
19631        if (isCallerSystem) {
19632            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19633                    isProtectedBroadcast, receivers);
19634        }
19635
19636        if ((receivers != null && receivers.size() > 0)
19637                || resultTo != null) {
19638            BroadcastQueue queue = broadcastQueueForIntent(intent);
19639            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19640                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19641                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19642                    resultData, resultExtras, ordered, sticky, false, userId);
19643
19644            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19645                    + ": prev had " + queue.mOrderedBroadcasts.size());
19646            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19647                    "Enqueueing broadcast " + r.intent.getAction());
19648
19649            final BroadcastRecord oldRecord =
19650                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19651            if (oldRecord != null) {
19652                // Replaced, fire the result-to receiver.
19653                if (oldRecord.resultTo != null) {
19654                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19655                    try {
19656                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19657                                oldRecord.intent,
19658                                Activity.RESULT_CANCELED, null, null,
19659                                false, false, oldRecord.userId);
19660                    } catch (RemoteException e) {
19661                        Slog.w(TAG, "Failure ["
19662                                + queue.mQueueName + "] sending broadcast result of "
19663                                + intent, e);
19664
19665                    }
19666                }
19667            } else {
19668                queue.enqueueOrderedBroadcastLocked(r);
19669                queue.scheduleBroadcastsLocked();
19670            }
19671        } else {
19672            // There was nobody interested in the broadcast, but we still want to record
19673            // that it happened.
19674            if (intent.getComponent() == null && intent.getPackage() == null
19675                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19676                // This was an implicit broadcast... let's record it for posterity.
19677                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19678            }
19679        }
19680
19681        return ActivityManager.BROADCAST_SUCCESS;
19682    }
19683
19684    /**
19685     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19686     */
19687    private int getUidFromIntent(Intent intent) {
19688        if (intent == null) {
19689            return -1;
19690        }
19691        final Bundle intentExtras = intent.getExtras();
19692        return intent.hasExtra(Intent.EXTRA_UID)
19693                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19694    }
19695
19696    final void rotateBroadcastStatsIfNeededLocked() {
19697        final long now = SystemClock.elapsedRealtime();
19698        if (mCurBroadcastStats == null ||
19699                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19700            mLastBroadcastStats = mCurBroadcastStats;
19701            if (mLastBroadcastStats != null) {
19702                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19703                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19704            }
19705            mCurBroadcastStats = new BroadcastStats();
19706        }
19707    }
19708
19709    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19710            int skipCount, long dispatchTime) {
19711        rotateBroadcastStatsIfNeededLocked();
19712        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19713    }
19714
19715    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19716        rotateBroadcastStatsIfNeededLocked();
19717        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19718    }
19719
19720    final Intent verifyBroadcastLocked(Intent intent) {
19721        // Refuse possible leaked file descriptors
19722        if (intent != null && intent.hasFileDescriptors() == true) {
19723            throw new IllegalArgumentException("File descriptors passed in Intent");
19724        }
19725
19726        int flags = intent.getFlags();
19727
19728        if (!mProcessesReady) {
19729            // if the caller really truly claims to know what they're doing, go
19730            // ahead and allow the broadcast without launching any receivers
19731            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19732                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19733            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19734                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19735                        + " before boot completion");
19736                throw new IllegalStateException("Cannot broadcast before boot completed");
19737            }
19738        }
19739
19740        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19741            throw new IllegalArgumentException(
19742                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19743        }
19744
19745        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19746            switch (Binder.getCallingUid()) {
19747                case ROOT_UID:
19748                case SHELL_UID:
19749                    break;
19750                default:
19751                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19752                            + Binder.getCallingUid());
19753                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19754                    break;
19755            }
19756        }
19757
19758        return intent;
19759    }
19760
19761    public final int broadcastIntent(IApplicationThread caller,
19762            Intent intent, String resolvedType, IIntentReceiver resultTo,
19763            int resultCode, String resultData, Bundle resultExtras,
19764            String[] requiredPermissions, int appOp, Bundle bOptions,
19765            boolean serialized, boolean sticky, int userId) {
19766        enforceNotIsolatedCaller("broadcastIntent");
19767        synchronized(this) {
19768            intent = verifyBroadcastLocked(intent);
19769
19770            final ProcessRecord callerApp = getRecordForAppLocked(caller);
19771            final int callingPid = Binder.getCallingPid();
19772            final int callingUid = Binder.getCallingUid();
19773            final long origId = Binder.clearCallingIdentity();
19774            int res = broadcastIntentLocked(callerApp,
19775                    callerApp != null ? callerApp.info.packageName : null,
19776                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19777                    requiredPermissions, appOp, bOptions, serialized, sticky,
19778                    callingPid, callingUid, userId);
19779            Binder.restoreCallingIdentity(origId);
19780            return res;
19781        }
19782    }
19783
19784
19785    int broadcastIntentInPackage(String packageName, int uid,
19786            Intent intent, String resolvedType, IIntentReceiver resultTo,
19787            int resultCode, String resultData, Bundle resultExtras,
19788            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19789            int userId) {
19790        synchronized(this) {
19791            intent = verifyBroadcastLocked(intent);
19792
19793            final long origId = Binder.clearCallingIdentity();
19794            String[] requiredPermissions = requiredPermission == null ? null
19795                    : new String[] {requiredPermission};
19796            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19797                    resultTo, resultCode, resultData, resultExtras,
19798                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19799                    sticky, -1, uid, userId);
19800            Binder.restoreCallingIdentity(origId);
19801            return res;
19802        }
19803    }
19804
19805    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19806        // Refuse possible leaked file descriptors
19807        if (intent != null && intent.hasFileDescriptors() == true) {
19808            throw new IllegalArgumentException("File descriptors passed in Intent");
19809        }
19810
19811        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19812                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19813
19814        synchronized(this) {
19815            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19816                    != PackageManager.PERMISSION_GRANTED) {
19817                String msg = "Permission Denial: unbroadcastIntent() from pid="
19818                        + Binder.getCallingPid()
19819                        + ", uid=" + Binder.getCallingUid()
19820                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19821                Slog.w(TAG, msg);
19822                throw new SecurityException(msg);
19823            }
19824            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19825            if (stickies != null) {
19826                ArrayList<Intent> list = stickies.get(intent.getAction());
19827                if (list != null) {
19828                    int N = list.size();
19829                    int i;
19830                    for (i=0; i<N; i++) {
19831                        if (intent.filterEquals(list.get(i))) {
19832                            list.remove(i);
19833                            break;
19834                        }
19835                    }
19836                    if (list.size() <= 0) {
19837                        stickies.remove(intent.getAction());
19838                    }
19839                }
19840                if (stickies.size() <= 0) {
19841                    mStickyBroadcasts.remove(userId);
19842                }
19843            }
19844        }
19845    }
19846
19847    void backgroundServicesFinishedLocked(int userId) {
19848        for (BroadcastQueue queue : mBroadcastQueues) {
19849            queue.backgroundServicesFinishedLocked(userId);
19850        }
19851    }
19852
19853    public void finishReceiver(IBinder who, int resultCode, String resultData,
19854            Bundle resultExtras, boolean resultAbort, int flags) {
19855        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19856
19857        // Refuse possible leaked file descriptors
19858        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19859            throw new IllegalArgumentException("File descriptors passed in Bundle");
19860        }
19861
19862        final long origId = Binder.clearCallingIdentity();
19863        try {
19864            boolean doNext = false;
19865            BroadcastRecord r;
19866
19867            synchronized(this) {
19868                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19869                        ? mFgBroadcastQueue : mBgBroadcastQueue;
19870                r = queue.getMatchingOrderedReceiver(who);
19871                if (r != null) {
19872                    doNext = r.queue.finishReceiverLocked(r, resultCode,
19873                        resultData, resultExtras, resultAbort, true);
19874                }
19875            }
19876
19877            if (doNext) {
19878                r.queue.processNextBroadcast(false);
19879            }
19880            trimApplications();
19881        } finally {
19882            Binder.restoreCallingIdentity(origId);
19883        }
19884    }
19885
19886    // =========================================================
19887    // INSTRUMENTATION
19888    // =========================================================
19889
19890    public boolean startInstrumentation(ComponentName className,
19891            String profileFile, int flags, Bundle arguments,
19892            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19893            int userId, String abiOverride) {
19894        enforceNotIsolatedCaller("startInstrumentation");
19895        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19896                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19897        // Refuse possible leaked file descriptors
19898        if (arguments != null && arguments.hasFileDescriptors()) {
19899            throw new IllegalArgumentException("File descriptors passed in Bundle");
19900        }
19901
19902        synchronized(this) {
19903            InstrumentationInfo ii = null;
19904            ApplicationInfo ai = null;
19905            try {
19906                ii = mContext.getPackageManager().getInstrumentationInfo(
19907                    className, STOCK_PM_FLAGS);
19908                ai = AppGlobals.getPackageManager().getApplicationInfo(
19909                        ii.targetPackage, STOCK_PM_FLAGS, userId);
19910            } catch (PackageManager.NameNotFoundException e) {
19911            } catch (RemoteException e) {
19912            }
19913            if (ii == null) {
19914                reportStartInstrumentationFailureLocked(watcher, className,
19915                        "Unable to find instrumentation info for: " + className);
19916                return false;
19917            }
19918            if (ai == null) {
19919                reportStartInstrumentationFailureLocked(watcher, className,
19920                        "Unable to find instrumentation target package: " + ii.targetPackage);
19921                return false;
19922            }
19923            if (!ai.hasCode()) {
19924                reportStartInstrumentationFailureLocked(watcher, className,
19925                        "Instrumentation target has no code: " + ii.targetPackage);
19926                return false;
19927            }
19928
19929            int match = mContext.getPackageManager().checkSignatures(
19930                    ii.targetPackage, ii.packageName);
19931            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19932                String msg = "Permission Denial: starting instrumentation "
19933                        + className + " from pid="
19934                        + Binder.getCallingPid()
19935                        + ", uid=" + Binder.getCallingPid()
19936                        + " not allowed because package " + ii.packageName
19937                        + " does not have a signature matching the target "
19938                        + ii.targetPackage;
19939                reportStartInstrumentationFailureLocked(watcher, className, msg);
19940                throw new SecurityException(msg);
19941            }
19942
19943            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19944            activeInstr.mClass = className;
19945            String defProcess = ai.processName;;
19946            if (ii.targetProcesses == null) {
19947                activeInstr.mTargetProcesses = new String[]{ai.processName};
19948            } else if (ii.targetProcesses.equals("*")) {
19949                activeInstr.mTargetProcesses = new String[0];
19950            } else {
19951                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
19952                defProcess = activeInstr.mTargetProcesses[0];
19953            }
19954            activeInstr.mTargetInfo = ai;
19955            activeInstr.mProfileFile = profileFile;
19956            activeInstr.mArguments = arguments;
19957            activeInstr.mWatcher = watcher;
19958            activeInstr.mUiAutomationConnection = uiAutomationConnection;
19959            activeInstr.mResultClass = className;
19960
19961            final long origId = Binder.clearCallingIdentity();
19962            // Instrumentation can kill and relaunch even persistent processes
19963            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19964                    "start instr");
19965            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19966            app.instr = activeInstr;
19967            activeInstr.mFinished = false;
19968            activeInstr.mRunningProcesses.add(app);
19969            if (!mActiveInstrumentation.contains(activeInstr)) {
19970                mActiveInstrumentation.add(activeInstr);
19971            }
19972            Binder.restoreCallingIdentity(origId);
19973        }
19974
19975        return true;
19976    }
19977
19978    /**
19979     * Report errors that occur while attempting to start Instrumentation.  Always writes the
19980     * error to the logs, but if somebody is watching, send the report there too.  This enables
19981     * the "am" command to report errors with more information.
19982     *
19983     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19984     * @param cn The component name of the instrumentation.
19985     * @param report The error report.
19986     */
19987    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19988            ComponentName cn, String report) {
19989        Slog.w(TAG, report);
19990        if (watcher != null) {
19991            Bundle results = new Bundle();
19992            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19993            results.putString("Error", report);
19994            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19995        }
19996    }
19997
19998    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19999        if (app.instr == null) {
20000            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20001            return;
20002        }
20003
20004        if (!app.instr.mFinished && results != null) {
20005            if (app.instr.mCurResults == null) {
20006                app.instr.mCurResults = new Bundle(results);
20007            } else {
20008                app.instr.mCurResults.putAll(results);
20009            }
20010        }
20011    }
20012
20013    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20014        int userId = UserHandle.getCallingUserId();
20015        // Refuse possible leaked file descriptors
20016        if (results != null && results.hasFileDescriptors()) {
20017            throw new IllegalArgumentException("File descriptors passed in Intent");
20018        }
20019
20020        synchronized(this) {
20021            ProcessRecord app = getRecordForAppLocked(target);
20022            if (app == null) {
20023                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20024                return;
20025            }
20026            final long origId = Binder.clearCallingIdentity();
20027            addInstrumentationResultsLocked(app, results);
20028            Binder.restoreCallingIdentity(origId);
20029        }
20030    }
20031
20032    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20033        if (app.instr == null) {
20034            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20035            return;
20036        }
20037
20038        if (!app.instr.mFinished) {
20039            if (app.instr.mWatcher != null) {
20040                Bundle finalResults = app.instr.mCurResults;
20041                if (finalResults != null) {
20042                    if (app.instr.mCurResults != null && results != null) {
20043                        finalResults.putAll(results);
20044                    }
20045                } else {
20046                    finalResults = results;
20047                }
20048                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20049                        app.instr.mClass, resultCode, finalResults);
20050            }
20051
20052            // Can't call out of the system process with a lock held, so post a message.
20053            if (app.instr.mUiAutomationConnection != null) {
20054                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20055                        app.instr.mUiAutomationConnection).sendToTarget();
20056            }
20057            app.instr.mFinished = true;
20058        }
20059
20060        app.instr.removeProcess(app);
20061        app.instr = null;
20062
20063        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20064                "finished inst");
20065    }
20066
20067    public void finishInstrumentation(IApplicationThread target,
20068            int resultCode, Bundle results) {
20069        int userId = UserHandle.getCallingUserId();
20070        // Refuse possible leaked file descriptors
20071        if (results != null && results.hasFileDescriptors()) {
20072            throw new IllegalArgumentException("File descriptors passed in Intent");
20073        }
20074
20075        synchronized(this) {
20076            ProcessRecord app = getRecordForAppLocked(target);
20077            if (app == null) {
20078                Slog.w(TAG, "finishInstrumentation: no app for " + target);
20079                return;
20080            }
20081            final long origId = Binder.clearCallingIdentity();
20082            finishInstrumentationLocked(app, resultCode, results);
20083            Binder.restoreCallingIdentity(origId);
20084        }
20085    }
20086
20087    // =========================================================
20088    // CONFIGURATION
20089    // =========================================================
20090
20091    public ConfigurationInfo getDeviceConfigurationInfo() {
20092        ConfigurationInfo config = new ConfigurationInfo();
20093        synchronized (this) {
20094            final Configuration globalConfig = getGlobalConfiguration();
20095            config.reqTouchScreen = globalConfig.touchscreen;
20096            config.reqKeyboardType = globalConfig.keyboard;
20097            config.reqNavigation = globalConfig.navigation;
20098            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20099                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20100                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20101            }
20102            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20103                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20104                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20105            }
20106            config.reqGlEsVersion = GL_ES_VERSION;
20107        }
20108        return config;
20109    }
20110
20111    ActivityStack getFocusedStack() {
20112        return mStackSupervisor.getFocusedStack();
20113    }
20114
20115    @Override
20116    public StackInfo getFocusedStackInfo() throws RemoteException {
20117        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
20118        long ident = Binder.clearCallingIdentity();
20119        try {
20120            synchronized (this) {
20121                ActivityStack focusedStack = getFocusedStack();
20122                if (focusedStack != null) {
20123                    return mStackSupervisor.getStackInfo(focusedStack.mStackId);
20124                }
20125                return null;
20126            }
20127        } finally {
20128            Binder.restoreCallingIdentity(ident);
20129        }
20130    }
20131
20132    public Configuration getConfiguration() {
20133        Configuration ci;
20134        synchronized(this) {
20135            ci = new Configuration(getGlobalConfiguration());
20136            ci.userSetLocale = false;
20137        }
20138        return ci;
20139    }
20140
20141    @Override
20142    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20143        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20144        synchronized (this) {
20145            mSuppressResizeConfigChanges = suppress;
20146        }
20147    }
20148
20149    /**
20150     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20151     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20152     *       activity and clearing the task at the same time.
20153     */
20154    @Override
20155    // TODO: API should just be about changing windowing modes...
20156    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20157        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
20158                "moveTasksToFullscreenStack()");
20159        synchronized (this) {
20160            final long origId = Binder.clearCallingIdentity();
20161            try {
20162                final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
20163                if (stack != null){
20164                    if (!stack.isActivityTypeStandardOrUndefined()) {
20165                        throw new IllegalArgumentException(
20166                                "You can't move tasks from non-standard stacks.");
20167                    }
20168                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
20169                }
20170            } finally {
20171                Binder.restoreCallingIdentity(origId);
20172            }
20173        }
20174    }
20175
20176    @Override
20177    public void updatePersistentConfiguration(Configuration values) {
20178        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20179        enforceWriteSettingsPermission("updatePersistentConfiguration()");
20180        if (values == null) {
20181            throw new NullPointerException("Configuration must not be null");
20182        }
20183
20184        int userId = UserHandle.getCallingUserId();
20185
20186        synchronized(this) {
20187            updatePersistentConfigurationLocked(values, userId);
20188        }
20189    }
20190
20191    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20192        final long origId = Binder.clearCallingIdentity();
20193        try {
20194            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20195        } finally {
20196            Binder.restoreCallingIdentity(origId);
20197        }
20198    }
20199
20200    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20201        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20202                FONT_SCALE, 1.0f, userId);
20203
20204        synchronized (this) {
20205            if (getGlobalConfiguration().fontScale == scaleFactor) {
20206                return;
20207            }
20208
20209            final Configuration configuration
20210                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20211            configuration.fontScale = scaleFactor;
20212            updatePersistentConfigurationLocked(configuration, userId);
20213        }
20214    }
20215
20216    private void enforceWriteSettingsPermission(String func) {
20217        int uid = Binder.getCallingUid();
20218        if (uid == ROOT_UID) {
20219            return;
20220        }
20221
20222        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20223                Settings.getPackageNameForUid(mContext, uid), false)) {
20224            return;
20225        }
20226
20227        String msg = "Permission Denial: " + func + " from pid="
20228                + Binder.getCallingPid()
20229                + ", uid=" + uid
20230                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20231        Slog.w(TAG, msg);
20232        throw new SecurityException(msg);
20233    }
20234
20235    @Override
20236    public boolean updateConfiguration(Configuration values) {
20237        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20238
20239        synchronized(this) {
20240            if (values == null && mWindowManager != null) {
20241                // sentinel: fetch the current configuration from the window manager
20242                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20243            }
20244
20245            if (mWindowManager != null) {
20246                // Update OOM levels based on display size.
20247                mProcessList.applyDisplaySize(mWindowManager);
20248            }
20249
20250            final long origId = Binder.clearCallingIdentity();
20251            try {
20252                if (values != null) {
20253                    Settings.System.clearConfiguration(values);
20254                }
20255                updateConfigurationLocked(values, null, false, false /* persistent */,
20256                        UserHandle.USER_NULL, false /* deferResume */,
20257                        mTmpUpdateConfigurationResult);
20258                return mTmpUpdateConfigurationResult.changes != 0;
20259            } finally {
20260                Binder.restoreCallingIdentity(origId);
20261            }
20262        }
20263    }
20264
20265    void updateUserConfigurationLocked() {
20266        final Configuration configuration = new Configuration(getGlobalConfiguration());
20267        final int currentUserId = mUserController.getCurrentUserId();
20268        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20269                currentUserId, Settings.System.canWrite(mContext));
20270        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20271                false /* persistent */, currentUserId, false /* deferResume */);
20272    }
20273
20274    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20275            boolean initLocale) {
20276        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20277    }
20278
20279    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20280            boolean initLocale, boolean deferResume) {
20281        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20282        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20283                UserHandle.USER_NULL, deferResume);
20284    }
20285
20286    // To cache the list of supported system locales
20287    private String[] mSupportedSystemLocales = null;
20288
20289    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20290            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20291        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20292                deferResume, null /* result */);
20293    }
20294
20295    /**
20296     * Do either or both things: (1) change the current configuration, and (2)
20297     * make sure the given activity is running with the (now) current
20298     * configuration.  Returns true if the activity has been left running, or
20299     * false if <var>starting</var> is being destroyed to match the new
20300     * configuration.
20301     *
20302     * @param userId is only used when persistent parameter is set to true to persist configuration
20303     *               for that particular user
20304     */
20305    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20306            boolean initLocale, boolean persistent, int userId, boolean deferResume,
20307            UpdateConfigurationResult result) {
20308        int changes = 0;
20309        boolean kept = true;
20310
20311        if (mWindowManager != null) {
20312            mWindowManager.deferSurfaceLayout();
20313        }
20314        try {
20315            if (values != null) {
20316                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20317                        deferResume);
20318            }
20319
20320            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20321        } finally {
20322            if (mWindowManager != null) {
20323                mWindowManager.continueSurfaceLayout();
20324            }
20325        }
20326
20327        if (result != null) {
20328            result.changes = changes;
20329            result.activityRelaunched = !kept;
20330        }
20331        return kept;
20332    }
20333
20334    /** Update default (global) configuration and notify listeners about changes. */
20335    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20336            boolean persistent, int userId, boolean deferResume) {
20337        mTempConfig.setTo(getGlobalConfiguration());
20338        final int changes = mTempConfig.updateFrom(values);
20339        if (changes == 0) {
20340            // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20341            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20342            // performDisplayOverrideConfigUpdate in order to send the new display configuration
20343            // (even if there are no actual changes) to unfreeze the window.
20344            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20345            return 0;
20346        }
20347
20348        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20349                "Updating global configuration to: " + values);
20350
20351        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20352
20353        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20354            final LocaleList locales = values.getLocales();
20355            int bestLocaleIndex = 0;
20356            if (locales.size() > 1) {
20357                if (mSupportedSystemLocales == null) {
20358                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20359                }
20360                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20361            }
20362            SystemProperties.set("persist.sys.locale",
20363                    locales.get(bestLocaleIndex).toLanguageTag());
20364            LocaleList.setDefault(locales, bestLocaleIndex);
20365            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20366                    locales.get(bestLocaleIndex)));
20367        }
20368
20369        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20370        mTempConfig.seq = mConfigurationSeq;
20371
20372        // Update stored global config and notify everyone about the change.
20373        mStackSupervisor.onConfigurationChanged(mTempConfig);
20374
20375        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20376        // TODO(multi-display): Update UsageEvents#Event to include displayId.
20377        mUsageStatsService.reportConfigurationChange(mTempConfig,
20378                mUserController.getCurrentUserId());
20379
20380        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20381        mShowDialogs = shouldShowDialogs(mTempConfig);
20382
20383        AttributeCache ac = AttributeCache.instance();
20384        if (ac != null) {
20385            ac.updateConfiguration(mTempConfig);
20386        }
20387
20388        // Make sure all resources in our process are updated right now, so that anyone who is going
20389        // to retrieve resource values after we return will be sure to get the new ones. This is
20390        // especially important during boot, where the first config change needs to guarantee all
20391        // resources have that config before following boot code is executed.
20392        mSystemThread.applyConfigurationToResources(mTempConfig);
20393
20394        // We need another copy of global config because we're scheduling some calls instead of
20395        // running them in place. We need to be sure that object we send will be handled unchanged.
20396        final Configuration configCopy = new Configuration(mTempConfig);
20397        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20398            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20399            msg.obj = configCopy;
20400            msg.arg1 = userId;
20401            mHandler.sendMessage(msg);
20402        }
20403
20404        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20405            ProcessRecord app = mLruProcesses.get(i);
20406            try {
20407                if (app.thread != null) {
20408                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20409                            + app.processName + " new config " + configCopy);
20410                    app.thread.scheduleConfigurationChanged(configCopy);
20411                }
20412            } catch (Exception e) {
20413            }
20414        }
20415
20416        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20417        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20418                | Intent.FLAG_RECEIVER_FOREGROUND
20419                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20420        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20421                AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20422                UserHandle.USER_ALL);
20423        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20424            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20425            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20426                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20427                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20428            if (initLocale || !mProcessesReady) {
20429                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20430            }
20431            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20432                    AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20433                    UserHandle.USER_ALL);
20434        }
20435
20436        // Override configuration of the default display duplicates global config, so we need to
20437        // update it also. This will also notify WindowManager about changes.
20438        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20439                DEFAULT_DISPLAY);
20440
20441        return changes;
20442    }
20443
20444    @Override
20445    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20446        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20447
20448        synchronized (this) {
20449            // Check if display is initialized in AM.
20450            if (!mStackSupervisor.isDisplayAdded(displayId)) {
20451                // Call might come when display is not yet added or has already been removed.
20452                if (DEBUG_CONFIGURATION) {
20453                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20454                            + displayId);
20455                }
20456                return false;
20457            }
20458
20459            if (values == null && mWindowManager != null) {
20460                // sentinel: fetch the current configuration from the window manager
20461                values = mWindowManager.computeNewConfiguration(displayId);
20462            }
20463
20464            if (mWindowManager != null) {
20465                // Update OOM levels based on display size.
20466                mProcessList.applyDisplaySize(mWindowManager);
20467            }
20468
20469            final long origId = Binder.clearCallingIdentity();
20470            try {
20471                if (values != null) {
20472                    Settings.System.clearConfiguration(values);
20473                }
20474                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20475                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20476                return mTmpUpdateConfigurationResult.changes != 0;
20477            } finally {
20478                Binder.restoreCallingIdentity(origId);
20479            }
20480        }
20481    }
20482
20483    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20484            boolean deferResume, int displayId) {
20485        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20486                displayId, null /* result */);
20487    }
20488
20489    /**
20490     * Updates override configuration specific for the selected display. If no config is provided,
20491     * new one will be computed in WM based on current display info.
20492     */
20493    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20494            ActivityRecord starting, boolean deferResume, int displayId,
20495            UpdateConfigurationResult result) {
20496        int changes = 0;
20497        boolean kept = true;
20498
20499        if (mWindowManager != null) {
20500            mWindowManager.deferSurfaceLayout();
20501        }
20502        try {
20503            if (values != null) {
20504                if (displayId == DEFAULT_DISPLAY) {
20505                    // Override configuration of the default display duplicates global config, so
20506                    // we're calling global config update instead for default display. It will also
20507                    // apply the correct override config.
20508                    changes = updateGlobalConfiguration(values, false /* initLocale */,
20509                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20510                } else {
20511                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20512                }
20513            }
20514
20515            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20516        } finally {
20517            if (mWindowManager != null) {
20518                mWindowManager.continueSurfaceLayout();
20519            }
20520        }
20521
20522        if (result != null) {
20523            result.changes = changes;
20524            result.activityRelaunched = !kept;
20525        }
20526        return kept;
20527    }
20528
20529    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20530            int displayId) {
20531        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20532        final int changes = mTempConfig.updateFrom(values);
20533        if (changes != 0) {
20534            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20535                    + mTempConfig + " for displayId=" + displayId);
20536            mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20537
20538            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20539            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20540                // Reset the unsupported display size dialog.
20541                mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20542
20543                killAllBackgroundProcessesExcept(N,
20544                        ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20545            }
20546        }
20547
20548        // Update the configuration with WM first and check if any of the stacks need to be resized
20549        // due to the configuration change. If so, resize the stacks now and do any relaunches if
20550        // necessary. This way we don't need to relaunch again afterwards in
20551        // ensureActivityConfigurationLocked().
20552        if (mWindowManager != null) {
20553            final int[] resizedStacks =
20554                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20555            if (resizedStacks != null) {
20556                for (int stackId : resizedStacks) {
20557                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20558                }
20559            }
20560        }
20561
20562        return changes;
20563    }
20564
20565    /** Applies latest configuration and/or visibility updates if needed. */
20566    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20567        boolean kept = true;
20568        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20569        // mainStack is null during startup.
20570        if (mainStack != null) {
20571            if (changes != 0 && starting == null) {
20572                // If the configuration changed, and the caller is not already
20573                // in the process of starting an activity, then find the top
20574                // activity to check if its configuration needs to change.
20575                starting = mainStack.topRunningActivityLocked();
20576            }
20577
20578            if (starting != null) {
20579                kept = starting.ensureActivityConfigurationLocked(changes,
20580                        false /* preserveWindow */);
20581                // And we need to make sure at this point that all other activities
20582                // are made visible with the correct configuration.
20583                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20584                        !PRESERVE_WINDOWS);
20585            }
20586        }
20587
20588        return kept;
20589    }
20590
20591    /** Helper method that requests bounds from WM and applies them to stack. */
20592    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20593        final Rect newStackBounds = new Rect();
20594        final ActivityStack stack = mStackSupervisor.getStack(stackId);
20595        stack.getBoundsForNewConfiguration(newStackBounds);
20596        mStackSupervisor.resizeStackLocked(
20597                stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20598                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20599                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20600    }
20601
20602    /**
20603     * Decide based on the configuration whether we should show the ANR,
20604     * crash, etc dialogs.  The idea is that if there is no affordance to
20605     * press the on-screen buttons, or the user experience would be more
20606     * greatly impacted than the crash itself, we shouldn't show the dialog.
20607     *
20608     * A thought: SystemUI might also want to get told about this, the Power
20609     * dialog / global actions also might want different behaviors.
20610     */
20611    private static boolean shouldShowDialogs(Configuration config) {
20612        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20613                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20614                                   && config.navigation == Configuration.NAVIGATION_NONAV);
20615        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20616        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20617                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20618                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20619                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20620        return inputMethodExists && uiModeSupportsDialogs;
20621    }
20622
20623    @Override
20624    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20625        synchronized (this) {
20626            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20627            if (srec != null) {
20628                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20629            }
20630        }
20631        return false;
20632    }
20633
20634    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20635            Intent resultData) {
20636
20637        synchronized (this) {
20638            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20639            if (r != null) {
20640                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20641            }
20642            return false;
20643        }
20644    }
20645
20646    public int getLaunchedFromUid(IBinder activityToken) {
20647        ActivityRecord srec;
20648        synchronized (this) {
20649            srec = ActivityRecord.forTokenLocked(activityToken);
20650        }
20651        if (srec == null) {
20652            return -1;
20653        }
20654        return srec.launchedFromUid;
20655    }
20656
20657    public String getLaunchedFromPackage(IBinder activityToken) {
20658        ActivityRecord srec;
20659        synchronized (this) {
20660            srec = ActivityRecord.forTokenLocked(activityToken);
20661        }
20662        if (srec == null) {
20663            return null;
20664        }
20665        return srec.launchedFromPackage;
20666    }
20667
20668    // =========================================================
20669    // LIFETIME MANAGEMENT
20670    // =========================================================
20671
20672    // Returns whether the app is receiving broadcast.
20673    // If receiving, fetch all broadcast queues which the app is
20674    // the current [or imminent] receiver on.
20675    private boolean isReceivingBroadcastLocked(ProcessRecord app,
20676            ArraySet<BroadcastQueue> receivingQueues) {
20677        if (!app.curReceivers.isEmpty()) {
20678            for (BroadcastRecord r : app.curReceivers) {
20679                receivingQueues.add(r.queue);
20680            }
20681            return true;
20682        }
20683
20684        // It's not the current receiver, but it might be starting up to become one
20685        for (BroadcastQueue queue : mBroadcastQueues) {
20686            final BroadcastRecord r = queue.mPendingBroadcast;
20687            if (r != null && r.curApp == app) {
20688                // found it; report which queue it's in
20689                receivingQueues.add(queue);
20690            }
20691        }
20692
20693        return !receivingQueues.isEmpty();
20694    }
20695
20696    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20697            int targetUid, ComponentName targetComponent, String targetProcess) {
20698        if (!mTrackingAssociations) {
20699            return null;
20700        }
20701        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20702                = mAssociations.get(targetUid);
20703        if (components == null) {
20704            components = new ArrayMap<>();
20705            mAssociations.put(targetUid, components);
20706        }
20707        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20708        if (sourceUids == null) {
20709            sourceUids = new SparseArray<>();
20710            components.put(targetComponent, sourceUids);
20711        }
20712        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20713        if (sourceProcesses == null) {
20714            sourceProcesses = new ArrayMap<>();
20715            sourceUids.put(sourceUid, sourceProcesses);
20716        }
20717        Association ass = sourceProcesses.get(sourceProcess);
20718        if (ass == null) {
20719            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20720                    targetProcess);
20721            sourceProcesses.put(sourceProcess, ass);
20722        }
20723        ass.mCount++;
20724        ass.mNesting++;
20725        if (ass.mNesting == 1) {
20726            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20727            ass.mLastState = sourceState;
20728        }
20729        return ass;
20730    }
20731
20732    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20733            ComponentName targetComponent) {
20734        if (!mTrackingAssociations) {
20735            return;
20736        }
20737        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20738                = mAssociations.get(targetUid);
20739        if (components == null) {
20740            return;
20741        }
20742        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20743        if (sourceUids == null) {
20744            return;
20745        }
20746        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20747        if (sourceProcesses == null) {
20748            return;
20749        }
20750        Association ass = sourceProcesses.get(sourceProcess);
20751        if (ass == null || ass.mNesting <= 0) {
20752            return;
20753        }
20754        ass.mNesting--;
20755        if (ass.mNesting == 0) {
20756            long uptime = SystemClock.uptimeMillis();
20757            ass.mTime += uptime - ass.mStartTime;
20758            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20759                    += uptime - ass.mLastStateUptime;
20760            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20761        }
20762    }
20763
20764    private void noteUidProcessState(final int uid, final int state) {
20765        mBatteryStatsService.noteUidProcessState(uid, state);
20766        if (mTrackingAssociations) {
20767            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20768                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20769                        = mAssociations.valueAt(i1);
20770                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20771                    SparseArray<ArrayMap<String, Association>> sourceUids
20772                            = targetComponents.valueAt(i2);
20773                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20774                    if (sourceProcesses != null) {
20775                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20776                            Association ass = sourceProcesses.valueAt(i4);
20777                            if (ass.mNesting >= 1) {
20778                                // currently associated
20779                                long uptime = SystemClock.uptimeMillis();
20780                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20781                                        += uptime - ass.mLastStateUptime;
20782                                ass.mLastState = state;
20783                                ass.mLastStateUptime = uptime;
20784                            }
20785                        }
20786                    }
20787                }
20788            }
20789        }
20790    }
20791
20792    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20793            boolean doingAll, long now) {
20794        if (mAdjSeq == app.adjSeq) {
20795            // This adjustment has already been computed.
20796            return app.curRawAdj;
20797        }
20798
20799        if (app.thread == null) {
20800            app.adjSeq = mAdjSeq;
20801            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20802            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20803            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20804        }
20805
20806        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20807        app.adjSource = null;
20808        app.adjTarget = null;
20809        app.empty = false;
20810        app.cached = false;
20811
20812        final int activitiesSize = app.activities.size();
20813
20814        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20815            // The max adjustment doesn't allow this app to be anything
20816            // below foreground, so it is not worth doing work for it.
20817            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20818            app.adjType = "fixed";
20819            app.adjSeq = mAdjSeq;
20820            app.curRawAdj = app.maxAdj;
20821            app.foregroundActivities = false;
20822            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20823            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20824            // System processes can do UI, and when they do we want to have
20825            // them trim their memory after the user leaves the UI.  To
20826            // facilitate this, here we need to determine whether or not it
20827            // is currently showing UI.
20828            app.systemNoUi = true;
20829            if (app == TOP_APP) {
20830                app.systemNoUi = false;
20831                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20832                app.adjType = "pers-top-activity";
20833            } else if (app.hasTopUi) {
20834                app.systemNoUi = false;
20835                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20836                app.adjType = "pers-top-ui";
20837            } else if (activitiesSize > 0) {
20838                for (int j = 0; j < activitiesSize; j++) {
20839                    final ActivityRecord r = app.activities.get(j);
20840                    if (r.visible) {
20841                        app.systemNoUi = false;
20842                    }
20843                }
20844            }
20845            if (!app.systemNoUi) {
20846                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20847            }
20848            return (app.curAdj=app.maxAdj);
20849        }
20850
20851        app.systemNoUi = false;
20852
20853        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20854
20855        // Determine the importance of the process, starting with most
20856        // important to least, and assign an appropriate OOM adjustment.
20857        int adj;
20858        int schedGroup;
20859        int procState;
20860        boolean foregroundActivities = false;
20861        mTmpBroadcastQueue.clear();
20862        if (app == TOP_APP) {
20863            // The last app on the list is the foreground app.
20864            adj = ProcessList.FOREGROUND_APP_ADJ;
20865            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20866            app.adjType = "top-activity";
20867            foregroundActivities = true;
20868            procState = PROCESS_STATE_CUR_TOP;
20869            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20870        } else if (app.instr != null) {
20871            // Don't want to kill running instrumentation.
20872            adj = ProcessList.FOREGROUND_APP_ADJ;
20873            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20874            app.adjType = "instrumentation";
20875            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20876            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20877        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20878            // An app that is currently receiving a broadcast also
20879            // counts as being in the foreground for OOM killer purposes.
20880            // It's placed in a sched group based on the nature of the
20881            // broadcast as reflected by which queue it's active in.
20882            adj = ProcessList.FOREGROUND_APP_ADJ;
20883            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20884                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20885            app.adjType = "broadcast";
20886            procState = ActivityManager.PROCESS_STATE_RECEIVER;
20887            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20888        } else if (app.executingServices.size() > 0) {
20889            // An app that is currently executing a service callback also
20890            // counts as being in the foreground.
20891            adj = ProcessList.FOREGROUND_APP_ADJ;
20892            schedGroup = app.execServicesFg ?
20893                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20894            app.adjType = "exec-service";
20895            procState = ActivityManager.PROCESS_STATE_SERVICE;
20896            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20897            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20898        } else {
20899            // As far as we know the process is empty.  We may change our mind later.
20900            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20901            // At this point we don't actually know the adjustment.  Use the cached adj
20902            // value that the caller wants us to.
20903            adj = cachedAdj;
20904            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20905            app.cached = true;
20906            app.empty = true;
20907            app.adjType = "cch-empty";
20908            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20909        }
20910
20911        // Examine all activities if not already foreground.
20912        if (!foregroundActivities && activitiesSize > 0) {
20913            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20914            for (int j = 0; j < activitiesSize; j++) {
20915                final ActivityRecord r = app.activities.get(j);
20916                if (r.app != app) {
20917                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20918                            + " instead of expected " + app);
20919                    if (r.app == null || (r.app.uid == app.uid)) {
20920                        // Only fix things up when they look sane
20921                        r.app = app;
20922                    } else {
20923                        continue;
20924                    }
20925                }
20926                if (r.visible) {
20927                    // App has a visible activity; only upgrade adjustment.
20928                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20929                        adj = ProcessList.VISIBLE_APP_ADJ;
20930                        app.adjType = "vis-activity";
20931                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20932                    }
20933                    if (procState > PROCESS_STATE_CUR_TOP) {
20934                        procState = PROCESS_STATE_CUR_TOP;
20935                        app.adjType = "vis-activity";
20936                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20937                    }
20938                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20939                    app.cached = false;
20940                    app.empty = false;
20941                    foregroundActivities = true;
20942                    final TaskRecord task = r.getTask();
20943                    if (task != null && minLayer > 0) {
20944                        final int layer = task.mLayerRank;
20945                        if (layer >= 0 && minLayer > layer) {
20946                            minLayer = layer;
20947                        }
20948                    }
20949                    break;
20950                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20951                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20952                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20953                        app.adjType = "pause-activity";
20954                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20955                    }
20956                    if (procState > PROCESS_STATE_CUR_TOP) {
20957                        procState = PROCESS_STATE_CUR_TOP;
20958                        app.adjType = "pause-activity";
20959                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20960                    }
20961                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20962                    app.cached = false;
20963                    app.empty = false;
20964                    foregroundActivities = true;
20965                } else if (r.state == ActivityState.STOPPING) {
20966                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20967                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20968                        app.adjType = "stop-activity";
20969                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20970                    }
20971                    // For the process state, we will at this point consider the
20972                    // process to be cached.  It will be cached either as an activity
20973                    // or empty depending on whether the activity is finishing.  We do
20974                    // this so that we can treat the process as cached for purposes of
20975                    // memory trimming (determing current memory level, trim command to
20976                    // send to process) since there can be an arbitrary number of stopping
20977                    // processes and they should soon all go into the cached state.
20978                    if (!r.finishing) {
20979                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20980                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20981                            app.adjType = "stop-activity";
20982                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20983                        }
20984                    }
20985                    app.cached = false;
20986                    app.empty = false;
20987                    foregroundActivities = true;
20988                } else {
20989                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20990                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20991                        app.adjType = "cch-act";
20992                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
20993                    }
20994                }
20995            }
20996            if (adj == ProcessList.VISIBLE_APP_ADJ) {
20997                adj += minLayer;
20998            }
20999        }
21000
21001        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21002                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21003            if (app.foregroundServices) {
21004                // The user is aware of this app, so make it visible.
21005                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21006                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21007                app.cached = false;
21008                app.adjType = "fg-service";
21009                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21010                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21011            } else if (app.hasOverlayUi) {
21012                // The process is display an overlay UI.
21013                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21014                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21015                app.cached = false;
21016                app.adjType = "has-overlay-ui";
21017                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21018                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21019            }
21020        }
21021
21022        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21023                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21024            if (app.forcingToImportant != null) {
21025                // This is currently used for toasts...  they are not interactive, and
21026                // we don't want them to cause the app to become fully foreground (and
21027                // thus out of background check), so we yes the best background level we can.
21028                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21029                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21030                app.cached = false;
21031                app.adjType = "force-imp";
21032                app.adjSource = app.forcingToImportant;
21033                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21034                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21035            }
21036        }
21037
21038        if (app == mHeavyWeightProcess) {
21039            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21040                // We don't want to kill the current heavy-weight process.
21041                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21042                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21043                app.cached = false;
21044                app.adjType = "heavy";
21045                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21046            }
21047            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21048                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21049                app.adjType = "heavy";
21050                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21051            }
21052        }
21053
21054        if (app == mHomeProcess) {
21055            if (adj > ProcessList.HOME_APP_ADJ) {
21056                // This process is hosting what we currently consider to be the
21057                // home app, so we don't want to let it go into the background.
21058                adj = ProcessList.HOME_APP_ADJ;
21059                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21060                app.cached = false;
21061                app.adjType = "home";
21062                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21063            }
21064            if (procState > ActivityManager.PROCESS_STATE_HOME) {
21065                procState = ActivityManager.PROCESS_STATE_HOME;
21066                app.adjType = "home";
21067                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21068            }
21069        }
21070
21071        if (app == mPreviousProcess && app.activities.size() > 0) {
21072            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21073                // This was the previous process that showed UI to the user.
21074                // We want to try to keep it around more aggressively, to give
21075                // a good experience around switching between two apps.
21076                adj = ProcessList.PREVIOUS_APP_ADJ;
21077                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21078                app.cached = false;
21079                app.adjType = "previous";
21080                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21081            }
21082            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21083                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21084                app.adjType = "previous";
21085                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21086            }
21087        }
21088
21089        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21090                + " reason=" + app.adjType);
21091
21092        // By default, we use the computed adjustment.  It may be changed if
21093        // there are applications dependent on our services or providers, but
21094        // this gives us a baseline and makes sure we don't get into an
21095        // infinite recursion.
21096        app.adjSeq = mAdjSeq;
21097        app.curRawAdj = adj;
21098        app.hasStartedServices = false;
21099
21100        if (mBackupTarget != null && app == mBackupTarget.app) {
21101            // If possible we want to avoid killing apps while they're being backed up
21102            if (adj > ProcessList.BACKUP_APP_ADJ) {
21103                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21104                adj = ProcessList.BACKUP_APP_ADJ;
21105                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21106                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21107                }
21108                app.adjType = "backup";
21109                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21110                app.cached = false;
21111            }
21112            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21113                procState = ActivityManager.PROCESS_STATE_BACKUP;
21114                app.adjType = "backup";
21115                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21116            }
21117        }
21118
21119        boolean mayBeTop = false;
21120        String mayBeTopType = null;
21121        Object mayBeTopSource = null;
21122        Object mayBeTopTarget = null;
21123
21124        for (int is = app.services.size()-1;
21125                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21126                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21127                        || procState > ActivityManager.PROCESS_STATE_TOP);
21128                is--) {
21129            ServiceRecord s = app.services.valueAt(is);
21130            if (s.startRequested) {
21131                app.hasStartedServices = true;
21132                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21133                    procState = ActivityManager.PROCESS_STATE_SERVICE;
21134                    app.adjType = "started-services";
21135                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21136                }
21137                if (app.hasShownUi && app != mHomeProcess) {
21138                    // If this process has shown some UI, let it immediately
21139                    // go to the LRU list because it may be pretty heavy with
21140                    // UI stuff.  We'll tag it with a label just to help
21141                    // debug and understand what is going on.
21142                    if (adj > ProcessList.SERVICE_ADJ) {
21143                        app.adjType = "cch-started-ui-services";
21144                    }
21145                } else {
21146                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21147                        // This service has seen some activity within
21148                        // recent memory, so we will keep its process ahead
21149                        // of the background processes.
21150                        if (adj > ProcessList.SERVICE_ADJ) {
21151                            adj = ProcessList.SERVICE_ADJ;
21152                            app.adjType = "started-services";
21153                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21154                            app.cached = false;
21155                        }
21156                    }
21157                    // If we have let the service slide into the background
21158                    // state, still have some text describing what it is doing
21159                    // even though the service no longer has an impact.
21160                    if (adj > ProcessList.SERVICE_ADJ) {
21161                        app.adjType = "cch-started-services";
21162                    }
21163                }
21164            }
21165
21166            for (int conni = s.connections.size()-1;
21167                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21168                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21169                            || procState > ActivityManager.PROCESS_STATE_TOP);
21170                    conni--) {
21171                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21172                for (int i = 0;
21173                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21174                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21175                                || procState > ActivityManager.PROCESS_STATE_TOP);
21176                        i++) {
21177                    // XXX should compute this based on the max of
21178                    // all connected clients.
21179                    ConnectionRecord cr = clist.get(i);
21180                    if (cr.binding.client == app) {
21181                        // Binding to ourself is not interesting.
21182                        continue;
21183                    }
21184
21185                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21186                        ProcessRecord client = cr.binding.client;
21187                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
21188                                TOP_APP, doingAll, now);
21189                        int clientProcState = client.curProcState;
21190                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21191                            // If the other app is cached for any reason, for purposes here
21192                            // we are going to consider it empty.  The specific cached state
21193                            // doesn't propagate except under certain conditions.
21194                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21195                        }
21196                        String adjType = null;
21197                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21198                            // Not doing bind OOM management, so treat
21199                            // this guy more like a started service.
21200                            if (app.hasShownUi && app != mHomeProcess) {
21201                                // If this process has shown some UI, let it immediately
21202                                // go to the LRU list because it may be pretty heavy with
21203                                // UI stuff.  We'll tag it with a label just to help
21204                                // debug and understand what is going on.
21205                                if (adj > clientAdj) {
21206                                    adjType = "cch-bound-ui-services";
21207                                }
21208                                app.cached = false;
21209                                clientAdj = adj;
21210                                clientProcState = procState;
21211                            } else {
21212                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21213                                    // This service has not seen activity within
21214                                    // recent memory, so allow it to drop to the
21215                                    // LRU list if there is no other reason to keep
21216                                    // it around.  We'll also tag it with a label just
21217                                    // to help debug and undertand what is going on.
21218                                    if (adj > clientAdj) {
21219                                        adjType = "cch-bound-services";
21220                                    }
21221                                    clientAdj = adj;
21222                                }
21223                            }
21224                        }
21225                        if (adj > clientAdj) {
21226                            // If this process has recently shown UI, and
21227                            // the process that is binding to it is less
21228                            // important than being visible, then we don't
21229                            // care about the binding as much as we care
21230                            // about letting this process get into the LRU
21231                            // list to be killed and restarted if needed for
21232                            // memory.
21233                            if (app.hasShownUi && app != mHomeProcess
21234                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21235                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21236                                    adjType = "cch-bound-ui-services";
21237                                }
21238                            } else {
21239                                int newAdj;
21240                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21241                                        |Context.BIND_IMPORTANT)) != 0) {
21242                                    newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21243                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21244                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21245                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21246                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21247                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21248                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21249                                    newAdj = clientAdj;
21250                                } else {
21251                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
21252                                        newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21253                                    } else {
21254                                        newAdj = adj;
21255                                    }
21256                                }
21257                                if (!client.cached) {
21258                                    app.cached = false;
21259                                }
21260                                if (adj >  newAdj) {
21261                                    adj = newAdj;
21262                                    adjType = "service";
21263                                }
21264                            }
21265                        }
21266                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21267                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21268                            // This will treat important bound services identically to
21269                            // the top app, which may behave differently than generic
21270                            // foreground work.
21271                            if (client.curSchedGroup > schedGroup) {
21272                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21273                                    schedGroup = client.curSchedGroup;
21274                                } else {
21275                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21276                                }
21277                            }
21278                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21279                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21280                                    // Special handling of clients who are in the top state.
21281                                    // We *may* want to consider this process to be in the
21282                                    // top state as well, but only if there is not another
21283                                    // reason for it to be running.  Being on the top is a
21284                                    // special state, meaning you are specifically running
21285                                    // for the current top app.  If the process is already
21286                                    // running in the background for some other reason, it
21287                                    // is more important to continue considering it to be
21288                                    // in the background state.
21289                                    mayBeTop = true;
21290                                    mayBeTopType = "service";
21291                                    mayBeTopSource = cr.binding.client;
21292                                    mayBeTopTarget = s.name;
21293                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21294                                } else {
21295                                    // Special handling for above-top states (persistent
21296                                    // processes).  These should not bring the current process
21297                                    // into the top state, since they are not on top.  Instead
21298                                    // give them the best state after that.
21299                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21300                                        clientProcState =
21301                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21302                                    } else if (mWakefulness
21303                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21304                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21305                                                    != 0) {
21306                                        clientProcState =
21307                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21308                                    } else {
21309                                        clientProcState =
21310                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21311                                    }
21312                                }
21313                            }
21314                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21315                            if (clientProcState <
21316                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21317                                clientProcState =
21318                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21319                            }
21320                        } else {
21321                            if (clientProcState <
21322                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21323                                clientProcState =
21324                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21325                            }
21326                        }
21327                        if (procState > clientProcState) {
21328                            procState = clientProcState;
21329                            if (adjType == null) {
21330                                adjType = "service";
21331                            }
21332                        }
21333                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21334                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21335                            app.pendingUiClean = true;
21336                        }
21337                        if (adjType != null) {
21338                            app.adjType = adjType;
21339                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21340                                    .REASON_SERVICE_IN_USE;
21341                            app.adjSource = cr.binding.client;
21342                            app.adjSourceProcState = clientProcState;
21343                            app.adjTarget = s.name;
21344                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21345                                    + ": " + app + ", due to " + cr.binding.client
21346                                    + " adj=" + adj + " procState=" + procState);
21347                        }
21348                    }
21349                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21350                        app.treatLikeActivity = true;
21351                    }
21352                    final ActivityRecord a = cr.activity;
21353                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21354                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21355                            (a.visible || a.state == ActivityState.RESUMED ||
21356                             a.state == ActivityState.PAUSING)) {
21357                            adj = ProcessList.FOREGROUND_APP_ADJ;
21358                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21359                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21360                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21361                                } else {
21362                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21363                                }
21364                            }
21365                            app.cached = false;
21366                            app.adjType = "service";
21367                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21368                                    .REASON_SERVICE_IN_USE;
21369                            app.adjSource = a;
21370                            app.adjSourceProcState = procState;
21371                            app.adjTarget = s.name;
21372                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21373                                    + app);
21374                        }
21375                    }
21376                }
21377            }
21378        }
21379
21380        for (int provi = app.pubProviders.size()-1;
21381                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21382                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21383                        || procState > ActivityManager.PROCESS_STATE_TOP);
21384                provi--) {
21385            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21386            for (int i = cpr.connections.size()-1;
21387                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21388                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21389                            || procState > ActivityManager.PROCESS_STATE_TOP);
21390                    i--) {
21391                ContentProviderConnection conn = cpr.connections.get(i);
21392                ProcessRecord client = conn.client;
21393                if (client == app) {
21394                    // Being our own client is not interesting.
21395                    continue;
21396                }
21397                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21398                int clientProcState = client.curProcState;
21399                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21400                    // If the other app is cached for any reason, for purposes here
21401                    // we are going to consider it empty.
21402                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21403                }
21404                String adjType = null;
21405                if (adj > clientAdj) {
21406                    if (app.hasShownUi && app != mHomeProcess
21407                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21408                        adjType = "cch-ui-provider";
21409                    } else {
21410                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21411                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21412                        adjType = "provider";
21413                    }
21414                    app.cached &= client.cached;
21415                }
21416                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21417                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21418                        // Special handling of clients who are in the top state.
21419                        // We *may* want to consider this process to be in the
21420                        // top state as well, but only if there is not another
21421                        // reason for it to be running.  Being on the top is a
21422                        // special state, meaning you are specifically running
21423                        // for the current top app.  If the process is already
21424                        // running in the background for some other reason, it
21425                        // is more important to continue considering it to be
21426                        // in the background state.
21427                        mayBeTop = true;
21428                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21429                        mayBeTopType = adjType = "provider-top";
21430                        mayBeTopSource = client;
21431                        mayBeTopTarget = cpr.name;
21432                    } else {
21433                        // Special handling for above-top states (persistent
21434                        // processes).  These should not bring the current process
21435                        // into the top state, since they are not on top.  Instead
21436                        // give them the best state after that.
21437                        clientProcState =
21438                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21439                        if (adjType == null) {
21440                            adjType = "provider";
21441                        }
21442                    }
21443                }
21444                if (procState > clientProcState) {
21445                    procState = clientProcState;
21446                }
21447                if (client.curSchedGroup > schedGroup) {
21448                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21449                }
21450                if (adjType != null) {
21451                    app.adjType = adjType;
21452                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21453                            .REASON_PROVIDER_IN_USE;
21454                    app.adjSource = client;
21455                    app.adjSourceProcState = clientProcState;
21456                    app.adjTarget = cpr.name;
21457                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21458                            + ": " + app + ", due to " + client
21459                            + " adj=" + adj + " procState=" + procState);
21460                }
21461            }
21462            // If the provider has external (non-framework) process
21463            // dependencies, ensure that its adjustment is at least
21464            // FOREGROUND_APP_ADJ.
21465            if (cpr.hasExternalProcessHandles()) {
21466                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21467                    adj = ProcessList.FOREGROUND_APP_ADJ;
21468                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21469                    app.cached = false;
21470                    app.adjType = "ext-provider";
21471                    app.adjTarget = cpr.name;
21472                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21473                }
21474                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21475                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21476                }
21477            }
21478        }
21479
21480        if (app.lastProviderTime > 0 &&
21481                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21482            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21483                adj = ProcessList.PREVIOUS_APP_ADJ;
21484                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21485                app.cached = false;
21486                app.adjType = "recent-provider";
21487                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21488            }
21489            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21490                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21491                app.adjType = "recent-provider";
21492                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21493            }
21494        }
21495
21496        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21497            // A client of one of our services or providers is in the top state.  We
21498            // *may* want to be in the top state, but not if we are already running in
21499            // the background for some other reason.  For the decision here, we are going
21500            // to pick out a few specific states that we want to remain in when a client
21501            // is top (states that tend to be longer-term) and otherwise allow it to go
21502            // to the top state.
21503            switch (procState) {
21504                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21505                    // Something else is keeping it at this level, just leave it.
21506                    break;
21507                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21508                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21509                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21510                case ActivityManager.PROCESS_STATE_SERVICE:
21511                    // These all are longer-term states, so pull them up to the top
21512                    // of the background states, but not all the way to the top state.
21513                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21514                    app.adjType = mayBeTopType;
21515                    app.adjSource = mayBeTopSource;
21516                    app.adjTarget = mayBeTopTarget;
21517                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21518                            + ": " + app + ", due to " + mayBeTopSource
21519                            + " adj=" + adj + " procState=" + procState);
21520                    break;
21521                default:
21522                    // Otherwise, top is a better choice, so take it.
21523                    procState = ActivityManager.PROCESS_STATE_TOP;
21524                    app.adjType = mayBeTopType;
21525                    app.adjSource = mayBeTopSource;
21526                    app.adjTarget = mayBeTopTarget;
21527                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21528                            + ": " + app + ", due to " + mayBeTopSource
21529                            + " adj=" + adj + " procState=" + procState);
21530                    break;
21531            }
21532        }
21533
21534        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21535            if (app.hasClientActivities) {
21536                // This is a cached process, but with client activities.  Mark it so.
21537                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21538                app.adjType = "cch-client-act";
21539            } else if (app.treatLikeActivity) {
21540                // This is a cached process, but somebody wants us to treat it like it has
21541                // an activity, okay!
21542                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21543                app.adjType = "cch-as-act";
21544            }
21545        }
21546
21547        if (adj == ProcessList.SERVICE_ADJ) {
21548            if (doingAll) {
21549                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21550                mNewNumServiceProcs++;
21551                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21552                if (!app.serviceb) {
21553                    // This service isn't far enough down on the LRU list to
21554                    // normally be a B service, but if we are low on RAM and it
21555                    // is large we want to force it down since we would prefer to
21556                    // keep launcher over it.
21557                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21558                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21559                        app.serviceHighRam = true;
21560                        app.serviceb = true;
21561                        //Slog.i(TAG, "ADJ " + app + " high ram!");
21562                    } else {
21563                        mNewNumAServiceProcs++;
21564                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
21565                    }
21566                } else {
21567                    app.serviceHighRam = false;
21568                }
21569            }
21570            if (app.serviceb) {
21571                adj = ProcessList.SERVICE_B_ADJ;
21572            }
21573        }
21574
21575        app.curRawAdj = adj;
21576
21577        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21578        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21579        if (adj > app.maxAdj) {
21580            adj = app.maxAdj;
21581            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21582                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21583            }
21584        }
21585
21586        // Do final modification to adj.  Everything we do between here and applying
21587        // the final setAdj must be done in this function, because we will also use
21588        // it when computing the final cached adj later.  Note that we don't need to
21589        // worry about this for max adj above, since max adj will always be used to
21590        // keep it out of the cached vaues.
21591        app.curAdj = app.modifyRawOomAdj(adj);
21592        app.curSchedGroup = schedGroup;
21593        app.curProcState = procState;
21594        app.foregroundActivities = foregroundActivities;
21595
21596        return app.curRawAdj;
21597    }
21598
21599    /**
21600     * Record new PSS sample for a process.
21601     */
21602    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21603            long now) {
21604        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21605                swapPss * 1024);
21606        proc.lastPssTime = now;
21607        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21608        if (DEBUG_PSS) Slog.d(TAG_PSS,
21609                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21610                + " state=" + ProcessList.makeProcStateString(procState));
21611        if (proc.initialIdlePss == 0) {
21612            proc.initialIdlePss = pss;
21613        }
21614        proc.lastPss = pss;
21615        proc.lastSwapPss = swapPss;
21616        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21617            proc.lastCachedPss = pss;
21618            proc.lastCachedSwapPss = swapPss;
21619        }
21620
21621        final SparseArray<Pair<Long, String>> watchUids
21622                = mMemWatchProcesses.getMap().get(proc.processName);
21623        Long check = null;
21624        if (watchUids != null) {
21625            Pair<Long, String> val = watchUids.get(proc.uid);
21626            if (val == null) {
21627                val = watchUids.get(0);
21628            }
21629            if (val != null) {
21630                check = val.first;
21631            }
21632        }
21633        if (check != null) {
21634            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21635                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21636                if (!isDebuggable) {
21637                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21638                        isDebuggable = true;
21639                    }
21640                }
21641                if (isDebuggable) {
21642                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21643                    final ProcessRecord myProc = proc;
21644                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
21645                    mMemWatchDumpProcName = proc.processName;
21646                    mMemWatchDumpFile = heapdumpFile.toString();
21647                    mMemWatchDumpPid = proc.pid;
21648                    mMemWatchDumpUid = proc.uid;
21649                    BackgroundThread.getHandler().post(new Runnable() {
21650                        @Override
21651                        public void run() {
21652                            revokeUriPermission(ActivityThread.currentActivityThread()
21653                                            .getApplicationThread(),
21654                                    null, DumpHeapActivity.JAVA_URI,
21655                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
21656                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21657                                    UserHandle.myUserId());
21658                            ParcelFileDescriptor fd = null;
21659                            try {
21660                                heapdumpFile.delete();
21661                                fd = ParcelFileDescriptor.open(heapdumpFile,
21662                                        ParcelFileDescriptor.MODE_CREATE |
21663                                                ParcelFileDescriptor.MODE_TRUNCATE |
21664                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
21665                                                ParcelFileDescriptor.MODE_APPEND);
21666                                IApplicationThread thread = myProc.thread;
21667                                if (thread != null) {
21668                                    try {
21669                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
21670                                                "Requesting dump heap from "
21671                                                + myProc + " to " + heapdumpFile);
21672                                        thread.dumpHeap(/* managed= */ true,
21673                                                /* mallocInfo= */ false, /* runGc= */ false,
21674                                                heapdumpFile.toString(), fd);
21675                                    } catch (RemoteException e) {
21676                                    }
21677                                }
21678                            } catch (FileNotFoundException e) {
21679                                e.printStackTrace();
21680                            } finally {
21681                                if (fd != null) {
21682                                    try {
21683                                        fd.close();
21684                                    } catch (IOException e) {
21685                                    }
21686                                }
21687                            }
21688                        }
21689                    });
21690                } else {
21691                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21692                            + ", but debugging not enabled");
21693                }
21694            }
21695        }
21696    }
21697
21698    /**
21699     * Schedule PSS collection of a process.
21700     */
21701    void requestPssLocked(ProcessRecord proc, int procState) {
21702        if (mPendingPssProcesses.contains(proc)) {
21703            return;
21704        }
21705        if (mPendingPssProcesses.size() == 0) {
21706            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21707        }
21708        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21709        proc.pssProcState = procState;
21710        mPendingPssProcesses.add(proc);
21711    }
21712
21713    /**
21714     * Schedule PSS collection of all processes.
21715     */
21716    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21717        if (!always) {
21718            if (now < (mLastFullPssTime +
21719                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21720                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
21721                return;
21722            }
21723        }
21724        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21725        mLastFullPssTime = now;
21726        mFullPssPending = true;
21727        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21728        mPendingPssProcesses.clear();
21729        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21730            ProcessRecord app = mLruProcesses.get(i);
21731            if (app.thread == null
21732                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21733                continue;
21734            }
21735            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21736                app.pssProcState = app.setProcState;
21737                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21738                        mTestPssMode, isSleepingLocked(), now);
21739                mPendingPssProcesses.add(app);
21740            }
21741        }
21742        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21743    }
21744
21745    public void setTestPssMode(boolean enabled) {
21746        synchronized (this) {
21747            mTestPssMode = enabled;
21748            if (enabled) {
21749                // Whenever we enable the mode, we want to take a snapshot all of current
21750                // process mem use.
21751                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21752            }
21753        }
21754    }
21755
21756    /**
21757     * Ask a given process to GC right now.
21758     */
21759    final void performAppGcLocked(ProcessRecord app) {
21760        try {
21761            app.lastRequestedGc = SystemClock.uptimeMillis();
21762            if (app.thread != null) {
21763                if (app.reportLowMemory) {
21764                    app.reportLowMemory = false;
21765                    app.thread.scheduleLowMemory();
21766                } else {
21767                    app.thread.processInBackground();
21768                }
21769            }
21770        } catch (Exception e) {
21771            // whatever.
21772        }
21773    }
21774
21775    /**
21776     * Returns true if things are idle enough to perform GCs.
21777     */
21778    private final boolean canGcNowLocked() {
21779        boolean processingBroadcasts = false;
21780        for (BroadcastQueue q : mBroadcastQueues) {
21781            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21782                processingBroadcasts = true;
21783            }
21784        }
21785        return !processingBroadcasts
21786                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21787    }
21788
21789    /**
21790     * Perform GCs on all processes that are waiting for it, but only
21791     * if things are idle.
21792     */
21793    final void performAppGcsLocked() {
21794        final int N = mProcessesToGc.size();
21795        if (N <= 0) {
21796            return;
21797        }
21798        if (canGcNowLocked()) {
21799            while (mProcessesToGc.size() > 0) {
21800                ProcessRecord proc = mProcessesToGc.remove(0);
21801                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21802                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21803                            <= SystemClock.uptimeMillis()) {
21804                        // To avoid spamming the system, we will GC processes one
21805                        // at a time, waiting a few seconds between each.
21806                        performAppGcLocked(proc);
21807                        scheduleAppGcsLocked();
21808                        return;
21809                    } else {
21810                        // It hasn't been long enough since we last GCed this
21811                        // process...  put it in the list to wait for its time.
21812                        addProcessToGcListLocked(proc);
21813                        break;
21814                    }
21815                }
21816            }
21817
21818            scheduleAppGcsLocked();
21819        }
21820    }
21821
21822    /**
21823     * If all looks good, perform GCs on all processes waiting for them.
21824     */
21825    final void performAppGcsIfAppropriateLocked() {
21826        if (canGcNowLocked()) {
21827            performAppGcsLocked();
21828            return;
21829        }
21830        // Still not idle, wait some more.
21831        scheduleAppGcsLocked();
21832    }
21833
21834    /**
21835     * Schedule the execution of all pending app GCs.
21836     */
21837    final void scheduleAppGcsLocked() {
21838        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21839
21840        if (mProcessesToGc.size() > 0) {
21841            // Schedule a GC for the time to the next process.
21842            ProcessRecord proc = mProcessesToGc.get(0);
21843            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21844
21845            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21846            long now = SystemClock.uptimeMillis();
21847            if (when < (now+mConstants.GC_TIMEOUT)) {
21848                when = now + mConstants.GC_TIMEOUT;
21849            }
21850            mHandler.sendMessageAtTime(msg, when);
21851        }
21852    }
21853
21854    /**
21855     * Add a process to the array of processes waiting to be GCed.  Keeps the
21856     * list in sorted order by the last GC time.  The process can't already be
21857     * on the list.
21858     */
21859    final void addProcessToGcListLocked(ProcessRecord proc) {
21860        boolean added = false;
21861        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21862            if (mProcessesToGc.get(i).lastRequestedGc <
21863                    proc.lastRequestedGc) {
21864                added = true;
21865                mProcessesToGc.add(i+1, proc);
21866                break;
21867            }
21868        }
21869        if (!added) {
21870            mProcessesToGc.add(0, proc);
21871        }
21872    }
21873
21874    /**
21875     * Set up to ask a process to GC itself.  This will either do it
21876     * immediately, or put it on the list of processes to gc the next
21877     * time things are idle.
21878     */
21879    final void scheduleAppGcLocked(ProcessRecord app) {
21880        long now = SystemClock.uptimeMillis();
21881        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21882            return;
21883        }
21884        if (!mProcessesToGc.contains(app)) {
21885            addProcessToGcListLocked(app);
21886            scheduleAppGcsLocked();
21887        }
21888    }
21889
21890    final void checkExcessivePowerUsageLocked() {
21891        updateCpuStatsNow();
21892
21893        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21894        boolean doCpuKills = true;
21895        if (mLastPowerCheckUptime == 0) {
21896            doCpuKills = false;
21897        }
21898        final long curUptime = SystemClock.uptimeMillis();
21899        final long uptimeSince = curUptime - mLastPowerCheckUptime;
21900        mLastPowerCheckUptime = curUptime;
21901        int i = mLruProcesses.size();
21902        while (i > 0) {
21903            i--;
21904            ProcessRecord app = mLruProcesses.get(i);
21905            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21906                if (app.lastCpuTime <= 0) {
21907                    continue;
21908                }
21909                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21910                if (DEBUG_POWER) {
21911                    StringBuilder sb = new StringBuilder(128);
21912                    sb.append("CPU for ");
21913                    app.toShortString(sb);
21914                    sb.append(": over ");
21915                    TimeUtils.formatDuration(uptimeSince, sb);
21916                    sb.append(" used ");
21917                    TimeUtils.formatDuration(cputimeUsed, sb);
21918                    sb.append(" (");
21919                    sb.append((cputimeUsed*100)/uptimeSince);
21920                    sb.append("%)");
21921                    Slog.i(TAG_POWER, sb.toString());
21922                }
21923                // If the process has used too much CPU over the last duration, the
21924                // user probably doesn't want this, so kill!
21925                if (doCpuKills && uptimeSince > 0) {
21926                    // What is the limit for this process?
21927                    int cpuLimit;
21928                    long checkDur = curUptime - app.whenUnimportant;
21929                    if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21930                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21931                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21932                            || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21933                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21934                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21935                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
21936                    } else {
21937                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
21938                    }
21939                    if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
21940                        synchronized (stats) {
21941                            stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21942                                    uptimeSince, cputimeUsed);
21943                        }
21944                        app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
21945                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
21946                        app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21947                    }
21948                }
21949                app.lastCpuTime = app.curCpuTime;
21950            }
21951        }
21952    }
21953
21954    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21955            long nowElapsed) {
21956        boolean success = true;
21957
21958        if (app.curRawAdj != app.setRawAdj) {
21959            app.setRawAdj = app.curRawAdj;
21960        }
21961
21962        int changes = 0;
21963
21964        if (app.curAdj != app.setAdj) {
21965            ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
21966            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
21967                String msg = "Set " + app.pid + " " + app.processName + " adj "
21968                        + app.curAdj + ": " + app.adjType;
21969                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
21970            }
21971            app.setAdj = app.curAdj;
21972            app.verifiedAdj = ProcessList.INVALID_ADJ;
21973        }
21974
21975        if (app.setSchedGroup != app.curSchedGroup) {
21976            int oldSchedGroup = app.setSchedGroup;
21977            app.setSchedGroup = app.curSchedGroup;
21978            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
21979                String msg = "Setting sched group of " + app.processName
21980                        + " to " + app.curSchedGroup;
21981                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
21982            }
21983            if (app.waitingToKill != null && app.curReceivers.isEmpty()
21984                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21985                app.kill(app.waitingToKill, true);
21986                success = false;
21987            } else {
21988                int processGroup;
21989                switch (app.curSchedGroup) {
21990                    case ProcessList.SCHED_GROUP_BACKGROUND:
21991                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
21992                        break;
21993                    case ProcessList.SCHED_GROUP_TOP_APP:
21994                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21995                        processGroup = THREAD_GROUP_TOP_APP;
21996                        break;
21997                    default:
21998                        processGroup = THREAD_GROUP_DEFAULT;
21999                        break;
22000                }
22001                long oldId = Binder.clearCallingIdentity();
22002                try {
22003                    setProcessGroup(app.pid, processGroup);
22004                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22005                        // do nothing if we already switched to RT
22006                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22007                            mVrController.onTopProcChangedLocked(app);
22008                            if (mUseFifoUiScheduling) {
22009                                // Switch UI pipeline for app to SCHED_FIFO
22010                                app.savedPriority = Process.getThreadPriority(app.pid);
22011                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22012                                if (app.renderThreadTid != 0) {
22013                                    scheduleAsFifoPriority(app.renderThreadTid,
22014                                        /* suppressLogs */true);
22015                                    if (DEBUG_OOM_ADJ) {
22016                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
22017                                            app.renderThreadTid + ") to FIFO");
22018                                    }
22019                                } else {
22020                                    if (DEBUG_OOM_ADJ) {
22021                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
22022                                    }
22023                                }
22024                            } else {
22025                                // Boost priority for top app UI and render threads
22026                                setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22027                                if (app.renderThreadTid != 0) {
22028                                    try {
22029                                        setThreadPriority(app.renderThreadTid,
22030                                                TOP_APP_PRIORITY_BOOST);
22031                                    } catch (IllegalArgumentException e) {
22032                                        // thread died, ignore
22033                                    }
22034                                }
22035                            }
22036                        }
22037                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22038                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22039                        mVrController.onTopProcChangedLocked(app);
22040                        if (mUseFifoUiScheduling) {
22041                            try {
22042                                // Reset UI pipeline to SCHED_OTHER
22043                                setThreadScheduler(app.pid, SCHED_OTHER, 0);
22044                                setThreadPriority(app.pid, app.savedPriority);
22045                                if (app.renderThreadTid != 0) {
22046                                    setThreadScheduler(app.renderThreadTid,
22047                                        SCHED_OTHER, 0);
22048                                    setThreadPriority(app.renderThreadTid, -4);
22049                                }
22050                            } catch (IllegalArgumentException e) {
22051                                Slog.w(TAG,
22052                                        "Failed to set scheduling policy, thread does not exist:\n"
22053                                                + e);
22054                            } catch (SecurityException e) {
22055                                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22056                            }
22057                        } else {
22058                            // Reset priority for top app UI and render threads
22059                            setThreadPriority(app.pid, 0);
22060                            if (app.renderThreadTid != 0) {
22061                                setThreadPriority(app.renderThreadTid, 0);
22062                            }
22063                        }
22064                    }
22065                } catch (Exception e) {
22066                    if (false) {
22067                        Slog.w(TAG, "Failed setting process group of " + app.pid
22068                                + " to " + app.curSchedGroup);
22069                        Slog.w(TAG, "at location", e);
22070                    }
22071                } finally {
22072                    Binder.restoreCallingIdentity(oldId);
22073                }
22074            }
22075        }
22076        if (app.repForegroundActivities != app.foregroundActivities) {
22077            app.repForegroundActivities = app.foregroundActivities;
22078            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22079        }
22080        if (app.repProcState != app.curProcState) {
22081            app.repProcState = app.curProcState;
22082            if (app.thread != null) {
22083                try {
22084                    if (false) {
22085                        //RuntimeException h = new RuntimeException("here");
22086                        Slog.i(TAG, "Sending new process state " + app.repProcState
22087                                + " to " + app /*, h*/);
22088                    }
22089                    app.thread.setProcessState(app.repProcState);
22090                } catch (RemoteException e) {
22091                }
22092            }
22093        }
22094        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22095                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22096            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22097                // Experimental code to more aggressively collect pss while
22098                // running test...  the problem is that this tends to collect
22099                // the data right when a process is transitioning between process
22100                // states, which well tend to give noisy data.
22101                long start = SystemClock.uptimeMillis();
22102                long pss = Debug.getPss(app.pid, mTmpLong, null);
22103                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22104                mPendingPssProcesses.remove(app);
22105                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22106                        + " to " + app.curProcState + ": "
22107                        + (SystemClock.uptimeMillis()-start) + "ms");
22108            }
22109            app.lastStateTime = now;
22110            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22111                    mTestPssMode, isSleepingLocked(), now);
22112            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22113                    + ProcessList.makeProcStateString(app.setProcState) + " to "
22114                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22115                    + (app.nextPssTime-now) + ": " + app);
22116        } else {
22117            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22118                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22119                    mTestPssMode)))) {
22120                requestPssLocked(app, app.setProcState);
22121                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22122                        mTestPssMode, isSleepingLocked(), now);
22123            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22124                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22125        }
22126        if (app.setProcState != app.curProcState) {
22127            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22128                String msg = "Proc state change of " + app.processName
22129                        + " to " + app.curProcState;
22130                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22131            }
22132            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22133            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22134            if (setImportant && !curImportant) {
22135                // This app is no longer something we consider important enough to allow to
22136                // use arbitrary amounts of battery power.  Note
22137                // its current CPU time to later know to kill it if
22138                // it is not behaving well.
22139                app.whenUnimportant = now;
22140                app.lastCpuTime = 0;
22141            }
22142            // Inform UsageStats of important process state change
22143            // Must be called before updating setProcState
22144            maybeUpdateUsageStatsLocked(app, nowElapsed);
22145
22146            app.setProcState = app.curProcState;
22147            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22148                app.notCachedSinceIdle = false;
22149            }
22150            if (!doingAll) {
22151                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22152            } else {
22153                app.procStateChanged = true;
22154            }
22155        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22156                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22157            // For apps that sit around for a long time in the interactive state, we need
22158            // to report this at least once a day so they don't go idle.
22159            maybeUpdateUsageStatsLocked(app, nowElapsed);
22160        }
22161
22162        if (changes != 0) {
22163            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22164                    "Changes in " + app + ": " + changes);
22165            int i = mPendingProcessChanges.size()-1;
22166            ProcessChangeItem item = null;
22167            while (i >= 0) {
22168                item = mPendingProcessChanges.get(i);
22169                if (item.pid == app.pid) {
22170                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22171                            "Re-using existing item: " + item);
22172                    break;
22173                }
22174                i--;
22175            }
22176            if (i < 0) {
22177                // No existing item in pending changes; need a new one.
22178                final int NA = mAvailProcessChanges.size();
22179                if (NA > 0) {
22180                    item = mAvailProcessChanges.remove(NA-1);
22181                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22182                            "Retrieving available item: " + item);
22183                } else {
22184                    item = new ProcessChangeItem();
22185                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22186                            "Allocating new item: " + item);
22187                }
22188                item.changes = 0;
22189                item.pid = app.pid;
22190                item.uid = app.info.uid;
22191                if (mPendingProcessChanges.size() == 0) {
22192                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22193                            "*** Enqueueing dispatch processes changed!");
22194                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22195                }
22196                mPendingProcessChanges.add(item);
22197            }
22198            item.changes |= changes;
22199            item.foregroundActivities = app.repForegroundActivities;
22200            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22201                    "Item " + Integer.toHexString(System.identityHashCode(item))
22202                    + " " + app.toShortString() + ": changes=" + item.changes
22203                    + " foreground=" + item.foregroundActivities
22204                    + " type=" + app.adjType + " source=" + app.adjSource
22205                    + " target=" + app.adjTarget);
22206        }
22207
22208        return success;
22209    }
22210
22211    private boolean isEphemeralLocked(int uid) {
22212        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22213        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22214            return false;
22215        }
22216        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22217                packages[0]);
22218    }
22219
22220    @VisibleForTesting
22221    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22222        final UidRecord.ChangeItem pendingChange;
22223        if (uidRec == null || uidRec.pendingChange == null) {
22224            if (mPendingUidChanges.size() == 0) {
22225                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22226                        "*** Enqueueing dispatch uid changed!");
22227                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22228            }
22229            final int NA = mAvailUidChanges.size();
22230            if (NA > 0) {
22231                pendingChange = mAvailUidChanges.remove(NA-1);
22232                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22233                        "Retrieving available item: " + pendingChange);
22234            } else {
22235                pendingChange = new UidRecord.ChangeItem();
22236                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22237                        "Allocating new item: " + pendingChange);
22238            }
22239            if (uidRec != null) {
22240                uidRec.pendingChange = pendingChange;
22241                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22242                    // If this uid is going away, and we haven't yet reported it is gone,
22243                    // then do so now.
22244                    change |= UidRecord.CHANGE_IDLE;
22245                }
22246            } else if (uid < 0) {
22247                throw new IllegalArgumentException("No UidRecord or uid");
22248            }
22249            pendingChange.uidRecord = uidRec;
22250            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22251            mPendingUidChanges.add(pendingChange);
22252        } else {
22253            pendingChange = uidRec.pendingChange;
22254            // If there is no change in idle or active state, then keep whatever was pending.
22255            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22256                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22257                        | UidRecord.CHANGE_ACTIVE));
22258            }
22259            // If there is no change in cached or uncached state, then keep whatever was pending.
22260            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22261                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22262                        | UidRecord.CHANGE_UNCACHED));
22263            }
22264            // If this is a report of the UID being gone, then we shouldn't keep any previous
22265            // report of it being active or cached.  (That is, a gone uid is never active,
22266            // and never cached.)
22267            if ((change & UidRecord.CHANGE_GONE) != 0) {
22268                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22269                if (!uidRec.idle) {
22270                    // If this uid is going away, and we haven't yet reported it is gone,
22271                    // then do so now.
22272                    change |= UidRecord.CHANGE_IDLE;
22273                }
22274            }
22275        }
22276        pendingChange.change = change;
22277        pendingChange.processState = uidRec != null
22278                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22279        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22280        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22281        if (uidRec != null) {
22282            uidRec.lastReportedChange = change;
22283            uidRec.updateLastDispatchedProcStateSeq(change);
22284        }
22285
22286        // Directly update the power manager, since we sit on top of it and it is critical
22287        // it be kept in sync (so wake locks will be held as soon as appropriate).
22288        if (mLocalPowerManager != null) {
22289            // TO DO: dispatch cached/uncached changes here, so we don't need to report
22290            // all proc state changes.
22291            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22292                mLocalPowerManager.uidActive(pendingChange.uid);
22293            }
22294            if ((change & UidRecord.CHANGE_IDLE) != 0) {
22295                mLocalPowerManager.uidIdle(pendingChange.uid);
22296            }
22297            if ((change & UidRecord.CHANGE_GONE) != 0) {
22298                mLocalPowerManager.uidGone(pendingChange.uid);
22299            } else {
22300                mLocalPowerManager.updateUidProcState(pendingChange.uid,
22301                        pendingChange.processState);
22302            }
22303        }
22304    }
22305
22306    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22307            String authority) {
22308        if (app == null) return;
22309        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22310            UserState userState = mUserController.getStartedUserState(app.userId);
22311            if (userState == null) return;
22312            final long now = SystemClock.elapsedRealtime();
22313            Long lastReported = userState.mProviderLastReportedFg.get(authority);
22314            if (lastReported == null || lastReported < now - 60 * 1000L) {
22315                if (mSystemReady) {
22316                    // Cannot touch the user stats if not system ready
22317                    mUsageStatsService.reportContentProviderUsage(
22318                            authority, providerPkgName, app.userId);
22319                }
22320                userState.mProviderLastReportedFg.put(authority, now);
22321            }
22322        }
22323    }
22324
22325    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22326        if (DEBUG_USAGE_STATS) {
22327            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22328                    + "] state changes: old = " + app.setProcState + ", new = "
22329                    + app.curProcState);
22330        }
22331        if (mUsageStatsService == null) {
22332            return;
22333        }
22334        boolean isInteraction;
22335        // To avoid some abuse patterns, we are going to be careful about what we consider
22336        // to be an app interaction.  Being the top activity doesn't count while the display
22337        // is sleeping, nor do short foreground services.
22338        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22339            isInteraction = true;
22340            app.fgInteractionTime = 0;
22341        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22342            if (app.fgInteractionTime == 0) {
22343                app.fgInteractionTime = nowElapsed;
22344                isInteraction = false;
22345            } else {
22346                isInteraction = nowElapsed > app.fgInteractionTime
22347                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22348            }
22349        } else {
22350            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22351            app.fgInteractionTime = 0;
22352        }
22353        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22354                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22355            app.interactionEventTime = nowElapsed;
22356            String[] packages = app.getPackageList();
22357            if (packages != null) {
22358                for (int i = 0; i < packages.length; i++) {
22359                    mUsageStatsService.reportEvent(packages[i], app.userId,
22360                            UsageEvents.Event.SYSTEM_INTERACTION);
22361                }
22362            }
22363        }
22364        app.reportedInteraction = isInteraction;
22365        if (!isInteraction) {
22366            app.interactionEventTime = 0;
22367        }
22368    }
22369
22370    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22371        if (proc.thread != null) {
22372            if (proc.baseProcessTracker != null) {
22373                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22374            }
22375        }
22376    }
22377
22378    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22379            ProcessRecord TOP_APP, boolean doingAll, long now) {
22380        if (app.thread == null) {
22381            return false;
22382        }
22383
22384        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22385
22386        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22387    }
22388
22389    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22390            boolean oomAdj) {
22391        if (isForeground != proc.foregroundServices) {
22392            proc.foregroundServices = isForeground;
22393            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22394                    proc.info.uid);
22395            if (isForeground) {
22396                if (curProcs == null) {
22397                    curProcs = new ArrayList<ProcessRecord>();
22398                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22399                }
22400                if (!curProcs.contains(proc)) {
22401                    curProcs.add(proc);
22402                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22403                            proc.info.packageName, proc.info.uid);
22404                }
22405            } else {
22406                if (curProcs != null) {
22407                    if (curProcs.remove(proc)) {
22408                        mBatteryStatsService.noteEvent(
22409                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22410                                proc.info.packageName, proc.info.uid);
22411                        if (curProcs.size() <= 0) {
22412                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22413                        }
22414                    }
22415                }
22416            }
22417            if (oomAdj) {
22418                updateOomAdjLocked();
22419            }
22420        }
22421    }
22422
22423    private final ActivityRecord resumedAppLocked() {
22424        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22425        String pkg;
22426        int uid;
22427        if (act != null) {
22428            pkg = act.packageName;
22429            uid = act.info.applicationInfo.uid;
22430        } else {
22431            pkg = null;
22432            uid = -1;
22433        }
22434        // Has the UID or resumed package name changed?
22435        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22436                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22437            if (mCurResumedPackage != null) {
22438                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22439                        mCurResumedPackage, mCurResumedUid);
22440            }
22441            mCurResumedPackage = pkg;
22442            mCurResumedUid = uid;
22443            if (mCurResumedPackage != null) {
22444                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22445                        mCurResumedPackage, mCurResumedUid);
22446            }
22447        }
22448        return act;
22449    }
22450
22451    /**
22452     * Update OomAdj for a specific process.
22453     * @param app The process to update
22454     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22455     *                  if necessary, or skip.
22456     * @return whether updateOomAdjLocked(app) was successful.
22457     */
22458    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22459        final ActivityRecord TOP_ACT = resumedAppLocked();
22460        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22461        final boolean wasCached = app.cached;
22462
22463        mAdjSeq++;
22464
22465        // This is the desired cached adjusment we want to tell it to use.
22466        // If our app is currently cached, we know it, and that is it.  Otherwise,
22467        // we don't know it yet, and it needs to now be cached we will then
22468        // need to do a complete oom adj.
22469        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22470                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22471        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22472                SystemClock.uptimeMillis());
22473        if (oomAdjAll
22474                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22475            // Changed to/from cached state, so apps after it in the LRU
22476            // list may also be changed.
22477            updateOomAdjLocked();
22478        }
22479        return success;
22480    }
22481
22482    final void updateOomAdjLocked() {
22483        final ActivityRecord TOP_ACT = resumedAppLocked();
22484        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22485        final long now = SystemClock.uptimeMillis();
22486        final long nowElapsed = SystemClock.elapsedRealtime();
22487        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22488        final int N = mLruProcesses.size();
22489
22490        if (false) {
22491            RuntimeException e = new RuntimeException();
22492            e.fillInStackTrace();
22493            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22494        }
22495
22496        // Reset state in all uid records.
22497        for (int i=mActiveUids.size()-1; i>=0; i--) {
22498            final UidRecord uidRec = mActiveUids.valueAt(i);
22499            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22500                    "Starting update of " + uidRec);
22501            uidRec.reset();
22502        }
22503
22504        mStackSupervisor.rankTaskLayersIfNeeded();
22505
22506        mAdjSeq++;
22507        mNewNumServiceProcs = 0;
22508        mNewNumAServiceProcs = 0;
22509
22510        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22511        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22512
22513        // Let's determine how many processes we have running vs.
22514        // how many slots we have for background processes; we may want
22515        // to put multiple processes in a slot of there are enough of
22516        // them.
22517        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22518                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22519        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22520        if (numEmptyProcs > cachedProcessLimit) {
22521            // If there are more empty processes than our limit on cached
22522            // processes, then use the cached process limit for the factor.
22523            // This ensures that the really old empty processes get pushed
22524            // down to the bottom, so if we are running low on memory we will
22525            // have a better chance at keeping around more cached processes
22526            // instead of a gazillion empty processes.
22527            numEmptyProcs = cachedProcessLimit;
22528        }
22529        int emptyFactor = numEmptyProcs/numSlots;
22530        if (emptyFactor < 1) emptyFactor = 1;
22531        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22532        if (cachedFactor < 1) cachedFactor = 1;
22533        int stepCached = 0;
22534        int stepEmpty = 0;
22535        int numCached = 0;
22536        int numEmpty = 0;
22537        int numTrimming = 0;
22538
22539        mNumNonCachedProcs = 0;
22540        mNumCachedHiddenProcs = 0;
22541
22542        // First update the OOM adjustment for each of the
22543        // application processes based on their current state.
22544        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22545        int nextCachedAdj = curCachedAdj+1;
22546        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22547        int nextEmptyAdj = curEmptyAdj+2;
22548        for (int i=N-1; i>=0; i--) {
22549            ProcessRecord app = mLruProcesses.get(i);
22550            if (!app.killedByAm && app.thread != null) {
22551                app.procStateChanged = false;
22552                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22553
22554                // If we haven't yet assigned the final cached adj
22555                // to the process, do that now.
22556                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22557                    switch (app.curProcState) {
22558                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22559                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22560                            // This process is a cached process holding activities...
22561                            // assign it the next cached value for that type, and then
22562                            // step that cached level.
22563                            app.curRawAdj = curCachedAdj;
22564                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22565                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22566                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22567                                    + ")");
22568                            if (curCachedAdj != nextCachedAdj) {
22569                                stepCached++;
22570                                if (stepCached >= cachedFactor) {
22571                                    stepCached = 0;
22572                                    curCachedAdj = nextCachedAdj;
22573                                    nextCachedAdj += 2;
22574                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22575                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22576                                    }
22577                                }
22578                            }
22579                            break;
22580                        default:
22581                            // For everything else, assign next empty cached process
22582                            // level and bump that up.  Note that this means that
22583                            // long-running services that have dropped down to the
22584                            // cached level will be treated as empty (since their process
22585                            // state is still as a service), which is what we want.
22586                            app.curRawAdj = curEmptyAdj;
22587                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22588                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22589                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22590                                    + ")");
22591                            if (curEmptyAdj != nextEmptyAdj) {
22592                                stepEmpty++;
22593                                if (stepEmpty >= emptyFactor) {
22594                                    stepEmpty = 0;
22595                                    curEmptyAdj = nextEmptyAdj;
22596                                    nextEmptyAdj += 2;
22597                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22598                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22599                                    }
22600                                }
22601                            }
22602                            break;
22603                    }
22604                }
22605
22606                applyOomAdjLocked(app, true, now, nowElapsed);
22607
22608                // Count the number of process types.
22609                switch (app.curProcState) {
22610                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22611                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22612                        mNumCachedHiddenProcs++;
22613                        numCached++;
22614                        if (numCached > cachedProcessLimit) {
22615                            app.kill("cached #" + numCached, true);
22616                        }
22617                        break;
22618                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22619                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22620                                && app.lastActivityTime < oldTime) {
22621                            app.kill("empty for "
22622                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22623                                    / 1000) + "s", true);
22624                        } else {
22625                            numEmpty++;
22626                            if (numEmpty > emptyProcessLimit) {
22627                                app.kill("empty #" + numEmpty, true);
22628                            }
22629                        }
22630                        break;
22631                    default:
22632                        mNumNonCachedProcs++;
22633                        break;
22634                }
22635
22636                if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
22637                    // If this is an isolated process, there are no services
22638                    // running in it, and it's not a special process with a
22639                    // custom entry point, then the process is no longer
22640                    // needed.  We agressively kill these because we can by
22641                    // definition not re-use the same process again, and it is
22642                    // good to avoid having whatever code was running in them
22643                    // left sitting around after no longer needed.
22644                    app.kill("isolated not needed", true);
22645                } else {
22646                    // Keeping this process, update its uid.
22647                    final UidRecord uidRec = app.uidRecord;
22648                    if (uidRec != null) {
22649                        uidRec.ephemeral = app.info.isInstantApp();
22650                        if (uidRec.curProcState > app.curProcState) {
22651                            uidRec.curProcState = app.curProcState;
22652                        }
22653                        if (app.foregroundServices) {
22654                            uidRec.foregroundServices = true;
22655                        }
22656                    }
22657                }
22658
22659                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22660                        && !app.killedByAm) {
22661                    numTrimming++;
22662                }
22663            }
22664        }
22665
22666        incrementProcStateSeqAndNotifyAppsLocked();
22667
22668        mNumServiceProcs = mNewNumServiceProcs;
22669
22670        // Now determine the memory trimming level of background processes.
22671        // Unfortunately we need to start at the back of the list to do this
22672        // properly.  We only do this if the number of background apps we
22673        // are managing to keep around is less than half the maximum we desire;
22674        // if we are keeping a good number around, we'll let them use whatever
22675        // memory they want.
22676        final int numCachedAndEmpty = numCached + numEmpty;
22677        int memFactor;
22678        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22679                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22680            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22681                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22682            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22683                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22684            } else {
22685                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22686            }
22687        } else {
22688            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22689        }
22690        // We always allow the memory level to go up (better).  We only allow it to go
22691        // down if we are in a state where that is allowed, *and* the total number of processes
22692        // has gone down since last time.
22693        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22694                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22695                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22696        if (memFactor > mLastMemoryLevel) {
22697            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22698                memFactor = mLastMemoryLevel;
22699                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22700            }
22701        }
22702        if (memFactor != mLastMemoryLevel) {
22703            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22704        }
22705        mLastMemoryLevel = memFactor;
22706        mLastNumProcesses = mLruProcesses.size();
22707        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22708        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22709        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22710            if (mLowRamStartTime == 0) {
22711                mLowRamStartTime = now;
22712            }
22713            int step = 0;
22714            int fgTrimLevel;
22715            switch (memFactor) {
22716                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22717                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22718                    break;
22719                case ProcessStats.ADJ_MEM_FACTOR_LOW:
22720                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22721                    break;
22722                default:
22723                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22724                    break;
22725            }
22726            int factor = numTrimming/3;
22727            int minFactor = 2;
22728            if (mHomeProcess != null) minFactor++;
22729            if (mPreviousProcess != null) minFactor++;
22730            if (factor < minFactor) factor = minFactor;
22731            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22732            for (int i=N-1; i>=0; i--) {
22733                ProcessRecord app = mLruProcesses.get(i);
22734                if (allChanged || app.procStateChanged) {
22735                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22736                    app.procStateChanged = false;
22737                }
22738                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22739                        && !app.killedByAm) {
22740                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
22741                        try {
22742                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22743                                    "Trimming memory of " + app.processName + " to " + curLevel);
22744                            app.thread.scheduleTrimMemory(curLevel);
22745                        } catch (RemoteException e) {
22746                        }
22747                        if (false) {
22748                            // For now we won't do this; our memory trimming seems
22749                            // to be good enough at this point that destroying
22750                            // activities causes more harm than good.
22751                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22752                                    && app != mHomeProcess && app != mPreviousProcess) {
22753                                // Need to do this on its own message because the stack may not
22754                                // be in a consistent state at this point.
22755                                // For these apps we will also finish their activities
22756                                // to help them free memory.
22757                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22758                            }
22759                        }
22760                    }
22761                    app.trimMemoryLevel = curLevel;
22762                    step++;
22763                    if (step >= factor) {
22764                        step = 0;
22765                        switch (curLevel) {
22766                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22767                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22768                                break;
22769                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22770                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22771                                break;
22772                        }
22773                    }
22774                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22775                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22776                            && app.thread != null) {
22777                        try {
22778                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22779                                    "Trimming memory of heavy-weight " + app.processName
22780                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22781                            app.thread.scheduleTrimMemory(
22782                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22783                        } catch (RemoteException e) {
22784                        }
22785                    }
22786                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22787                } else {
22788                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22789                            || app.systemNoUi) && app.pendingUiClean) {
22790                        // If this application is now in the background and it
22791                        // had done UI, then give it the special trim level to
22792                        // have it free UI resources.
22793                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22794                        if (app.trimMemoryLevel < level && app.thread != null) {
22795                            try {
22796                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22797                                        "Trimming memory of bg-ui " + app.processName
22798                                        + " to " + level);
22799                                app.thread.scheduleTrimMemory(level);
22800                            } catch (RemoteException e) {
22801                            }
22802                        }
22803                        app.pendingUiClean = false;
22804                    }
22805                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22806                        try {
22807                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22808                                    "Trimming memory of fg " + app.processName
22809                                    + " to " + fgTrimLevel);
22810                            app.thread.scheduleTrimMemory(fgTrimLevel);
22811                        } catch (RemoteException e) {
22812                        }
22813                    }
22814                    app.trimMemoryLevel = fgTrimLevel;
22815                }
22816            }
22817        } else {
22818            if (mLowRamStartTime != 0) {
22819                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22820                mLowRamStartTime = 0;
22821            }
22822            for (int i=N-1; i>=0; i--) {
22823                ProcessRecord app = mLruProcesses.get(i);
22824                if (allChanged || app.procStateChanged) {
22825                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22826                    app.procStateChanged = false;
22827                }
22828                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22829                        || app.systemNoUi) && app.pendingUiClean) {
22830                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22831                            && app.thread != null) {
22832                        try {
22833                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22834                                    "Trimming memory of ui hidden " + app.processName
22835                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22836                            app.thread.scheduleTrimMemory(
22837                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22838                        } catch (RemoteException e) {
22839                        }
22840                    }
22841                    app.pendingUiClean = false;
22842                }
22843                app.trimMemoryLevel = 0;
22844            }
22845        }
22846
22847        if (mAlwaysFinishActivities) {
22848            // Need to do this on its own message because the stack may not
22849            // be in a consistent state at this point.
22850            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22851        }
22852
22853        if (allChanged) {
22854            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22855        }
22856
22857        ArrayList<UidRecord> becameIdle = null;
22858
22859        // Update from any uid changes.
22860        if (mLocalPowerManager != null) {
22861            mLocalPowerManager.startUidChanges();
22862        }
22863        for (int i=mActiveUids.size()-1; i>=0; i--) {
22864            final UidRecord uidRec = mActiveUids.valueAt(i);
22865            int uidChange = UidRecord.CHANGE_PROCSTATE;
22866            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22867                    && (uidRec.setProcState != uidRec.curProcState
22868                           || uidRec.setWhitelist != uidRec.curWhitelist)) {
22869                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22870                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22871                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22872                        + " to " + uidRec.curWhitelist);
22873                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22874                        && !uidRec.curWhitelist) {
22875                    // UID is now in the background (and not on the temp whitelist).  Was it
22876                    // previously in the foreground (or on the temp whitelist)?
22877                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22878                            || uidRec.setWhitelist) {
22879                        uidRec.lastBackgroundTime = nowElapsed;
22880                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22881                            // Note: the background settle time is in elapsed realtime, while
22882                            // the handler time base is uptime.  All this means is that we may
22883                            // stop background uids later than we had intended, but that only
22884                            // happens because the device was sleeping so we are okay anyway.
22885                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22886                                    mConstants.BACKGROUND_SETTLE_TIME);
22887                        }
22888                    }
22889                    if (uidRec.idle && !uidRec.setIdle) {
22890                        uidChange = UidRecord.CHANGE_IDLE;
22891                        if (becameIdle == null) {
22892                            becameIdle = new ArrayList<>();
22893                        }
22894                        becameIdle.add(uidRec);
22895                    }
22896                } else {
22897                    if (uidRec.idle) {
22898                        uidChange = UidRecord.CHANGE_ACTIVE;
22899                        EventLogTags.writeAmUidActive(uidRec.uid);
22900                        uidRec.idle = false;
22901                    }
22902                    uidRec.lastBackgroundTime = 0;
22903                }
22904                final boolean wasCached = uidRec.setProcState
22905                        > ActivityManager.PROCESS_STATE_RECEIVER;
22906                final boolean isCached = uidRec.curProcState
22907                        > ActivityManager.PROCESS_STATE_RECEIVER;
22908                if (wasCached != isCached ||
22909                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22910                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22911                }
22912                uidRec.setProcState = uidRec.curProcState;
22913                uidRec.setWhitelist = uidRec.curWhitelist;
22914                uidRec.setIdle = uidRec.idle;
22915                enqueueUidChangeLocked(uidRec, -1, uidChange);
22916                noteUidProcessState(uidRec.uid, uidRec.curProcState);
22917                if (uidRec.foregroundServices) {
22918                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
22919                }
22920            }
22921        }
22922        if (mLocalPowerManager != null) {
22923            mLocalPowerManager.finishUidChanges();
22924        }
22925
22926        if (becameIdle != null) {
22927            // If we have any new uids that became idle this time, we need to make sure
22928            // they aren't left with running services.
22929            for (int i = becameIdle.size() - 1; i >= 0; i--) {
22930                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22931            }
22932        }
22933
22934        if (mProcessStats.shouldWriteNowLocked(now)) {
22935            mHandler.post(new Runnable() {
22936                @Override public void run() {
22937                    synchronized (ActivityManagerService.this) {
22938                        mProcessStats.writeStateAsyncLocked();
22939                    }
22940                }
22941            });
22942        }
22943
22944        if (DEBUG_OOM_ADJ) {
22945            final long duration = SystemClock.uptimeMillis() - now;
22946            if (false) {
22947                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22948                        new RuntimeException("here").fillInStackTrace());
22949            } else {
22950                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22951            }
22952        }
22953    }
22954
22955    @Override
22956    public void makePackageIdle(String packageName, int userId) {
22957        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22958                != PackageManager.PERMISSION_GRANTED) {
22959            String msg = "Permission Denial: makePackageIdle() from pid="
22960                    + Binder.getCallingPid()
22961                    + ", uid=" + Binder.getCallingUid()
22962                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22963            Slog.w(TAG, msg);
22964            throw new SecurityException(msg);
22965        }
22966        final int callingPid = Binder.getCallingPid();
22967        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22968                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22969        long callingId = Binder.clearCallingIdentity();
22970        synchronized(this) {
22971            try {
22972                IPackageManager pm = AppGlobals.getPackageManager();
22973                int pkgUid = -1;
22974                try {
22975                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22976                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22977                } catch (RemoteException e) {
22978                }
22979                if (pkgUid == -1) {
22980                    throw new IllegalArgumentException("Unknown package name " + packageName);
22981                }
22982
22983                if (mLocalPowerManager != null) {
22984                    mLocalPowerManager.startUidChanges();
22985                }
22986                final int appId = UserHandle.getAppId(pkgUid);
22987                final int N = mActiveUids.size();
22988                for (int i=N-1; i>=0; i--) {
22989                    final UidRecord uidRec = mActiveUids.valueAt(i);
22990                    final long bgTime = uidRec.lastBackgroundTime;
22991                    if (bgTime > 0 && !uidRec.idle) {
22992                        if (UserHandle.getAppId(uidRec.uid) == appId) {
22993                            if (userId == UserHandle.USER_ALL ||
22994                                    userId == UserHandle.getUserId(uidRec.uid)) {
22995                                EventLogTags.writeAmUidIdle(uidRec.uid);
22996                                uidRec.idle = true;
22997                                uidRec.setIdle = true;
22998                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22999                                        + " from package " + packageName + " user " + userId);
23000                                doStopUidLocked(uidRec.uid, uidRec);
23001                            }
23002                        }
23003                    }
23004                }
23005            } finally {
23006                if (mLocalPowerManager != null) {
23007                    mLocalPowerManager.finishUidChanges();
23008                }
23009                Binder.restoreCallingIdentity(callingId);
23010            }
23011        }
23012    }
23013
23014    final void idleUids() {
23015        synchronized (this) {
23016            final int N = mActiveUids.size();
23017            if (N <= 0) {
23018                return;
23019            }
23020            final long nowElapsed = SystemClock.elapsedRealtime();
23021            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23022            long nextTime = 0;
23023            if (mLocalPowerManager != null) {
23024                mLocalPowerManager.startUidChanges();
23025            }
23026            for (int i=N-1; i>=0; i--) {
23027                final UidRecord uidRec = mActiveUids.valueAt(i);
23028                final long bgTime = uidRec.lastBackgroundTime;
23029                if (bgTime > 0 && !uidRec.idle) {
23030                    if (bgTime <= maxBgTime) {
23031                        EventLogTags.writeAmUidIdle(uidRec.uid);
23032                        uidRec.idle = true;
23033                        uidRec.setIdle = true;
23034                        doStopUidLocked(uidRec.uid, uidRec);
23035                    } else {
23036                        if (nextTime == 0 || nextTime > bgTime) {
23037                            nextTime = bgTime;
23038                        }
23039                    }
23040                }
23041            }
23042            if (mLocalPowerManager != null) {
23043                mLocalPowerManager.finishUidChanges();
23044            }
23045            if (nextTime > 0) {
23046                mHandler.removeMessages(IDLE_UIDS_MSG);
23047                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23048                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23049            }
23050        }
23051    }
23052
23053    /**
23054     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23055     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23056     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23057     */
23058    @VisibleForTesting
23059    @GuardedBy("this")
23060    void incrementProcStateSeqAndNotifyAppsLocked() {
23061        if (mWaitForNetworkTimeoutMs <= 0) {
23062            return;
23063        }
23064        // Used for identifying which uids need to block for network.
23065        ArrayList<Integer> blockingUids = null;
23066        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23067            final UidRecord uidRec = mActiveUids.valueAt(i);
23068            // If the network is not restricted for uid, then nothing to do here.
23069            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23070                continue;
23071            }
23072            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23073                continue;
23074            }
23075            // If process state is not changed, then there's nothing to do.
23076            if (uidRec.setProcState == uidRec.curProcState) {
23077                continue;
23078            }
23079            final int blockState = getBlockStateForUid(uidRec);
23080            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23081            // there's nothing the app needs to do in this scenario.
23082            if (blockState == NETWORK_STATE_NO_CHANGE) {
23083                continue;
23084            }
23085            synchronized (uidRec.networkStateLock) {
23086                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23087                if (blockState == NETWORK_STATE_BLOCK) {
23088                    if (blockingUids == null) {
23089                        blockingUids = new ArrayList<>();
23090                    }
23091                    blockingUids.add(uidRec.uid);
23092                } else {
23093                    if (DEBUG_NETWORK) {
23094                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23095                                + " threads for uid: " + uidRec);
23096                    }
23097                    if (uidRec.waitingForNetwork) {
23098                        uidRec.networkStateLock.notifyAll();
23099                    }
23100                }
23101            }
23102        }
23103
23104        // There are no uids that need to block, so nothing more to do.
23105        if (blockingUids == null) {
23106            return;
23107        }
23108
23109        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23110            final ProcessRecord app = mLruProcesses.get(i);
23111            if (!blockingUids.contains(app.uid)) {
23112                continue;
23113            }
23114            if (!app.killedByAm && app.thread != null) {
23115                final UidRecord uidRec = mActiveUids.get(app.uid);
23116                try {
23117                    if (DEBUG_NETWORK) {
23118                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23119                                + uidRec);
23120                    }
23121                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23122                } catch (RemoteException ignored) {
23123                }
23124            }
23125        }
23126    }
23127
23128    /**
23129     * Checks if the uid is coming from background to foreground or vice versa and returns
23130     * appropriate block state based on this.
23131     *
23132     * @return blockState based on whether the uid is coming from background to foreground or
23133     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23134     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23135     *         {@link #NETWORK_STATE_NO_CHANGE}.
23136     */
23137    @VisibleForTesting
23138    int getBlockStateForUid(UidRecord uidRec) {
23139        // Denotes whether uid's process state is currently allowed network access.
23140        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23141                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23142        // Denotes whether uid's process state was previously allowed network access.
23143        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23144                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23145
23146        // When the uid is coming to foreground, AMS should inform the app thread that it should
23147        // block for the network rules to get updated before launching an activity.
23148        if (!wasAllowed && isAllowed) {
23149            return NETWORK_STATE_BLOCK;
23150        }
23151        // When the uid is going to background, AMS should inform the app thread that if an
23152        // activity launch is blocked for the network rules to get updated, it should be unblocked.
23153        if (wasAllowed && !isAllowed) {
23154            return NETWORK_STATE_UNBLOCK;
23155        }
23156        return NETWORK_STATE_NO_CHANGE;
23157    }
23158
23159    final void runInBackgroundDisabled(int uid) {
23160        synchronized (this) {
23161            UidRecord uidRec = mActiveUids.get(uid);
23162            if (uidRec != null) {
23163                // This uid is actually running...  should it be considered background now?
23164                if (uidRec.idle) {
23165                    doStopUidLocked(uidRec.uid, uidRec);
23166                }
23167            } else {
23168                // This uid isn't actually running...  still send a report about it being "stopped".
23169                doStopUidLocked(uid, null);
23170            }
23171        }
23172    }
23173
23174    final void doStopUidLocked(int uid, final UidRecord uidRec) {
23175        mServices.stopInBackgroundLocked(uid);
23176        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23177    }
23178
23179    /**
23180     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23181     */
23182    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23183            long duration, String tag) {
23184        if (DEBUG_WHITELISTS) {
23185            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23186                    + targetUid + ", " + duration + ")");
23187        }
23188
23189        synchronized (mPidsSelfLocked) {
23190            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23191            if (pr == null) {
23192                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23193                        + callerPid);
23194                return;
23195            }
23196            if (!pr.whitelistManager) {
23197                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23198                        != PackageManager.PERMISSION_GRANTED) {
23199                    if (DEBUG_WHITELISTS) {
23200                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23201                                + ": pid " + callerPid + " is not allowed");
23202                    }
23203                    return;
23204                }
23205            }
23206        }
23207
23208        tempWhitelistUidLocked(targetUid, duration, tag);
23209    }
23210
23211    /**
23212     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23213     */
23214    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23215        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23216        setUidTempWhitelistStateLocked(targetUid, true);
23217        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23218    }
23219
23220    void pushTempWhitelist() {
23221        final int N;
23222        final PendingTempWhitelist[] list;
23223
23224        // First copy out the pending changes...  we need to leave them in the map for now,
23225        // in case someone needs to check what is coming up while we don't have the lock held.
23226        synchronized(this) {
23227            N = mPendingTempWhitelist.size();
23228            list = new PendingTempWhitelist[N];
23229            for (int i = 0; i < N; i++) {
23230                list[i] = mPendingTempWhitelist.valueAt(i);
23231            }
23232        }
23233
23234        // Now safely dispatch changes to device idle controller.
23235        for (int i = 0; i < N; i++) {
23236            PendingTempWhitelist ptw = list[i];
23237            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23238                    ptw.duration, true, ptw.tag);
23239        }
23240
23241        // And now we can safely remove them from the map.
23242        synchronized(this) {
23243            for (int i = 0; i < N; i++) {
23244                PendingTempWhitelist ptw = list[i];
23245                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23246                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23247                    mPendingTempWhitelist.removeAt(index);
23248                }
23249            }
23250        }
23251    }
23252
23253    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23254        boolean changed = false;
23255        for (int i=mActiveUids.size()-1; i>=0; i--) {
23256            final UidRecord uidRec = mActiveUids.valueAt(i);
23257            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23258                uidRec.curWhitelist = onWhitelist;
23259                changed = true;
23260            }
23261        }
23262        if (changed) {
23263            updateOomAdjLocked();
23264        }
23265    }
23266
23267    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23268        boolean changed = false;
23269        final UidRecord uidRec = mActiveUids.get(uid);
23270        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23271            uidRec.curWhitelist = onWhitelist;
23272            updateOomAdjLocked();
23273        }
23274    }
23275
23276    final void trimApplications() {
23277        synchronized (this) {
23278            int i;
23279
23280            // First remove any unused application processes whose package
23281            // has been removed.
23282            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23283                final ProcessRecord app = mRemovedProcesses.get(i);
23284                if (app.activities.size() == 0
23285                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
23286                    Slog.i(
23287                        TAG, "Exiting empty application process "
23288                        + app.toShortString() + " ("
23289                        + (app.thread != null ? app.thread.asBinder() : null)
23290                        + ")\n");
23291                    if (app.pid > 0 && app.pid != MY_PID) {
23292                        app.kill("empty", false);
23293                    } else {
23294                        try {
23295                            app.thread.scheduleExit();
23296                        } catch (Exception e) {
23297                            // Ignore exceptions.
23298                        }
23299                    }
23300                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23301                    mRemovedProcesses.remove(i);
23302
23303                    if (app.persistent) {
23304                        addAppLocked(app.info, null, false, null /* ABI override */);
23305                    }
23306                }
23307            }
23308
23309            // Now update the oom adj for all processes.
23310            updateOomAdjLocked();
23311        }
23312    }
23313
23314    /** This method sends the specified signal to each of the persistent apps */
23315    public void signalPersistentProcesses(int sig) throws RemoteException {
23316        if (sig != SIGNAL_USR1) {
23317            throw new SecurityException("Only SIGNAL_USR1 is allowed");
23318        }
23319
23320        synchronized (this) {
23321            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23322                    != PackageManager.PERMISSION_GRANTED) {
23323                throw new SecurityException("Requires permission "
23324                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23325            }
23326
23327            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23328                ProcessRecord r = mLruProcesses.get(i);
23329                if (r.thread != null && r.persistent) {
23330                    sendSignal(r.pid, sig);
23331                }
23332            }
23333        }
23334    }
23335
23336    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23337        if (proc == null || proc == mProfileProc) {
23338            proc = mProfileProc;
23339            profileType = mProfileType;
23340            clearProfilerLocked();
23341        }
23342        if (proc == null) {
23343            return;
23344        }
23345        try {
23346            proc.thread.profilerControl(false, null, profileType);
23347        } catch (RemoteException e) {
23348            throw new IllegalStateException("Process disappeared");
23349        }
23350    }
23351
23352    private void clearProfilerLocked() {
23353        if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23354            try {
23355                mProfilerInfo.profileFd.close();
23356            } catch (IOException e) {
23357            }
23358        }
23359        mProfileApp = null;
23360        mProfileProc = null;
23361        mProfilerInfo = null;
23362    }
23363
23364    public boolean profileControl(String process, int userId, boolean start,
23365            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23366
23367        try {
23368            synchronized (this) {
23369                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23370                // its own permission.
23371                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23372                        != PackageManager.PERMISSION_GRANTED) {
23373                    throw new SecurityException("Requires permission "
23374                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23375                }
23376
23377                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23378                    throw new IllegalArgumentException("null profile info or fd");
23379                }
23380
23381                ProcessRecord proc = null;
23382                if (process != null) {
23383                    proc = findProcessLocked(process, userId, "profileControl");
23384                }
23385
23386                if (start && (proc == null || proc.thread == null)) {
23387                    throw new IllegalArgumentException("Unknown process: " + process);
23388                }
23389
23390                if (start) {
23391                    stopProfilerLocked(null, 0);
23392                    setProfileApp(proc.info, proc.processName, profilerInfo);
23393                    mProfileProc = proc;
23394                    mProfileType = profileType;
23395                    ParcelFileDescriptor fd = profilerInfo.profileFd;
23396                    try {
23397                        fd = fd.dup();
23398                    } catch (IOException e) {
23399                        fd = null;
23400                    }
23401                    profilerInfo.profileFd = fd;
23402                    proc.thread.profilerControl(start, profilerInfo, profileType);
23403                    fd = null;
23404                    try {
23405                        mProfilerInfo.profileFd.close();
23406                    } catch (IOException e) {
23407                    }
23408                    mProfilerInfo.profileFd = null;
23409                } else {
23410                    stopProfilerLocked(proc, profileType);
23411                    if (profilerInfo != null && profilerInfo.profileFd != null) {
23412                        try {
23413                            profilerInfo.profileFd.close();
23414                        } catch (IOException e) {
23415                        }
23416                    }
23417                }
23418
23419                return true;
23420            }
23421        } catch (RemoteException e) {
23422            throw new IllegalStateException("Process disappeared");
23423        } finally {
23424            if (profilerInfo != null && profilerInfo.profileFd != null) {
23425                try {
23426                    profilerInfo.profileFd.close();
23427                } catch (IOException e) {
23428                }
23429            }
23430        }
23431    }
23432
23433    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23434        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23435                userId, true, ALLOW_FULL_ONLY, callName, null);
23436        ProcessRecord proc = null;
23437        try {
23438            int pid = Integer.parseInt(process);
23439            synchronized (mPidsSelfLocked) {
23440                proc = mPidsSelfLocked.get(pid);
23441            }
23442        } catch (NumberFormatException e) {
23443        }
23444
23445        if (proc == null) {
23446            ArrayMap<String, SparseArray<ProcessRecord>> all
23447                    = mProcessNames.getMap();
23448            SparseArray<ProcessRecord> procs = all.get(process);
23449            if (procs != null && procs.size() > 0) {
23450                proc = procs.valueAt(0);
23451                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23452                    for (int i=1; i<procs.size(); i++) {
23453                        ProcessRecord thisProc = procs.valueAt(i);
23454                        if (thisProc.userId == userId) {
23455                            proc = thisProc;
23456                            break;
23457                        }
23458                    }
23459                }
23460            }
23461        }
23462
23463        return proc;
23464    }
23465
23466    public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23467            boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23468
23469        try {
23470            synchronized (this) {
23471                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23472                // its own permission (same as profileControl).
23473                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23474                        != PackageManager.PERMISSION_GRANTED) {
23475                    throw new SecurityException("Requires permission "
23476                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23477                }
23478
23479                if (fd == null) {
23480                    throw new IllegalArgumentException("null fd");
23481                }
23482
23483                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23484                if (proc == null || proc.thread == null) {
23485                    throw new IllegalArgumentException("Unknown process: " + process);
23486                }
23487
23488                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23489                if (!isDebuggable) {
23490                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23491                        throw new SecurityException("Process not debuggable: " + proc);
23492                    }
23493                }
23494
23495                proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23496                fd = null;
23497                return true;
23498            }
23499        } catch (RemoteException e) {
23500            throw new IllegalStateException("Process disappeared");
23501        } finally {
23502            if (fd != null) {
23503                try {
23504                    fd.close();
23505                } catch (IOException e) {
23506                }
23507            }
23508        }
23509    }
23510
23511    @Override
23512    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23513            String reportPackage) {
23514        if (processName != null) {
23515            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23516                    "setDumpHeapDebugLimit()");
23517        } else {
23518            synchronized (mPidsSelfLocked) {
23519                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23520                if (proc == null) {
23521                    throw new SecurityException("No process found for calling pid "
23522                            + Binder.getCallingPid());
23523                }
23524                if (!Build.IS_DEBUGGABLE
23525                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23526                    throw new SecurityException("Not running a debuggable build");
23527                }
23528                processName = proc.processName;
23529                uid = proc.uid;
23530                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23531                    throw new SecurityException("Package " + reportPackage + " is not running in "
23532                            + proc);
23533                }
23534            }
23535        }
23536        synchronized (this) {
23537            if (maxMemSize > 0) {
23538                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23539            } else {
23540                if (uid != 0) {
23541                    mMemWatchProcesses.remove(processName, uid);
23542                } else {
23543                    mMemWatchProcesses.getMap().remove(processName);
23544                }
23545            }
23546        }
23547    }
23548
23549    @Override
23550    public void dumpHeapFinished(String path) {
23551        synchronized (this) {
23552            if (Binder.getCallingPid() != mMemWatchDumpPid) {
23553                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23554                        + " does not match last pid " + mMemWatchDumpPid);
23555                return;
23556            }
23557            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23558                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23559                        + " does not match last path " + mMemWatchDumpFile);
23560                return;
23561            }
23562            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23563            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23564
23565            // Forced gc to clean up the remnant hprof fd.
23566            Runtime.getRuntime().gc();
23567        }
23568    }
23569
23570    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23571    public void monitor() {
23572        synchronized (this) { }
23573    }
23574
23575    void onCoreSettingsChange(Bundle settings) {
23576        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23577            ProcessRecord processRecord = mLruProcesses.get(i);
23578            try {
23579                if (processRecord.thread != null) {
23580                    processRecord.thread.setCoreSettings(settings);
23581                }
23582            } catch (RemoteException re) {
23583                /* ignore */
23584            }
23585        }
23586    }
23587
23588    // Multi-user methods
23589
23590    /**
23591     * Start user, if its not already running, but don't bring it to foreground.
23592     */
23593    @Override
23594    public boolean startUserInBackground(final int userId) {
23595        return mUserController.startUser(userId, /* foreground */ false);
23596    }
23597
23598    @Override
23599    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23600        return mUserController.unlockUser(userId, token, secret, listener);
23601    }
23602
23603    @Override
23604    public boolean switchUser(final int targetUserId) {
23605        return mUserController.switchUser(targetUserId);
23606    }
23607
23608    @Override
23609    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23610        return mUserController.stopUser(userId, force, callback);
23611    }
23612
23613    @Override
23614    public UserInfo getCurrentUser() {
23615        return mUserController.getCurrentUser();
23616    }
23617
23618    String getStartedUserState(int userId) {
23619        final UserState userState = mUserController.getStartedUserState(userId);
23620        return UserState.stateToString(userState.state);
23621    }
23622
23623    @Override
23624    public boolean isUserRunning(int userId, int flags) {
23625        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23626                && checkCallingPermission(INTERACT_ACROSS_USERS)
23627                    != PackageManager.PERMISSION_GRANTED) {
23628            String msg = "Permission Denial: isUserRunning() from pid="
23629                    + Binder.getCallingPid()
23630                    + ", uid=" + Binder.getCallingUid()
23631                    + " requires " + INTERACT_ACROSS_USERS;
23632            Slog.w(TAG, msg);
23633            throw new SecurityException(msg);
23634        }
23635        return mUserController.isUserRunning(userId, flags);
23636    }
23637
23638    @Override
23639    public int[] getRunningUserIds() {
23640        if (checkCallingPermission(INTERACT_ACROSS_USERS)
23641                != PackageManager.PERMISSION_GRANTED) {
23642            String msg = "Permission Denial: isUserRunning() from pid="
23643                    + Binder.getCallingPid()
23644                    + ", uid=" + Binder.getCallingUid()
23645                    + " requires " + INTERACT_ACROSS_USERS;
23646            Slog.w(TAG, msg);
23647            throw new SecurityException(msg);
23648        }
23649        return mUserController.getStartedUserArray();
23650    }
23651
23652    @Override
23653    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23654        mUserController.registerUserSwitchObserver(observer, name);
23655    }
23656
23657    @Override
23658    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23659        mUserController.unregisterUserSwitchObserver(observer);
23660    }
23661
23662    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23663        if (info == null) return null;
23664        ApplicationInfo newInfo = new ApplicationInfo(info);
23665        newInfo.initForUser(userId);
23666        return newInfo;
23667    }
23668
23669    public boolean isUserStopped(int userId) {
23670        return mUserController.getStartedUserState(userId) == null;
23671    }
23672
23673    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23674        if (aInfo == null
23675                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23676            return aInfo;
23677        }
23678
23679        ActivityInfo info = new ActivityInfo(aInfo);
23680        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23681        return info;
23682    }
23683
23684    private boolean processSanityChecksLocked(ProcessRecord process) {
23685        if (process == null || process.thread == null) {
23686            return false;
23687        }
23688
23689        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23690        if (!isDebuggable) {
23691            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23692                return false;
23693            }
23694        }
23695
23696        return true;
23697    }
23698
23699    public boolean startBinderTracking() throws RemoteException {
23700        synchronized (this) {
23701            mBinderTransactionTrackingEnabled = true;
23702            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23703            // permission (same as profileControl).
23704            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23705                    != PackageManager.PERMISSION_GRANTED) {
23706                throw new SecurityException("Requires permission "
23707                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23708            }
23709
23710            for (int i = 0; i < mLruProcesses.size(); i++) {
23711                ProcessRecord process = mLruProcesses.get(i);
23712                if (!processSanityChecksLocked(process)) {
23713                    continue;
23714                }
23715                try {
23716                    process.thread.startBinderTracking();
23717                } catch (RemoteException e) {
23718                    Log.v(TAG, "Process disappared");
23719                }
23720            }
23721            return true;
23722        }
23723    }
23724
23725    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23726        try {
23727            synchronized (this) {
23728                mBinderTransactionTrackingEnabled = false;
23729                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23730                // permission (same as profileControl).
23731                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23732                        != PackageManager.PERMISSION_GRANTED) {
23733                    throw new SecurityException("Requires permission "
23734                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23735                }
23736
23737                if (fd == null) {
23738                    throw new IllegalArgumentException("null fd");
23739                }
23740
23741                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23742                pw.println("Binder transaction traces for all processes.\n");
23743                for (ProcessRecord process : mLruProcesses) {
23744                    if (!processSanityChecksLocked(process)) {
23745                        continue;
23746                    }
23747
23748                    pw.println("Traces for process: " + process.processName);
23749                    pw.flush();
23750                    try {
23751                        TransferPipe tp = new TransferPipe();
23752                        try {
23753                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23754                            tp.go(fd.getFileDescriptor());
23755                        } finally {
23756                            tp.kill();
23757                        }
23758                    } catch (IOException e) {
23759                        pw.println("Failure while dumping IPC traces from " + process +
23760                                ".  Exception: " + e);
23761                        pw.flush();
23762                    } catch (RemoteException e) {
23763                        pw.println("Got a RemoteException while dumping IPC traces from " +
23764                                process + ".  Exception: " + e);
23765                        pw.flush();
23766                    }
23767                }
23768                fd = null;
23769                return true;
23770            }
23771        } finally {
23772            if (fd != null) {
23773                try {
23774                    fd.close();
23775                } catch (IOException e) {
23776                }
23777            }
23778        }
23779    }
23780
23781    @VisibleForTesting
23782    final class LocalService extends ActivityManagerInternal {
23783        @Override
23784        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23785                int targetUserId) {
23786            synchronized (ActivityManagerService.this) {
23787                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23788                        targetPkg, intent, null, targetUserId);
23789            }
23790        }
23791
23792        @Override
23793        public String checkContentProviderAccess(String authority, int userId) {
23794            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23795        }
23796
23797        @Override
23798        public void onWakefulnessChanged(int wakefulness) {
23799            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23800        }
23801
23802        @Override
23803        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23804                String processName, String abiOverride, int uid, Runnable crashHandler) {
23805            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23806                    processName, abiOverride, uid, crashHandler);
23807        }
23808
23809        @Override
23810        public SleepToken acquireSleepToken(String tag, int displayId) {
23811            Preconditions.checkNotNull(tag);
23812            return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23813        }
23814
23815        @Override
23816        public ComponentName getHomeActivityForUser(int userId) {
23817            synchronized (ActivityManagerService.this) {
23818                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23819                return homeActivity == null ? null : homeActivity.realActivity;
23820            }
23821        }
23822
23823        @Override
23824        public void onUserRemoved(int userId) {
23825            synchronized (ActivityManagerService.this) {
23826                ActivityManagerService.this.onUserStoppedLocked(userId);
23827            }
23828            mBatteryStatsService.onUserRemoved(userId);
23829        }
23830
23831        @Override
23832        public void onLocalVoiceInteractionStarted(IBinder activity,
23833                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23834            synchronized (ActivityManagerService.this) {
23835                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23836                        voiceSession, voiceInteractor);
23837            }
23838        }
23839
23840        @Override
23841        public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23842            synchronized (ActivityManagerService.this) {
23843                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23844                        reasons, timestamp);
23845            }
23846        }
23847
23848        @Override
23849        public void notifyAppTransitionFinished() {
23850            synchronized (ActivityManagerService.this) {
23851                mStackSupervisor.notifyAppTransitionDone();
23852            }
23853        }
23854
23855        @Override
23856        public void notifyAppTransitionCancelled() {
23857            synchronized (ActivityManagerService.this) {
23858                mStackSupervisor.notifyAppTransitionDone();
23859            }
23860        }
23861
23862        @Override
23863        public List<IBinder> getTopVisibleActivities() {
23864            synchronized (ActivityManagerService.this) {
23865                return mStackSupervisor.getTopVisibleActivities();
23866            }
23867        }
23868
23869        @Override
23870        public void notifyDockedStackMinimizedChanged(boolean minimized) {
23871            synchronized (ActivityManagerService.this) {
23872                mStackSupervisor.setDockedStackMinimized(minimized);
23873            }
23874        }
23875
23876        @Override
23877        public void killForegroundAppsForUser(int userHandle) {
23878            synchronized (ActivityManagerService.this) {
23879                final ArrayList<ProcessRecord> procs = new ArrayList<>();
23880                final int NP = mProcessNames.getMap().size();
23881                for (int ip = 0; ip < NP; ip++) {
23882                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23883                    final int NA = apps.size();
23884                    for (int ia = 0; ia < NA; ia++) {
23885                        final ProcessRecord app = apps.valueAt(ia);
23886                        if (app.persistent) {
23887                            // We don't kill persistent processes.
23888                            continue;
23889                        }
23890                        if (app.removed) {
23891                            procs.add(app);
23892                        } else if (app.userId == userHandle && app.foregroundActivities) {
23893                            app.removed = true;
23894                            procs.add(app);
23895                        }
23896                    }
23897                }
23898
23899                final int N = procs.size();
23900                for (int i = 0; i < N; i++) {
23901                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
23902                }
23903            }
23904        }
23905
23906        @Override
23907        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
23908                long duration) {
23909            if (!(target instanceof PendingIntentRecord)) {
23910                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23911                return;
23912            }
23913            synchronized (ActivityManagerService.this) {
23914                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
23915            }
23916        }
23917
23918        @Override
23919        public void setDeviceIdleWhitelist(int[] appids) {
23920            synchronized (ActivityManagerService.this) {
23921                mDeviceIdleWhitelist = appids;
23922            }
23923        }
23924
23925        @Override
23926        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23927            synchronized (ActivityManagerService.this) {
23928                mDeviceIdleTempWhitelist = appids;
23929                setAppIdTempWhitelistStateLocked(changingAppId, adding);
23930            }
23931        }
23932
23933        @Override
23934        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23935                int userId) {
23936            Preconditions.checkNotNull(values, "Configuration must not be null");
23937            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23938            synchronized (ActivityManagerService.this) {
23939                updateConfigurationLocked(values, null, false, true, userId,
23940                        false /* deferResume */);
23941            }
23942        }
23943
23944        @Override
23945        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23946                Bundle bOptions) {
23947            Preconditions.checkNotNull(intents, "intents");
23948            final String[] resolvedTypes = new String[intents.length];
23949            for (int i = 0; i < intents.length; i++) {
23950                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23951            }
23952
23953            // UID of the package on user userId.
23954            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23955            // packageUid may not be initialized.
23956            int packageUid = 0;
23957            try {
23958                packageUid = AppGlobals.getPackageManager().getPackageUid(
23959                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23960            } catch (RemoteException e) {
23961                // Shouldn't happen.
23962            }
23963
23964            synchronized (ActivityManagerService.this) {
23965                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23966                        /*resultTo*/ null, bOptions, userId);
23967            }
23968        }
23969
23970        @Override
23971        public int getUidProcessState(int uid) {
23972            return getUidState(uid);
23973        }
23974
23975        @Override
23976        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23977            synchronized (ActivityManagerService.this) {
23978
23979                // We might change the visibilities here, so prepare an empty app transition which
23980                // might be overridden later if we actually change visibilities.
23981                final boolean wasTransitionSet =
23982                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
23983                if (!wasTransitionSet) {
23984                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
23985                            false /* alwaysKeepCurrent */);
23986                }
23987                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23988
23989                // If there was a transition set already we don't want to interfere with it as we
23990                // might be starting it too early.
23991                if (!wasTransitionSet) {
23992                    mWindowManager.executeAppTransition();
23993                }
23994            }
23995            if (callback != null) {
23996                callback.run();
23997            }
23998        }
23999
24000        @Override
24001        public boolean isSystemReady() {
24002            // no need to synchronize(this) just to read & return the value
24003            return mSystemReady;
24004        }
24005
24006        @Override
24007        public void notifyKeyguardTrustedChanged() {
24008            synchronized (ActivityManagerService.this) {
24009                if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24010                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24011                }
24012            }
24013        }
24014
24015        /**
24016         * Sets if the given pid has an overlay UI or not.
24017         *
24018         * @param pid The pid we are setting overlay UI for.
24019         * @param hasOverlayUi True if the process has overlay UI.
24020         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24021         */
24022        @Override
24023        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24024            synchronized (ActivityManagerService.this) {
24025                final ProcessRecord pr;
24026                synchronized (mPidsSelfLocked) {
24027                    pr = mPidsSelfLocked.get(pid);
24028                    if (pr == null) {
24029                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24030                        return;
24031                    }
24032                }
24033                if (pr.hasOverlayUi == hasOverlayUi) {
24034                    return;
24035                }
24036                pr.hasOverlayUi = hasOverlayUi;
24037                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24038                updateOomAdjLocked(pr, true);
24039            }
24040        }
24041
24042        /**
24043         * Called after the network policy rules are updated by
24044         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24045         * and {@param procStateSeq}.
24046         */
24047        @Override
24048        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24049            if (DEBUG_NETWORK) {
24050                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24051                        + uid + " seq: " + procStateSeq);
24052            }
24053            UidRecord record;
24054            synchronized (ActivityManagerService.this) {
24055                record = mActiveUids.get(uid);
24056                if (record == null) {
24057                    if (DEBUG_NETWORK) {
24058                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24059                                + " procStateSeq: " + procStateSeq);
24060                    }
24061                    return;
24062                }
24063            }
24064            synchronized (record.networkStateLock) {
24065                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24066                    if (DEBUG_NETWORK) {
24067                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24068                                + " been handled for uid: " + uid);
24069                    }
24070                    return;
24071                }
24072                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24073                if (record.curProcStateSeq > procStateSeq) {
24074                    if (DEBUG_NETWORK) {
24075                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24076                                + ", curProcstateSeq: " + record.curProcStateSeq
24077                                + ", procStateSeq: " + procStateSeq);
24078                    }
24079                    return;
24080                }
24081                if (record.waitingForNetwork) {
24082                    if (DEBUG_NETWORK) {
24083                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24084                                + ", procStateSeq: " + procStateSeq);
24085                    }
24086                    record.networkStateLock.notifyAll();
24087                }
24088            }
24089        }
24090
24091        /**
24092         * Called after virtual display Id is updated by
24093         * {@link com.android.server.vr.Vr2dDisplay} with a specific
24094         * {@param vrVr2dDisplayId}.
24095         */
24096        @Override
24097        public void setVr2dDisplayId(int vr2dDisplayId) {
24098            if (DEBUG_STACK) {
24099                Slog.d(TAG, "setVr2dDisplayId called for: " +
24100                        vr2dDisplayId);
24101            }
24102            synchronized (ActivityManagerService.this) {
24103                mVr2dDisplayId = vr2dDisplayId;
24104            }
24105        }
24106
24107        @Override
24108        public void saveANRState(String reason) {
24109            synchronized (ActivityManagerService.this) {
24110                final StringWriter sw = new StringWriter();
24111                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24112                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24113                if (reason != null) {
24114                    pw.println("  Reason: " + reason);
24115                }
24116                pw.println();
24117                mActivityStarter.dump(pw, "  ", null);
24118                pw.println();
24119                pw.println("-------------------------------------------------------------------------------");
24120                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24121                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24122                        "" /* header */);
24123                pw.println();
24124                pw.close();
24125
24126                mLastANRState = sw.toString();
24127            }
24128        }
24129
24130        @Override
24131        public void clearSavedANRState() {
24132            synchronized (ActivityManagerService.this) {
24133                mLastANRState = null;
24134            }
24135        }
24136
24137        @Override
24138        public void setFocusedActivity(IBinder token) {
24139            synchronized (ActivityManagerService.this) {
24140                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24141                if (r == null) {
24142                    throw new IllegalArgumentException(
24143                            "setFocusedActivity: No activity record matching token=" + token);
24144                }
24145                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24146                        r, "setFocusedActivity")) {
24147                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
24148                }
24149            }
24150        }
24151    }
24152
24153    /**
24154     * Called by app main thread to wait for the network policy rules to get updated.
24155     *
24156     * @param procStateSeq The sequence number indicating the process state change that the main
24157     *                     thread is interested in.
24158     */
24159    @Override
24160    public void waitForNetworkStateUpdate(long procStateSeq) {
24161        final int callingUid = Binder.getCallingUid();
24162        if (DEBUG_NETWORK) {
24163            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24164        }
24165        UidRecord record;
24166        synchronized (this) {
24167            record = mActiveUids.get(callingUid);
24168            if (record == null) {
24169                return;
24170            }
24171        }
24172        synchronized (record.networkStateLock) {
24173            if (record.lastDispatchedProcStateSeq < procStateSeq) {
24174                if (DEBUG_NETWORK) {
24175                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24176                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24177                            + " lastProcStateSeqDispatchedToObservers: "
24178                            + record.lastDispatchedProcStateSeq);
24179                }
24180                return;
24181            }
24182            if (record.curProcStateSeq > procStateSeq) {
24183                if (DEBUG_NETWORK) {
24184                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24185                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24186                            + ", procStateSeq: " + procStateSeq);
24187                }
24188                return;
24189            }
24190            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24191                if (DEBUG_NETWORK) {
24192                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24193                            + procStateSeq + ", so no need to wait. Uid: "
24194                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24195                            + record.lastNetworkUpdatedProcStateSeq);
24196                }
24197                return;
24198            }
24199            try {
24200                if (DEBUG_NETWORK) {
24201                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24202                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24203                }
24204                final long startTime = SystemClock.uptimeMillis();
24205                record.waitingForNetwork = true;
24206                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24207                record.waitingForNetwork = false;
24208                final long totalTime = SystemClock.uptimeMillis() - startTime;
24209                if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24210                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24211                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24212                            + procStateSeq + " UidRec: " + record
24213                            + " validateUidRec: " + mValidateUids.get(callingUid));
24214                }
24215            } catch (InterruptedException e) {
24216                Thread.currentThread().interrupt();
24217            }
24218        }
24219    }
24220
24221    public void waitForBroadcastIdle(PrintWriter pw) {
24222        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24223        while (true) {
24224            boolean idle = true;
24225            synchronized (this) {
24226                for (BroadcastQueue queue : mBroadcastQueues) {
24227                    if (!queue.isIdle()) {
24228                        final String msg = "Waiting for queue " + queue + " to become idle...";
24229                        pw.println(msg);
24230                        pw.flush();
24231                        Slog.v(TAG, msg);
24232                        idle = false;
24233                    }
24234                }
24235            }
24236
24237            if (idle) {
24238                final String msg = "All broadcast queues are idle!";
24239                pw.println(msg);
24240                pw.flush();
24241                Slog.v(TAG, msg);
24242                return;
24243            } else {
24244                SystemClock.sleep(1000);
24245            }
24246        }
24247    }
24248
24249    /**
24250     * Return the user id of the last resumed activity.
24251     */
24252    @Override
24253    public @UserIdInt int getLastResumedActivityUserId() {
24254        enforceCallingPermission(
24255                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24256        synchronized (this) {
24257            if (mLastResumedActivity == null) {
24258                return mUserController.getCurrentUserId();
24259            }
24260            return mLastResumedActivity.userId;
24261        }
24262    }
24263
24264    /**
24265     * Kill processes for the user with id userId and that depend on the package named packageName
24266     */
24267    @Override
24268    public void killPackageDependents(String packageName, int userId) {
24269        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24270        if (packageName == null) {
24271            throw new NullPointerException(
24272                    "Cannot kill the dependents of a package without its name.");
24273        }
24274
24275        long callingId = Binder.clearCallingIdentity();
24276        IPackageManager pm = AppGlobals.getPackageManager();
24277        int pkgUid = -1;
24278        try {
24279            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24280        } catch (RemoteException e) {
24281        }
24282        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24283            throw new IllegalArgumentException(
24284                    "Cannot kill dependents of non-existing package " + packageName);
24285        }
24286        try {
24287            synchronized(this) {
24288                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24289                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24290                        "dep: " + packageName);
24291            }
24292        } finally {
24293            Binder.restoreCallingIdentity(callingId);
24294        }
24295    }
24296
24297    @Override
24298    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24299            throws RemoteException {
24300        final long callingId = Binder.clearCallingIdentity();
24301        try {
24302            mKeyguardController.dismissKeyguard(token, callback);
24303        } finally {
24304            Binder.restoreCallingIdentity(callingId);
24305        }
24306    }
24307
24308    @Override
24309    public int restartUserInBackground(final int userId) {
24310        return mUserController.restartUser(userId, /* foreground */ false);
24311    }
24312
24313    @Override
24314    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24315        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24316                "scheduleApplicationInfoChanged()");
24317
24318        synchronized (this) {
24319            final long origId = Binder.clearCallingIdentity();
24320            try {
24321                updateApplicationInfoLocked(packageNames, userId);
24322            } finally {
24323                Binder.restoreCallingIdentity(origId);
24324            }
24325        }
24326    }
24327
24328    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24329        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24330        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24331            final ProcessRecord app = mLruProcesses.get(i);
24332            if (app.thread == null) {
24333                continue;
24334            }
24335
24336            if (userId != UserHandle.USER_ALL && app.userId != userId) {
24337                continue;
24338            }
24339
24340            final int packageCount = app.pkgList.size();
24341            for (int j = 0; j < packageCount; j++) {
24342                final String packageName = app.pkgList.keyAt(j);
24343                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24344                    try {
24345                        final ApplicationInfo ai = AppGlobals.getPackageManager()
24346                                .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24347                        if (ai != null) {
24348                            app.thread.scheduleApplicationInfoChanged(ai);
24349                        }
24350                    } catch (RemoteException e) {
24351                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24352                                    packageName, app));
24353                    }
24354                }
24355            }
24356        }
24357    }
24358
24359    /**
24360     * Attach an agent to the specified process (proces name or PID)
24361     */
24362    public void attachAgent(String process, String path) {
24363        try {
24364            synchronized (this) {
24365                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24366                if (proc == null || proc.thread == null) {
24367                    throw new IllegalArgumentException("Unknown process: " + process);
24368                }
24369
24370                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24371                if (!isDebuggable) {
24372                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24373                        throw new SecurityException("Process not debuggable: " + proc);
24374                    }
24375                }
24376
24377                proc.thread.attachAgent(path);
24378            }
24379        } catch (RemoteException e) {
24380            throw new IllegalStateException("Process disappeared");
24381        }
24382    }
24383
24384    @VisibleForTesting
24385    public static class Injector {
24386        private NetworkManagementInternal mNmi;
24387
24388        public Context getContext() {
24389            return null;
24390        }
24391
24392        public AppOpsService getAppOpsService(File file, Handler handler) {
24393            return new AppOpsService(file, handler);
24394        }
24395
24396        public Handler getUiHandler(ActivityManagerService service) {
24397            return service.new UiHandler();
24398        }
24399
24400        public boolean isNetworkRestrictedForUid(int uid) {
24401            if (ensureHasNetworkManagementInternal()) {
24402                return mNmi.isNetworkRestrictedForUid(uid);
24403            }
24404            return false;
24405        }
24406
24407        private boolean ensureHasNetworkManagementInternal() {
24408            if (mNmi == null) {
24409                mNmi = LocalServices.getService(NetworkManagementInternal.class);
24410            }
24411            return mNmi != null;
24412        }
24413    }
24414
24415    @Override
24416    public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24417            throws RemoteException {
24418        synchronized (this) {
24419            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24420            if (r == null) {
24421                return;
24422            }
24423            final long origId = Binder.clearCallingIdentity();
24424            try {
24425                r.setShowWhenLocked(showWhenLocked);
24426            } finally {
24427                Binder.restoreCallingIdentity(origId);
24428            }
24429        }
24430    }
24431
24432    @Override
24433    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24434        synchronized (this) {
24435            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24436            if (r == null) {
24437                return;
24438            }
24439            final long origId = Binder.clearCallingIdentity();
24440            try {
24441                r.setTurnScreenOn(turnScreenOn);
24442            } finally {
24443                Binder.restoreCallingIdentity(origId);
24444            }
24445        }
24446    }
24447}
24448