ActivityManagerService.java revision 76f7a40780f680c452c909f0ede55e4ab5f1c7b5
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.Manifest.permission;
67import android.annotation.NonNull;
68import android.annotation.UserIdInt;
69import android.app.Activity;
70import android.app.ActivityManager;
71import android.app.ActivityManager.RunningTaskInfo;
72import android.app.ActivityManager.StackId;
73import android.app.ActivityManager.StackInfo;
74import android.app.ActivityManager.TaskThumbnailInfo;
75import android.app.ActivityManagerInternal;
76import android.app.ActivityManagerInternal.SleepToken;
77import android.app.ActivityManagerNative;
78import android.app.ActivityOptions;
79import android.app.ActivityThread;
80import android.app.AlertDialog;
81import android.app.AppGlobals;
82import android.app.AppOpsManager;
83import android.app.ApplicationErrorReport;
84import android.app.ApplicationThreadNative;
85import android.app.BroadcastOptions;
86import android.app.Dialog;
87import android.app.IActivityContainer;
88import android.app.IActivityContainerCallback;
89import android.app.IActivityController;
90import android.app.IAppTask;
91import android.app.IApplicationThread;
92import android.app.IInstrumentationWatcher;
93import android.app.INotificationManager;
94import android.app.IProcessObserver;
95import android.app.IServiceConnection;
96import android.app.IStopUserCallback;
97import android.app.ITaskStackListener;
98import android.app.IUiAutomationConnection;
99import android.app.IUidObserver;
100import android.app.IUserSwitchObserver;
101import android.app.Instrumentation;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.ProfilerInfo;
106import android.app.admin.DevicePolicyManager;
107import android.app.assist.AssistContent;
108import android.app.assist.AssistStructure;
109import android.app.backup.IBackupManager;
110import android.app.usage.UsageEvents;
111import android.app.usage.UsageStatsManagerInternal;
112import android.appwidget.AppWidgetManager;
113import android.content.ActivityNotFoundException;
114import android.content.BroadcastReceiver;
115import android.content.ClipData;
116import android.content.ComponentCallbacks2;
117import android.content.ComponentName;
118import android.content.ContentProvider;
119import android.content.ContentResolver;
120import android.content.Context;
121import android.content.DialogInterface;
122import android.content.IContentProvider;
123import android.content.IIntentReceiver;
124import android.content.IIntentSender;
125import android.content.Intent;
126import android.content.IntentFilter;
127import android.content.IntentSender;
128import android.content.pm.ActivityInfo;
129import android.content.pm.ApplicationInfo;
130import android.content.pm.ConfigurationInfo;
131import android.content.pm.IPackageDataObserver;
132import android.content.pm.IPackageManager;
133import android.content.pm.InstrumentationInfo;
134import android.content.pm.PackageInfo;
135import android.content.pm.PackageManager;
136import android.content.pm.PackageManager.NameNotFoundException;
137import android.content.pm.PackageManagerInternal;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.PathPermission;
140import android.content.pm.PermissionInfo;
141import android.content.pm.ProviderInfo;
142import android.content.pm.ResolveInfo;
143import android.content.pm.ServiceInfo;
144import android.content.pm.UserInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.content.res.Resources;
148import android.database.ContentObserver;
149import android.graphics.Bitmap;
150import android.graphics.Point;
151import android.graphics.Rect;
152import android.location.LocationManager;
153import android.net.Proxy;
154import android.net.ProxyInfo;
155import android.net.Uri;
156import android.os.BatteryStats;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IProcessInfoService;
170import android.os.IProgressListener;
171import android.os.LocaleList;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.PersistableBundle;
177import android.os.PowerManager;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.ResultReceiver;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.Trace;
188import android.os.TransactionTooLargeException;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.os.WorkSource;
193import android.os.storage.IMountService;
194import android.os.storage.MountServiceInternal;
195import android.os.storage.StorageManager;
196import android.provider.Settings;
197import android.service.voice.IVoiceInteractionSession;
198import android.service.voice.VoiceInteractionManagerInternal;
199import android.service.voice.VoiceInteractionSession;
200import android.telecom.TelecomManager;
201import android.text.format.DateUtils;
202import android.text.format.Time;
203import android.text.style.SuggestionSpan;
204import android.util.ArrayMap;
205import android.util.ArraySet;
206import android.util.AtomicFile;
207import android.util.DebugUtils;
208import android.util.DisplayMetrics;
209import android.util.EventLog;
210import android.util.Log;
211import android.util.Pair;
212import android.util.PrintWriterPrinter;
213import android.util.Slog;
214import android.util.SparseArray;
215import android.util.TimeUtils;
216import android.util.Xml;
217import android.view.Display;
218import android.view.Gravity;
219import android.view.LayoutInflater;
220import android.view.View;
221import android.view.WindowManager;
222
223import java.io.File;
224import java.io.FileDescriptor;
225import java.io.FileInputStream;
226import java.io.FileNotFoundException;
227import java.io.FileOutputStream;
228import java.io.IOException;
229import java.io.InputStreamReader;
230import java.io.PrintWriter;
231import java.io.StringWriter;
232import java.lang.ref.WeakReference;
233import java.nio.charset.StandardCharsets;
234import java.util.ArrayList;
235import java.util.Arrays;
236import java.util.Collections;
237import java.util.Comparator;
238import java.util.HashMap;
239import java.util.HashSet;
240import java.util.Iterator;
241import java.util.List;
242import java.util.Locale;
243import java.util.Map;
244import java.util.Objects;
245import java.util.Set;
246import java.util.concurrent.atomic.AtomicBoolean;
247import java.util.concurrent.atomic.AtomicLong;
248
249import dalvik.system.VMRuntime;
250
251import libcore.io.IoUtils;
252import libcore.util.EmptyArray;
253
254import static android.Manifest.permission.INTERACT_ACROSS_USERS;
255import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
256import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
257import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
258import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
259import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
260import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
261import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
263import static android.app.ActivityManager.StackId.HOME_STACK_ID;
264import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
265import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
266import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
267import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
268import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
269import static android.content.pm.PackageManager.GET_PROVIDERS;
270import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
272import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
273import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
274import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
275import static android.content.pm.PackageManager.PERMISSION_GRANTED;
276import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
277import static android.os.Process.PROC_CHAR;
278import static android.os.Process.PROC_OUT_LONG;
279import static android.os.Process.PROC_PARENS;
280import static android.os.Process.PROC_SPACE_TERM;
281import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
282import static android.provider.Settings.Global.DEBUG_APP;
283import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
284import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
285import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
286import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
287import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
288import static android.provider.Settings.System.FONT_SCALE;
289import static com.android.internal.util.XmlUtils.readBooleanAttribute;
290import static com.android.internal.util.XmlUtils.readIntAttribute;
291import static com.android.internal.util.XmlUtils.readLongAttribute;
292import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
293import static com.android.internal.util.XmlUtils.writeIntAttribute;
294import static com.android.internal.util.XmlUtils.writeLongAttribute;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
352import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
353import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
354import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
355import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
356import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
357import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
358import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
359import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
360import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
361import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
362import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
363import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
364import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
365import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
366import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
367import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
368import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
369import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
370import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
371import static org.xmlpull.v1.XmlPullParser.START_TAG;
372
373public final class ActivityManagerService extends ActivityManagerNative
374        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
375
376    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
377    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
378    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
379    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
380    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
381    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
382    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
383    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
384    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
385    private static final String TAG_LRU = TAG + POSTFIX_LRU;
386    private static final String TAG_MU = TAG + POSTFIX_MU;
387    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
388    private static final String TAG_POWER = TAG + POSTFIX_POWER;
389    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
390    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
391    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
392    private static final String TAG_PSS = TAG + POSTFIX_PSS;
393    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
394    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
395    private static final String TAG_STACK = TAG + POSTFIX_STACK;
396    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
397    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
398    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
399    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
400    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
401
402    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
403    // here so that while the job scheduler can depend on AMS, the other way around
404    // need not be the case.
405    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
406
407    /** Control over CPU and battery monitoring */
408    // write battery stats every 30 minutes.
409    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
410    static final boolean MONITOR_CPU_USAGE = true;
411    // don't sample cpu less than every 5 seconds.
412    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
413    // wait possibly forever for next cpu sample.
414    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
415    static final boolean MONITOR_THREAD_CPU_USAGE = false;
416
417    // The flags that are set for all calls we make to the package manager.
418    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
419
420    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
421
422    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
423
424    // Amount of time after a call to stopAppSwitches() during which we will
425    // prevent further untrusted switches from happening.
426    static final long APP_SWITCH_DELAY_TIME = 5*1000;
427
428    // How long we wait for a launched process to attach to the activity manager
429    // before we decide it's never going to come up for real.
430    static final int PROC_START_TIMEOUT = 10*1000;
431    // How long we wait for an attached process to publish its content providers
432    // before we decide it must be hung.
433    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
434
435    // How long we will retain processes hosting content providers in the "last activity"
436    // state before allowing them to drop down to the regular cached LRU list.  This is
437    // to avoid thrashing of provider processes under low memory situations.
438    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
439
440    // How long we wait for a launched process to attach to the activity manager
441    // before we decide it's never going to come up for real, when the process was
442    // started with a wrapper for instrumentation (such as Valgrind) because it
443    // could take much longer than usual.
444    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
445
446    // How long to wait after going idle before forcing apps to GC.
447    static final int GC_TIMEOUT = 5*1000;
448
449    // The minimum amount of time between successive GC requests for a process.
450    static final int GC_MIN_INTERVAL = 60*1000;
451
452    // The minimum amount of time between successive PSS requests for a process.
453    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
454
455    // The minimum amount of time between successive PSS requests for a process
456    // when the request is due to the memory state being lowered.
457    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
458
459    // The rate at which we check for apps using excessive power -- 15 mins.
460    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
461
462    // The minimum sample duration we will allow before deciding we have
463    // enough data on wake locks to start killing things.
464    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
465
466    // The minimum sample duration we will allow before deciding we have
467    // enough data on CPU usage to start killing things.
468    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
469
470    // How long we allow a receiver to run before giving up on it.
471    static final int BROADCAST_FG_TIMEOUT = 10*1000;
472    static final int BROADCAST_BG_TIMEOUT = 60*1000;
473
474    // How long we wait until we timeout on key dispatching.
475    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
476
477    // How long we wait until we timeout on key dispatching during instrumentation.
478    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
479
480    // This is the amount of time an app needs to be running a foreground service before
481    // we will consider it to be doing interaction for usage stats.
482    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
483
484    // Maximum amount of time we will allow to elapse before re-reporting usage stats
485    // interaction with foreground processes.
486    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
487
488    // This is the amount of time we allow an app to settle after it goes into the background,
489    // before we start restricting what it can do.
490    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
491
492    // How long to wait in getAssistContextExtras for the activity and foreground services
493    // to respond with the result.
494    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
495
496    // How long top wait when going through the modern assist (which doesn't need to block
497    // on getting this result before starting to launch its UI).
498    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
499
500    // Maximum number of persisted Uri grants a package is allowed
501    static final int MAX_PERSISTED_URI_GRANTS = 128;
502
503    static final int MY_PID = Process.myPid();
504
505    static final String[] EMPTY_STRING_ARRAY = new String[0];
506
507    // How many bytes to write into the dropbox log before truncating
508    static final int DROPBOX_MAX_SIZE = 192 * 1024;
509    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
510    // as one line, but close enough for now.
511    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
512
513    // Access modes for handleIncomingUser.
514    static final int ALLOW_NON_FULL = 0;
515    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
516    static final int ALLOW_FULL_ONLY = 2;
517
518    // Delay in notifying task stack change listeners (in millis)
519    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
520
521    // Necessary ApplicationInfo flags to mark an app as persistent
522    private static final int PERSISTENT_MASK =
523            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
524
525    // Intent sent when remote bugreport collection has been completed
526    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
527            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
528
529    // Delay to disable app launch boost
530    static final int APP_BOOST_MESSAGE_DELAY = 3000;
531    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
532    static final int APP_BOOST_TIMEOUT = 2500;
533
534    // Used to indicate that a task is removed it should also be removed from recents.
535    private static final boolean REMOVE_FROM_RECENTS = true;
536    // Used to indicate that an app transition should be animated.
537    static final boolean ANIMATE = true;
538
539    // Determines whether to take full screen screenshots
540    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
541    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
542
543    private static native int nativeMigrateToBoost();
544    private static native int nativeMigrateFromBoost();
545    private boolean mIsBoosted = false;
546    private long mBoostStartTime = 0;
547
548    /** All system services */
549    SystemServiceManager mSystemServiceManager;
550
551    private Installer mInstaller;
552
553    /** Run all ActivityStacks through this */
554    final ActivityStackSupervisor mStackSupervisor;
555
556    final ActivityStarter mActivityStarter;
557
558    /** Task stack change listeners. */
559    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
560            new RemoteCallbackList<ITaskStackListener>();
561
562    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
563
564    public IntentFirewall mIntentFirewall;
565
566    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
567    // default actuion automatically.  Important for devices without direct input
568    // devices.
569    private boolean mShowDialogs = true;
570    private boolean mInVrMode = false;
571
572    // Whether we should use SCHED_FIFO for UI and RenderThreads.
573    private boolean mUseFifoUiScheduling = false;
574
575    BroadcastQueue mFgBroadcastQueue;
576    BroadcastQueue mBgBroadcastQueue;
577    // Convenient for easy iteration over the queues. Foreground is first
578    // so that dispatch of foreground broadcasts gets precedence.
579    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
580
581    BroadcastStats mLastBroadcastStats;
582    BroadcastStats mCurBroadcastStats;
583
584    BroadcastQueue broadcastQueueForIntent(Intent intent) {
585        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
586        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
587                "Broadcast intent " + intent + " on "
588                + (isFg ? "foreground" : "background") + " queue");
589        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
590    }
591
592    /**
593     * Activity we have told the window manager to have key focus.
594     */
595    ActivityRecord mFocusedActivity = null;
596
597    /**
598     * User id of the last activity mFocusedActivity was set to.
599     */
600    private int mLastFocusedUserId;
601
602    /**
603     * If non-null, we are tracking the time the user spends in the currently focused app.
604     */
605    private AppTimeTracker mCurAppTimeTracker;
606
607    /**
608     * List of intents that were used to start the most recent tasks.
609     */
610    final RecentTasks mRecentTasks;
611
612    /**
613     * For addAppTask: cached of the last activity component that was added.
614     */
615    ComponentName mLastAddedTaskComponent;
616
617    /**
618     * For addAppTask: cached of the last activity uid that was added.
619     */
620    int mLastAddedTaskUid;
621
622    /**
623     * For addAppTask: cached of the last ActivityInfo that was added.
624     */
625    ActivityInfo mLastAddedTaskActivity;
626
627    /**
628     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
629     */
630    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
631
632    /**
633     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
634     */
635    String mDeviceOwnerName;
636
637    final UserController mUserController;
638
639    final AppErrors mAppErrors;
640
641    boolean mDoingSetFocusedActivity;
642
643    public boolean canShowErrorDialogs() {
644        return mShowDialogs && !mSleeping && !mShuttingDown;
645    }
646
647    private static final class PriorityState {
648        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
649        // the current thread is currently in. When it drops down to zero, we will no longer boost
650        // the thread's priority.
651        private int regionCounter = 0;
652
653        // The thread's previous priority before boosting.
654        private int prevPriority = Integer.MIN_VALUE;
655    }
656
657    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
658        @Override protected PriorityState initialValue() {
659            return new PriorityState();
660        }
661    };
662
663    static void boostPriorityForLockedSection() {
664        int tid = Process.myTid();
665        int prevPriority = Process.getThreadPriority(tid);
666        PriorityState state = sThreadPriorityState.get();
667        if (state.regionCounter == 0 && prevPriority > -2) {
668            state.prevPriority = prevPriority;
669            Process.setThreadPriority(tid, -2);
670        }
671        state.regionCounter++;
672    }
673
674    static void resetPriorityAfterLockedSection() {
675        PriorityState state = sThreadPriorityState.get();
676        state.regionCounter--;
677        if (state.regionCounter == 0 && state.prevPriority > -2) {
678            Process.setThreadPriority(Process.myTid(), state.prevPriority);
679        }
680    }
681
682    public class PendingAssistExtras extends Binder implements Runnable {
683        public final ActivityRecord activity;
684        public final Bundle extras;
685        public final Intent intent;
686        public final String hint;
687        public final IResultReceiver receiver;
688        public final int userHandle;
689        public boolean haveResult = false;
690        public Bundle result = null;
691        public AssistStructure structure = null;
692        public AssistContent content = null;
693        public Bundle receiverExtras;
694
695        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
696                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
697            activity = _activity;
698            extras = _extras;
699            intent = _intent;
700            hint = _hint;
701            receiver = _receiver;
702            receiverExtras = _receiverExtras;
703            userHandle = _userHandle;
704        }
705        @Override
706        public void run() {
707            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
708            synchronized (this) {
709                haveResult = true;
710                notifyAll();
711            }
712            pendingAssistExtrasTimedOut(this);
713        }
714    }
715
716    final ArrayList<PendingAssistExtras> mPendingAssistExtras
717            = new ArrayList<PendingAssistExtras>();
718
719    /**
720     * Process management.
721     */
722    final ProcessList mProcessList = new ProcessList();
723
724    /**
725     * All of the applications we currently have running organized by name.
726     * The keys are strings of the application package name (as
727     * returned by the package manager), and the keys are ApplicationRecord
728     * objects.
729     */
730    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
731
732    /**
733     * Tracking long-term execution of processes to look for abuse and other
734     * bad app behavior.
735     */
736    final ProcessStatsService mProcessStats;
737
738    /**
739     * The currently running isolated processes.
740     */
741    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
742
743    /**
744     * Counter for assigning isolated process uids, to avoid frequently reusing the
745     * same ones.
746     */
747    int mNextIsolatedProcessUid = 0;
748
749    /**
750     * The currently running heavy-weight process, if any.
751     */
752    ProcessRecord mHeavyWeightProcess = null;
753
754    /**
755     * All of the processes we currently have running organized by pid.
756     * The keys are the pid running the application.
757     *
758     * <p>NOTE: This object is protected by its own lock, NOT the global
759     * activity manager lock!
760     */
761    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
762
763    /**
764     * All of the processes that have been forced to be foreground.  The key
765     * is the pid of the caller who requested it (we hold a death
766     * link on it).
767     */
768    abstract class ForegroundToken implements IBinder.DeathRecipient {
769        int pid;
770        IBinder token;
771    }
772    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
773
774    /**
775     * List of records for processes that someone had tried to start before the
776     * system was ready.  We don't start them at that point, but ensure they
777     * are started by the time booting is complete.
778     */
779    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
780
781    /**
782     * List of persistent applications that are in the process
783     * of being started.
784     */
785    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
786
787    /**
788     * Processes that are being forcibly torn down.
789     */
790    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
791
792    /**
793     * List of running applications, sorted by recent usage.
794     * The first entry in the list is the least recently used.
795     */
796    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
797
798    /**
799     * Where in mLruProcesses that the processes hosting activities start.
800     */
801    int mLruProcessActivityStart = 0;
802
803    /**
804     * Where in mLruProcesses that the processes hosting services start.
805     * This is after (lower index) than mLruProcessesActivityStart.
806     */
807    int mLruProcessServiceStart = 0;
808
809    /**
810     * List of processes that should gc as soon as things are idle.
811     */
812    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
813
814    /**
815     * Processes we want to collect PSS data from.
816     */
817    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
818
819    private boolean mBinderTransactionTrackingEnabled = false;
820
821    /**
822     * Last time we requested PSS data of all processes.
823     */
824    long mLastFullPssTime = SystemClock.uptimeMillis();
825
826    /**
827     * If set, the next time we collect PSS data we should do a full collection
828     * with data from native processes and the kernel.
829     */
830    boolean mFullPssPending = false;
831
832    /**
833     * This is the process holding what we currently consider to be
834     * the "home" activity.
835     */
836    ProcessRecord mHomeProcess;
837
838    /**
839     * This is the process holding the activity the user last visited that
840     * is in a different process from the one they are currently in.
841     */
842    ProcessRecord mPreviousProcess;
843
844    /**
845     * The time at which the previous process was last visible.
846     */
847    long mPreviousProcessVisibleTime;
848
849    /**
850     * Track all uids that have actively running processes.
851     */
852    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
853
854    /**
855     * This is for verifying the UID report flow.
856     */
857    static final boolean VALIDATE_UID_STATES = true;
858    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
859
860    /**
861     * Packages that the user has asked to have run in screen size
862     * compatibility mode instead of filling the screen.
863     */
864    final CompatModePackages mCompatModePackages;
865
866    /**
867     * Set of IntentSenderRecord objects that are currently active.
868     */
869    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
870            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
871
872    /**
873     * Fingerprints (hashCode()) of stack traces that we've
874     * already logged DropBox entries for.  Guarded by itself.  If
875     * something (rogue user app) forces this over
876     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
877     */
878    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
879    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
880
881    /**
882     * Strict Mode background batched logging state.
883     *
884     * The string buffer is guarded by itself, and its lock is also
885     * used to determine if another batched write is already
886     * in-flight.
887     */
888    private final StringBuilder mStrictModeBuffer = new StringBuilder();
889
890    /**
891     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
892     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
893     */
894    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
895
896    /**
897     * Resolver for broadcast intents to registered receivers.
898     * Holds BroadcastFilter (subclass of IntentFilter).
899     */
900    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
901            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
902        @Override
903        protected boolean allowFilterResult(
904                BroadcastFilter filter, List<BroadcastFilter> dest) {
905            IBinder target = filter.receiverList.receiver.asBinder();
906            for (int i = dest.size() - 1; i >= 0; i--) {
907                if (dest.get(i).receiverList.receiver.asBinder() == target) {
908                    return false;
909                }
910            }
911            return true;
912        }
913
914        @Override
915        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
916            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
917                    || userId == filter.owningUserId) {
918                return super.newResult(filter, match, userId);
919            }
920            return null;
921        }
922
923        @Override
924        protected BroadcastFilter[] newArray(int size) {
925            return new BroadcastFilter[size];
926        }
927
928        @Override
929        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
930            return packageName.equals(filter.packageName);
931        }
932    };
933
934    /**
935     * State of all active sticky broadcasts per user.  Keys are the action of the
936     * sticky Intent, values are an ArrayList of all broadcasted intents with
937     * that action (which should usually be one).  The SparseArray is keyed
938     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
939     * for stickies that are sent to all users.
940     */
941    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
942            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
943
944    final ActiveServices mServices;
945
946    final static class Association {
947        final int mSourceUid;
948        final String mSourceProcess;
949        final int mTargetUid;
950        final ComponentName mTargetComponent;
951        final String mTargetProcess;
952
953        int mCount;
954        long mTime;
955
956        int mNesting;
957        long mStartTime;
958
959        // states of the source process when the bind occurred.
960        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
961        long mLastStateUptime;
962        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
963                - ActivityManager.MIN_PROCESS_STATE+1];
964
965        Association(int sourceUid, String sourceProcess, int targetUid,
966                ComponentName targetComponent, String targetProcess) {
967            mSourceUid = sourceUid;
968            mSourceProcess = sourceProcess;
969            mTargetUid = targetUid;
970            mTargetComponent = targetComponent;
971            mTargetProcess = targetProcess;
972        }
973    }
974
975    /**
976     * When service association tracking is enabled, this is all of the associations we
977     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
978     * -> association data.
979     */
980    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
981            mAssociations = new SparseArray<>();
982    boolean mTrackingAssociations;
983
984    /**
985     * Backup/restore process management
986     */
987    String mBackupAppName = null;
988    BackupRecord mBackupTarget = null;
989
990    final ProviderMap mProviderMap;
991
992    /**
993     * List of content providers who have clients waiting for them.  The
994     * application is currently being launched and the provider will be
995     * removed from this list once it is published.
996     */
997    final ArrayList<ContentProviderRecord> mLaunchingProviders
998            = new ArrayList<ContentProviderRecord>();
999
1000    /**
1001     * File storing persisted {@link #mGrantedUriPermissions}.
1002     */
1003    private final AtomicFile mGrantFile;
1004
1005    /** XML constants used in {@link #mGrantFile} */
1006    private static final String TAG_URI_GRANTS = "uri-grants";
1007    private static final String TAG_URI_GRANT = "uri-grant";
1008    private static final String ATTR_USER_HANDLE = "userHandle";
1009    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1010    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1011    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1012    private static final String ATTR_TARGET_PKG = "targetPkg";
1013    private static final String ATTR_URI = "uri";
1014    private static final String ATTR_MODE_FLAGS = "modeFlags";
1015    private static final String ATTR_CREATED_TIME = "createdTime";
1016    private static final String ATTR_PREFIX = "prefix";
1017
1018    /**
1019     * Global set of specific {@link Uri} permissions that have been granted.
1020     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1021     * to {@link UriPermission#uri} to {@link UriPermission}.
1022     */
1023    @GuardedBy("this")
1024    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1025            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1026
1027    public static class GrantUri {
1028        public final int sourceUserId;
1029        public final Uri uri;
1030        public boolean prefix;
1031
1032        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1033            this.sourceUserId = sourceUserId;
1034            this.uri = uri;
1035            this.prefix = prefix;
1036        }
1037
1038        @Override
1039        public int hashCode() {
1040            int hashCode = 1;
1041            hashCode = 31 * hashCode + sourceUserId;
1042            hashCode = 31 * hashCode + uri.hashCode();
1043            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1044            return hashCode;
1045        }
1046
1047        @Override
1048        public boolean equals(Object o) {
1049            if (o instanceof GrantUri) {
1050                GrantUri other = (GrantUri) o;
1051                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1052                        && prefix == other.prefix;
1053            }
1054            return false;
1055        }
1056
1057        @Override
1058        public String toString() {
1059            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1060            if (prefix) result += " [prefix]";
1061            return result;
1062        }
1063
1064        public String toSafeString() {
1065            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1066            if (prefix) result += " [prefix]";
1067            return result;
1068        }
1069
1070        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1071            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1072                    ContentProvider.getUriWithoutUserId(uri), false);
1073        }
1074    }
1075
1076    CoreSettingsObserver mCoreSettingsObserver;
1077
1078    FontScaleSettingObserver mFontScaleSettingObserver;
1079
1080    private final class FontScaleSettingObserver extends ContentObserver {
1081        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1082
1083        public FontScaleSettingObserver() {
1084            super(mHandler);
1085            ContentResolver resolver = mContext.getContentResolver();
1086            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1087        }
1088
1089        @Override
1090        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1091            if (mFontScaleUri.equals(uri)) {
1092                updateFontScaleIfNeeded(userId);
1093            }
1094        }
1095    }
1096
1097    /**
1098     * Thread-local storage used to carry caller permissions over through
1099     * indirect content-provider access.
1100     */
1101    private class Identity {
1102        public final IBinder token;
1103        public final int pid;
1104        public final int uid;
1105
1106        Identity(IBinder _token, int _pid, int _uid) {
1107            token = _token;
1108            pid = _pid;
1109            uid = _uid;
1110        }
1111    }
1112
1113    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1114
1115    /**
1116     * All information we have collected about the runtime performance of
1117     * any user id that can impact battery performance.
1118     */
1119    final BatteryStatsService mBatteryStatsService;
1120
1121    /**
1122     * Information about component usage
1123     */
1124    UsageStatsManagerInternal mUsageStatsService;
1125
1126    /**
1127     * Access to DeviceIdleController service.
1128     */
1129    DeviceIdleController.LocalService mLocalDeviceIdleController;
1130
1131    /**
1132     * Information about and control over application operations
1133     */
1134    final AppOpsService mAppOpsService;
1135
1136    /**
1137     * Current configuration information.  HistoryRecord objects are given
1138     * a reference to this object to indicate which configuration they are
1139     * currently running in, so this object must be kept immutable.
1140     */
1141    Configuration mConfiguration = new Configuration();
1142
1143    /**
1144     * Current sequencing integer of the configuration, for skipping old
1145     * configurations.
1146     */
1147    int mConfigurationSeq = 0;
1148
1149    boolean mSuppressResizeConfigChanges = false;
1150
1151    /**
1152     * Hardware-reported OpenGLES version.
1153     */
1154    final int GL_ES_VERSION;
1155
1156    /**
1157     * List of initialization arguments to pass to all processes when binding applications to them.
1158     * For example, references to the commonly used services.
1159     */
1160    HashMap<String, IBinder> mAppBindArgs;
1161
1162    /**
1163     * Temporary to avoid allocations.  Protected by main lock.
1164     */
1165    final StringBuilder mStringBuilder = new StringBuilder(256);
1166
1167    /**
1168     * Used to control how we initialize the service.
1169     */
1170    ComponentName mTopComponent;
1171    String mTopAction = Intent.ACTION_MAIN;
1172    String mTopData;
1173
1174    volatile boolean mProcessesReady = false;
1175    volatile boolean mSystemReady = false;
1176    volatile boolean mOnBattery = false;
1177    volatile int mFactoryTest;
1178
1179    @GuardedBy("this") boolean mBooting = false;
1180    @GuardedBy("this") boolean mCallFinishBooting = false;
1181    @GuardedBy("this") boolean mBootAnimationComplete = false;
1182    @GuardedBy("this") boolean mLaunchWarningShown = false;
1183    @GuardedBy("this") boolean mCheckedForSetup = false;
1184
1185    Context mContext;
1186
1187    /**
1188     * The time at which we will allow normal application switches again,
1189     * after a call to {@link #stopAppSwitches()}.
1190     */
1191    long mAppSwitchesAllowedTime;
1192
1193    /**
1194     * This is set to true after the first switch after mAppSwitchesAllowedTime
1195     * is set; any switches after that will clear the time.
1196     */
1197    boolean mDidAppSwitch;
1198
1199    /**
1200     * Last time (in realtime) at which we checked for power usage.
1201     */
1202    long mLastPowerCheckRealtime;
1203
1204    /**
1205     * Last time (in uptime) at which we checked for power usage.
1206     */
1207    long mLastPowerCheckUptime;
1208
1209    /**
1210     * Set while we are wanting to sleep, to prevent any
1211     * activities from being started/resumed.
1212     */
1213    private boolean mSleeping = false;
1214
1215    /**
1216     * The process state used for processes that are running the top activities.
1217     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1218     */
1219    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1220
1221    /**
1222     * Set while we are running a voice interaction.  This overrides
1223     * sleeping while it is active.
1224     */
1225    private IVoiceInteractionSession mRunningVoice;
1226
1227    /**
1228     * For some direct access we need to power manager.
1229     */
1230    PowerManagerInternal mLocalPowerManager;
1231
1232    /**
1233     * We want to hold a wake lock while running a voice interaction session, since
1234     * this may happen with the screen off and we need to keep the CPU running to
1235     * be able to continue to interact with the user.
1236     */
1237    PowerManager.WakeLock mVoiceWakeLock;
1238
1239    /**
1240     * State of external calls telling us if the device is awake or asleep.
1241     */
1242    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1243
1244    /**
1245     * A list of tokens that cause the top activity to be put to sleep.
1246     * They are used by components that may hide and block interaction with underlying
1247     * activities.
1248     */
1249    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1250
1251    static final int LOCK_SCREEN_HIDDEN = 0;
1252    static final int LOCK_SCREEN_LEAVING = 1;
1253    static final int LOCK_SCREEN_SHOWN = 2;
1254    /**
1255     * State of external call telling us if the lock screen is shown.
1256     */
1257    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1258
1259    /**
1260     * Set if we are shutting down the system, similar to sleeping.
1261     */
1262    boolean mShuttingDown = false;
1263
1264    /**
1265     * Current sequence id for oom_adj computation traversal.
1266     */
1267    int mAdjSeq = 0;
1268
1269    /**
1270     * Current sequence id for process LRU updating.
1271     */
1272    int mLruSeq = 0;
1273
1274    /**
1275     * Keep track of the non-cached/empty process we last found, to help
1276     * determine how to distribute cached/empty processes next time.
1277     */
1278    int mNumNonCachedProcs = 0;
1279
1280    /**
1281     * Keep track of the number of cached hidden procs, to balance oom adj
1282     * distribution between those and empty procs.
1283     */
1284    int mNumCachedHiddenProcs = 0;
1285
1286    /**
1287     * Keep track of the number of service processes we last found, to
1288     * determine on the next iteration which should be B services.
1289     */
1290    int mNumServiceProcs = 0;
1291    int mNewNumAServiceProcs = 0;
1292    int mNewNumServiceProcs = 0;
1293
1294    /**
1295     * Allow the current computed overall memory level of the system to go down?
1296     * This is set to false when we are killing processes for reasons other than
1297     * memory management, so that the now smaller process list will not be taken as
1298     * an indication that memory is tighter.
1299     */
1300    boolean mAllowLowerMemLevel = false;
1301
1302    /**
1303     * The last computed memory level, for holding when we are in a state that
1304     * processes are going away for other reasons.
1305     */
1306    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1307
1308    /**
1309     * The last total number of process we have, to determine if changes actually look
1310     * like a shrinking number of process due to lower RAM.
1311     */
1312    int mLastNumProcesses;
1313
1314    /**
1315     * The uptime of the last time we performed idle maintenance.
1316     */
1317    long mLastIdleTime = SystemClock.uptimeMillis();
1318
1319    /**
1320     * Total time spent with RAM that has been added in the past since the last idle time.
1321     */
1322    long mLowRamTimeSinceLastIdle = 0;
1323
1324    /**
1325     * If RAM is currently low, when that horrible situation started.
1326     */
1327    long mLowRamStartTime = 0;
1328
1329    /**
1330     * For reporting to battery stats the current top application.
1331     */
1332    private String mCurResumedPackage = null;
1333    private int mCurResumedUid = -1;
1334
1335    /**
1336     * For reporting to battery stats the apps currently running foreground
1337     * service.  The ProcessMap is package/uid tuples; each of these contain
1338     * an array of the currently foreground processes.
1339     */
1340    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1341            = new ProcessMap<ArrayList<ProcessRecord>>();
1342
1343    /**
1344     * This is set if we had to do a delayed dexopt of an app before launching
1345     * it, to increase the ANR timeouts in that case.
1346     */
1347    boolean mDidDexOpt;
1348
1349    /**
1350     * Set if the systemServer made a call to enterSafeMode.
1351     */
1352    boolean mSafeMode;
1353
1354    /**
1355     * If true, we are running under a test environment so will sample PSS from processes
1356     * much more rapidly to try to collect better data when the tests are rapidly
1357     * running through apps.
1358     */
1359    boolean mTestPssMode = false;
1360
1361    String mDebugApp = null;
1362    boolean mWaitForDebugger = false;
1363    boolean mDebugTransient = false;
1364    String mOrigDebugApp = null;
1365    boolean mOrigWaitForDebugger = false;
1366    boolean mAlwaysFinishActivities = false;
1367    boolean mLenientBackgroundCheck = false;
1368    boolean mForceResizableActivities;
1369    boolean mSupportsMultiWindow;
1370    boolean mSupportsFreeformWindowManagement;
1371    boolean mSupportsPictureInPicture;
1372    boolean mSupportsLeanbackOnly;
1373    Rect mDefaultPinnedStackBounds;
1374    IActivityController mController = null;
1375    boolean mControllerIsAMonkey = false;
1376    String mProfileApp = null;
1377    ProcessRecord mProfileProc = null;
1378    String mProfileFile;
1379    ParcelFileDescriptor mProfileFd;
1380    int mSamplingInterval = 0;
1381    boolean mAutoStopProfiler = false;
1382    int mProfileType = 0;
1383    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1384    String mMemWatchDumpProcName;
1385    String mMemWatchDumpFile;
1386    int mMemWatchDumpPid;
1387    int mMemWatchDumpUid;
1388    String mTrackAllocationApp = null;
1389    String mNativeDebuggingApp = null;
1390
1391    final long[] mTmpLong = new long[2];
1392
1393    static final class ProcessChangeItem {
1394        static final int CHANGE_ACTIVITIES = 1<<0;
1395        static final int CHANGE_PROCESS_STATE = 1<<1;
1396        int changes;
1397        int uid;
1398        int pid;
1399        int processState;
1400        boolean foregroundActivities;
1401    }
1402
1403    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1404    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1405
1406    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1407    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1408
1409    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1410    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1411
1412    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1413    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1414
1415    /**
1416     * Runtime CPU use collection thread.  This object's lock is used to
1417     * perform synchronization with the thread (notifying it to run).
1418     */
1419    final Thread mProcessCpuThread;
1420
1421    /**
1422     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1423     * Must acquire this object's lock when accessing it.
1424     * NOTE: this lock will be held while doing long operations (trawling
1425     * through all processes in /proc), so it should never be acquired by
1426     * any critical paths such as when holding the main activity manager lock.
1427     */
1428    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1429            MONITOR_THREAD_CPU_USAGE);
1430    final AtomicLong mLastCpuTime = new AtomicLong(0);
1431    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1432
1433    long mLastWriteTime = 0;
1434
1435    /**
1436     * Used to retain an update lock when the foreground activity is in
1437     * immersive mode.
1438     */
1439    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1440
1441    /**
1442     * Set to true after the system has finished booting.
1443     */
1444    boolean mBooted = false;
1445
1446    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1447    int mProcessLimitOverride = -1;
1448
1449    WindowManagerService mWindowManager;
1450    final ActivityThread mSystemThread;
1451
1452    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1453        final ProcessRecord mApp;
1454        final int mPid;
1455        final IApplicationThread mAppThread;
1456
1457        AppDeathRecipient(ProcessRecord app, int pid,
1458                IApplicationThread thread) {
1459            if (DEBUG_ALL) Slog.v(
1460                TAG, "New death recipient " + this
1461                + " for thread " + thread.asBinder());
1462            mApp = app;
1463            mPid = pid;
1464            mAppThread = thread;
1465        }
1466
1467        @Override
1468        public void binderDied() {
1469            if (DEBUG_ALL) Slog.v(
1470                TAG, "Death received in " + this
1471                + " for thread " + mAppThread.asBinder());
1472            synchronized(ActivityManagerService.this) {
1473                appDiedLocked(mApp, mPid, mAppThread, true);
1474            }
1475        }
1476    }
1477
1478    static final int SHOW_ERROR_UI_MSG = 1;
1479    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1480    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1481    static final int UPDATE_CONFIGURATION_MSG = 4;
1482    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1483    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1484    static final int SERVICE_TIMEOUT_MSG = 12;
1485    static final int UPDATE_TIME_ZONE = 13;
1486    static final int SHOW_UID_ERROR_UI_MSG = 14;
1487    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1488    static final int PROC_START_TIMEOUT_MSG = 20;
1489    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1490    static final int KILL_APPLICATION_MSG = 22;
1491    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1492    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1493    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1494    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1495    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1496    static final int CLEAR_DNS_CACHE_MSG = 28;
1497    static final int UPDATE_HTTP_PROXY_MSG = 29;
1498    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1499    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1500    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1501    static final int REPORT_MEM_USAGE_MSG = 33;
1502    static final int REPORT_USER_SWITCH_MSG = 34;
1503    static final int CONTINUE_USER_SWITCH_MSG = 35;
1504    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1505    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1506    static final int PERSIST_URI_GRANTS_MSG = 38;
1507    static final int REQUEST_ALL_PSS_MSG = 39;
1508    static final int START_PROFILES_MSG = 40;
1509    static final int UPDATE_TIME = 41;
1510    static final int SYSTEM_USER_START_MSG = 42;
1511    static final int SYSTEM_USER_CURRENT_MSG = 43;
1512    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1513    static final int FINISH_BOOTING_MSG = 45;
1514    static final int START_USER_SWITCH_UI_MSG = 46;
1515    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1516    static final int DISMISS_DIALOG_UI_MSG = 48;
1517    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1518    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1519    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1520    static final int DELETE_DUMPHEAP_MSG = 52;
1521    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1522    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1523    static final int REPORT_TIME_TRACKER_MSG = 55;
1524    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1525    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1526    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1527    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1528    static final int IDLE_UIDS_MSG = 60;
1529    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1530    static final int LOG_STACK_STATE = 62;
1531    static final int VR_MODE_CHANGE_MSG = 63;
1532    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1533    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1534    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1535    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1536    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1537    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1538    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1539
1540    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1541    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1542    static final int FIRST_COMPAT_MODE_MSG = 300;
1543    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1544
1545    static ServiceThread sKillThread = null;
1546    static KillHandler sKillHandler = null;
1547
1548    CompatModeDialog mCompatModeDialog;
1549    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1550    long mLastMemUsageReportTime = 0;
1551
1552    /**
1553     * Flag whether the current user is a "monkey", i.e. whether
1554     * the UI is driven by a UI automation tool.
1555     */
1556    private boolean mUserIsMonkey;
1557
1558    /** Flag whether the device has a Recents UI */
1559    boolean mHasRecents;
1560
1561    /** The dimensions of the thumbnails in the Recents UI. */
1562    int mThumbnailWidth;
1563    int mThumbnailHeight;
1564    float mFullscreenThumbnailScale;
1565
1566    final ServiceThread mHandlerThread;
1567    final MainHandler mHandler;
1568    final UiHandler mUiHandler;
1569
1570    PackageManagerInternal mPackageManagerInt;
1571
1572    // VoiceInteraction session ID that changes for each new request except when
1573    // being called for multiwindow assist in a single session.
1574    private int mViSessionId = 1000;
1575
1576    final class KillHandler extends Handler {
1577        static final int KILL_PROCESS_GROUP_MSG = 4000;
1578
1579        public KillHandler(Looper looper) {
1580            super(looper, null, true);
1581        }
1582
1583        @Override
1584        public void handleMessage(Message msg) {
1585            switch (msg.what) {
1586                case KILL_PROCESS_GROUP_MSG:
1587                {
1588                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1589                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1590                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1591                }
1592                break;
1593
1594                default:
1595                    super.handleMessage(msg);
1596            }
1597        }
1598    }
1599
1600    final class UiHandler extends Handler {
1601        public UiHandler() {
1602            super(com.android.server.UiThread.get().getLooper(), null, true);
1603        }
1604
1605        @Override
1606        public void handleMessage(Message msg) {
1607            switch (msg.what) {
1608            case SHOW_ERROR_UI_MSG: {
1609                mAppErrors.handleShowAppErrorUi(msg);
1610                ensureBootCompleted();
1611            } break;
1612            case SHOW_NOT_RESPONDING_UI_MSG: {
1613                mAppErrors.handleShowAnrUi(msg);
1614                ensureBootCompleted();
1615            } break;
1616            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1617                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1618                synchronized (ActivityManagerService.this) {
1619                    ProcessRecord proc = (ProcessRecord) data.get("app");
1620                    if (proc == null) {
1621                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1622                        break;
1623                    }
1624                    if (proc.crashDialog != null) {
1625                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1626                        return;
1627                    }
1628                    AppErrorResult res = (AppErrorResult) data.get("result");
1629                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1630                        Dialog d = new StrictModeViolationDialog(mContext,
1631                                ActivityManagerService.this, res, proc);
1632                        d.show();
1633                        proc.crashDialog = d;
1634                    } else {
1635                        // The device is asleep, so just pretend that the user
1636                        // saw a crash dialog and hit "force quit".
1637                        res.set(0);
1638                    }
1639                }
1640                ensureBootCompleted();
1641            } break;
1642            case SHOW_FACTORY_ERROR_UI_MSG: {
1643                Dialog d = new FactoryErrorDialog(
1644                    mContext, msg.getData().getCharSequence("msg"));
1645                d.show();
1646                ensureBootCompleted();
1647            } break;
1648            case WAIT_FOR_DEBUGGER_UI_MSG: {
1649                synchronized (ActivityManagerService.this) {
1650                    ProcessRecord app = (ProcessRecord)msg.obj;
1651                    if (msg.arg1 != 0) {
1652                        if (!app.waitedForDebugger) {
1653                            Dialog d = new AppWaitingForDebuggerDialog(
1654                                    ActivityManagerService.this,
1655                                    mContext, app);
1656                            app.waitDialog = d;
1657                            app.waitedForDebugger = true;
1658                            d.show();
1659                        }
1660                    } else {
1661                        if (app.waitDialog != null) {
1662                            app.waitDialog.dismiss();
1663                            app.waitDialog = null;
1664                        }
1665                    }
1666                }
1667            } break;
1668            case SHOW_UID_ERROR_UI_MSG: {
1669                if (mShowDialogs) {
1670                    AlertDialog d = new BaseErrorDialog(mContext);
1671                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1672                    d.setCancelable(false);
1673                    d.setTitle(mContext.getText(R.string.android_system_label));
1674                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1675                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1676                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1677                    d.show();
1678                }
1679            } break;
1680            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1681                if (mShowDialogs) {
1682                    AlertDialog d = new BaseErrorDialog(mContext);
1683                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1684                    d.setCancelable(false);
1685                    d.setTitle(mContext.getText(R.string.android_system_label));
1686                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1687                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1688                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1689                    d.show();
1690                }
1691            } break;
1692            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    ActivityRecord ar = (ActivityRecord) msg.obj;
1695                    if (mCompatModeDialog != null) {
1696                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1697                                ar.info.applicationInfo.packageName)) {
1698                            return;
1699                        }
1700                        mCompatModeDialog.dismiss();
1701                        mCompatModeDialog = null;
1702                    }
1703                    if (ar != null && false) {
1704                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1705                                ar.packageName)) {
1706                            int mode = mCompatModePackages.computeCompatModeLocked(
1707                                    ar.info.applicationInfo);
1708                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1709                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1710                                mCompatModeDialog = new CompatModeDialog(
1711                                        ActivityManagerService.this, mContext,
1712                                        ar.info.applicationInfo);
1713                                mCompatModeDialog.show();
1714                            }
1715                        }
1716                    }
1717                }
1718                break;
1719            }
1720            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1721                synchronized (ActivityManagerService.this) {
1722                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1723                    if (mUnsupportedDisplaySizeDialog != null) {
1724                        mUnsupportedDisplaySizeDialog.dismiss();
1725                        mUnsupportedDisplaySizeDialog = null;
1726                    }
1727                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1728                            ar.packageName)) {
1729                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1730                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1731                        mUnsupportedDisplaySizeDialog.show();
1732                    }
1733                }
1734                break;
1735            }
1736            case START_USER_SWITCH_UI_MSG: {
1737                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1738                break;
1739            }
1740            case DISMISS_DIALOG_UI_MSG: {
1741                final Dialog d = (Dialog) msg.obj;
1742                d.dismiss();
1743                break;
1744            }
1745            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1746                dispatchProcessesChanged();
1747                break;
1748            }
1749            case DISPATCH_PROCESS_DIED_UI_MSG: {
1750                final int pid = msg.arg1;
1751                final int uid = msg.arg2;
1752                dispatchProcessDied(pid, uid);
1753                break;
1754            }
1755            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1756                dispatchUidsChanged();
1757            } break;
1758            }
1759        }
1760    }
1761
1762    final class MainHandler extends Handler {
1763        public MainHandler(Looper looper) {
1764            super(looper, null, true);
1765        }
1766
1767        @Override
1768        public void handleMessage(Message msg) {
1769            switch (msg.what) {
1770            case UPDATE_CONFIGURATION_MSG: {
1771                final ContentResolver resolver = mContext.getContentResolver();
1772                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1773                        msg.arg1);
1774            } break;
1775            case GC_BACKGROUND_PROCESSES_MSG: {
1776                synchronized (ActivityManagerService.this) {
1777                    performAppGcsIfAppropriateLocked();
1778                }
1779            } break;
1780            case SERVICE_TIMEOUT_MSG: {
1781                if (mDidDexOpt) {
1782                    mDidDexOpt = false;
1783                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1784                    nmsg.obj = msg.obj;
1785                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1786                    return;
1787                }
1788                mServices.serviceTimeout((ProcessRecord)msg.obj);
1789            } break;
1790            case UPDATE_TIME_ZONE: {
1791                synchronized (ActivityManagerService.this) {
1792                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1793                        ProcessRecord r = mLruProcesses.get(i);
1794                        if (r.thread != null) {
1795                            try {
1796                                r.thread.updateTimeZone();
1797                            } catch (RemoteException ex) {
1798                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1799                            }
1800                        }
1801                    }
1802                }
1803            } break;
1804            case CLEAR_DNS_CACHE_MSG: {
1805                synchronized (ActivityManagerService.this) {
1806                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1807                        ProcessRecord r = mLruProcesses.get(i);
1808                        if (r.thread != null) {
1809                            try {
1810                                r.thread.clearDnsCache();
1811                            } catch (RemoteException ex) {
1812                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1813                            }
1814                        }
1815                    }
1816                }
1817            } break;
1818            case UPDATE_HTTP_PROXY_MSG: {
1819                ProxyInfo proxy = (ProxyInfo)msg.obj;
1820                String host = "";
1821                String port = "";
1822                String exclList = "";
1823                Uri pacFileUrl = Uri.EMPTY;
1824                if (proxy != null) {
1825                    host = proxy.getHost();
1826                    port = Integer.toString(proxy.getPort());
1827                    exclList = proxy.getExclusionListAsString();
1828                    pacFileUrl = proxy.getPacFileUrl();
1829                }
1830                synchronized (ActivityManagerService.this) {
1831                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1832                        ProcessRecord r = mLruProcesses.get(i);
1833                        if (r.thread != null) {
1834                            try {
1835                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1836                            } catch (RemoteException ex) {
1837                                Slog.w(TAG, "Failed to update http proxy for: " +
1838                                        r.info.processName);
1839                            }
1840                        }
1841                    }
1842                }
1843            } break;
1844            case PROC_START_TIMEOUT_MSG: {
1845                if (mDidDexOpt) {
1846                    mDidDexOpt = false;
1847                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1848                    nmsg.obj = msg.obj;
1849                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1850                    return;
1851                }
1852                ProcessRecord app = (ProcessRecord)msg.obj;
1853                synchronized (ActivityManagerService.this) {
1854                    processStartTimedOutLocked(app);
1855                }
1856            } break;
1857            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1858                ProcessRecord app = (ProcessRecord)msg.obj;
1859                synchronized (ActivityManagerService.this) {
1860                    processContentProviderPublishTimedOutLocked(app);
1861                }
1862            } break;
1863            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1864                synchronized (ActivityManagerService.this) {
1865                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1866                }
1867            } break;
1868            case KILL_APPLICATION_MSG: {
1869                synchronized (ActivityManagerService.this) {
1870                    final int appId = msg.arg1;
1871                    final int userId = msg.arg2;
1872                    Bundle bundle = (Bundle)msg.obj;
1873                    String pkg = bundle.getString("pkg");
1874                    String reason = bundle.getString("reason");
1875                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1876                            false, userId, reason);
1877                }
1878            } break;
1879            case FINALIZE_PENDING_INTENT_MSG: {
1880                ((PendingIntentRecord)msg.obj).completeFinalize();
1881            } break;
1882            case POST_HEAVY_NOTIFICATION_MSG: {
1883                INotificationManager inm = NotificationManager.getService();
1884                if (inm == null) {
1885                    return;
1886                }
1887
1888                ActivityRecord root = (ActivityRecord)msg.obj;
1889                ProcessRecord process = root.app;
1890                if (process == null) {
1891                    return;
1892                }
1893
1894                try {
1895                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1896                    String text = mContext.getString(R.string.heavy_weight_notification,
1897                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1898                    Notification notification = new Notification.Builder(context)
1899                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1900                            .setWhen(0)
1901                            .setOngoing(true)
1902                            .setTicker(text)
1903                            .setColor(mContext.getColor(
1904                                    com.android.internal.R.color.system_notification_accent_color))
1905                            .setContentTitle(text)
1906                            .setContentText(
1907                                    mContext.getText(R.string.heavy_weight_notification_detail))
1908                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1909                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1910                                    new UserHandle(root.userId)))
1911                            .build();
1912                    try {
1913                        int[] outId = new int[1];
1914                        inm.enqueueNotificationWithTag("android", "android", null,
1915                                R.string.heavy_weight_notification,
1916                                notification, outId, root.userId);
1917                    } catch (RuntimeException e) {
1918                        Slog.w(ActivityManagerService.TAG,
1919                                "Error showing notification for heavy-weight app", e);
1920                    } catch (RemoteException e) {
1921                    }
1922                } catch (NameNotFoundException e) {
1923                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1924                }
1925            } break;
1926            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1927                INotificationManager inm = NotificationManager.getService();
1928                if (inm == null) {
1929                    return;
1930                }
1931                try {
1932                    inm.cancelNotificationWithTag("android", null,
1933                            R.string.heavy_weight_notification,  msg.arg1);
1934                } catch (RuntimeException e) {
1935                    Slog.w(ActivityManagerService.TAG,
1936                            "Error canceling notification for service", e);
1937                } catch (RemoteException e) {
1938                }
1939            } break;
1940            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1941                synchronized (ActivityManagerService.this) {
1942                    checkExcessivePowerUsageLocked(true);
1943                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1944                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1945                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1946                }
1947            } break;
1948            case REPORT_MEM_USAGE_MSG: {
1949                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1950                Thread thread = new Thread() {
1951                    @Override public void run() {
1952                        reportMemUsage(memInfos);
1953                    }
1954                };
1955                thread.start();
1956                break;
1957            }
1958            case REPORT_USER_SWITCH_MSG: {
1959                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1960                break;
1961            }
1962            case CONTINUE_USER_SWITCH_MSG: {
1963                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1964                break;
1965            }
1966            case USER_SWITCH_TIMEOUT_MSG: {
1967                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1968                break;
1969            }
1970            case IMMERSIVE_MODE_LOCK_MSG: {
1971                final boolean nextState = (msg.arg1 != 0);
1972                if (mUpdateLock.isHeld() != nextState) {
1973                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1974                            "Applying new update lock state '" + nextState
1975                            + "' for " + (ActivityRecord)msg.obj);
1976                    if (nextState) {
1977                        mUpdateLock.acquire();
1978                    } else {
1979                        mUpdateLock.release();
1980                    }
1981                }
1982                break;
1983            }
1984            case PERSIST_URI_GRANTS_MSG: {
1985                writeGrantedUriPermissions();
1986                break;
1987            }
1988            case REQUEST_ALL_PSS_MSG: {
1989                synchronized (ActivityManagerService.this) {
1990                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1991                }
1992                break;
1993            }
1994            case START_PROFILES_MSG: {
1995                synchronized (ActivityManagerService.this) {
1996                    mUserController.startProfilesLocked();
1997                }
1998                break;
1999            }
2000            case UPDATE_TIME: {
2001                synchronized (ActivityManagerService.this) {
2002                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2003                        ProcessRecord r = mLruProcesses.get(i);
2004                        if (r.thread != null) {
2005                            try {
2006                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2007                            } catch (RemoteException ex) {
2008                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2009                            }
2010                        }
2011                    }
2012                }
2013                break;
2014            }
2015            case SYSTEM_USER_START_MSG: {
2016                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2017                        Integer.toString(msg.arg1), msg.arg1);
2018                mSystemServiceManager.startUser(msg.arg1);
2019                break;
2020            }
2021            case SYSTEM_USER_UNLOCK_MSG: {
2022                final int userId = msg.arg1;
2023                mSystemServiceManager.unlockUser(userId);
2024                synchronized (ActivityManagerService.this) {
2025                    mRecentTasks.loadUserRecentsLocked(userId);
2026                }
2027                if (userId == UserHandle.USER_SYSTEM) {
2028                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2029                }
2030                installEncryptionUnawareProviders(userId);
2031                mUserController.finishUserUnlocked((UserState) msg.obj);
2032                break;
2033            }
2034            case SYSTEM_USER_CURRENT_MSG: {
2035                mBatteryStatsService.noteEvent(
2036                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2037                        Integer.toString(msg.arg2), msg.arg2);
2038                mBatteryStatsService.noteEvent(
2039                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2040                        Integer.toString(msg.arg1), msg.arg1);
2041                mSystemServiceManager.switchUser(msg.arg1);
2042                break;
2043            }
2044            case ENTER_ANIMATION_COMPLETE_MSG: {
2045                synchronized (ActivityManagerService.this) {
2046                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2047                    if (r != null && r.app != null && r.app.thread != null) {
2048                        try {
2049                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2050                        } catch (RemoteException e) {
2051                        }
2052                    }
2053                }
2054                break;
2055            }
2056            case FINISH_BOOTING_MSG: {
2057                if (msg.arg1 != 0) {
2058                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2059                    finishBooting();
2060                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2061                }
2062                if (msg.arg2 != 0) {
2063                    enableScreenAfterBoot();
2064                }
2065                break;
2066            }
2067            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2068                try {
2069                    Locale l = (Locale) msg.obj;
2070                    IBinder service = ServiceManager.getService("mount");
2071                    IMountService mountService = IMountService.Stub.asInterface(service);
2072                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2073                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2074                } catch (RemoteException e) {
2075                    Log.e(TAG, "Error storing locale for decryption UI", e);
2076                }
2077                break;
2078            }
2079            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2080                synchronized (ActivityManagerService.this) {
2081                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2082                        try {
2083                            // Make a one-way callback to the listener
2084                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2085                        } catch (RemoteException e){
2086                            // Handled by the RemoteCallbackList
2087                        }
2088                    }
2089                    mTaskStackListeners.finishBroadcast();
2090                }
2091                break;
2092            }
2093            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2094                synchronized (ActivityManagerService.this) {
2095                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2096                        try {
2097                            // Make a one-way callback to the listener
2098                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2099                        } catch (RemoteException e){
2100                            // Handled by the RemoteCallbackList
2101                        }
2102                    }
2103                    mTaskStackListeners.finishBroadcast();
2104                }
2105                break;
2106            }
2107            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2108                synchronized (ActivityManagerService.this) {
2109                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2110                        try {
2111                            // Make a one-way callback to the listener
2112                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2113                        } catch (RemoteException e){
2114                            // Handled by the RemoteCallbackList
2115                        }
2116                    }
2117                    mTaskStackListeners.finishBroadcast();
2118                }
2119                break;
2120            }
2121            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2122                synchronized (ActivityManagerService.this) {
2123                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2124                        try {
2125                            // Make a one-way callback to the listener
2126                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2127                        } catch (RemoteException e){
2128                            // Handled by the RemoteCallbackList
2129                        }
2130                    }
2131                    mTaskStackListeners.finishBroadcast();
2132                }
2133                break;
2134            }
2135            case NOTIFY_FORCED_RESIZABLE_MSG: {
2136                synchronized (ActivityManagerService.this) {
2137                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2138                        try {
2139                            // Make a one-way callback to the listener
2140                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2141                                    (String) msg.obj, msg.arg1);
2142                        } catch (RemoteException e){
2143                            // Handled by the RemoteCallbackList
2144                        }
2145                    }
2146                    mTaskStackListeners.finishBroadcast();
2147                }
2148                break;
2149            }
2150                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2151                    synchronized (ActivityManagerService.this) {
2152                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2153                            try {
2154                                // Make a one-way callback to the listener
2155                                mTaskStackListeners.getBroadcastItem(i)
2156                                        .onActivityDismissingDockedStack();
2157                            } catch (RemoteException e){
2158                                // Handled by the RemoteCallbackList
2159                            }
2160                        }
2161                        mTaskStackListeners.finishBroadcast();
2162                    }
2163                    break;
2164                }
2165            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2166                final int uid = msg.arg1;
2167                final byte[] firstPacket = (byte[]) msg.obj;
2168
2169                synchronized (mPidsSelfLocked) {
2170                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2171                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2172                        if (p.uid == uid) {
2173                            try {
2174                                p.thread.notifyCleartextNetwork(firstPacket);
2175                            } catch (RemoteException ignored) {
2176                            }
2177                        }
2178                    }
2179                }
2180                break;
2181            }
2182            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2183                final String procName;
2184                final int uid;
2185                final long memLimit;
2186                final String reportPackage;
2187                synchronized (ActivityManagerService.this) {
2188                    procName = mMemWatchDumpProcName;
2189                    uid = mMemWatchDumpUid;
2190                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2191                    if (val == null) {
2192                        val = mMemWatchProcesses.get(procName, 0);
2193                    }
2194                    if (val != null) {
2195                        memLimit = val.first;
2196                        reportPackage = val.second;
2197                    } else {
2198                        memLimit = 0;
2199                        reportPackage = null;
2200                    }
2201                }
2202                if (procName == null) {
2203                    return;
2204                }
2205
2206                if (DEBUG_PSS) Slog.d(TAG_PSS,
2207                        "Showing dump heap notification from " + procName + "/" + uid);
2208
2209                INotificationManager inm = NotificationManager.getService();
2210                if (inm == null) {
2211                    return;
2212                }
2213
2214                String text = mContext.getString(R.string.dump_heap_notification, procName);
2215
2216
2217                Intent deleteIntent = new Intent();
2218                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2219                Intent intent = new Intent();
2220                intent.setClassName("android", DumpHeapActivity.class.getName());
2221                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2222                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2223                if (reportPackage != null) {
2224                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2225                }
2226                int userId = UserHandle.getUserId(uid);
2227                Notification notification = new Notification.Builder(mContext)
2228                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2229                        .setWhen(0)
2230                        .setOngoing(true)
2231                        .setAutoCancel(true)
2232                        .setTicker(text)
2233                        .setColor(mContext.getColor(
2234                                com.android.internal.R.color.system_notification_accent_color))
2235                        .setContentTitle(text)
2236                        .setContentText(
2237                                mContext.getText(R.string.dump_heap_notification_detail))
2238                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2239                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2240                                new UserHandle(userId)))
2241                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2242                                deleteIntent, 0, UserHandle.SYSTEM))
2243                        .build();
2244
2245                try {
2246                    int[] outId = new int[1];
2247                    inm.enqueueNotificationWithTag("android", "android", null,
2248                            R.string.dump_heap_notification,
2249                            notification, outId, userId);
2250                } catch (RuntimeException e) {
2251                    Slog.w(ActivityManagerService.TAG,
2252                            "Error showing notification for dump heap", e);
2253                } catch (RemoteException e) {
2254                }
2255            } break;
2256            case DELETE_DUMPHEAP_MSG: {
2257                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2258                        DumpHeapActivity.JAVA_URI,
2259                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2260                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2261                        UserHandle.myUserId());
2262                synchronized (ActivityManagerService.this) {
2263                    mMemWatchDumpFile = null;
2264                    mMemWatchDumpProcName = null;
2265                    mMemWatchDumpPid = -1;
2266                    mMemWatchDumpUid = -1;
2267                }
2268            } break;
2269            case FOREGROUND_PROFILE_CHANGED_MSG: {
2270                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2271            } break;
2272            case REPORT_TIME_TRACKER_MSG: {
2273                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2274                tracker.deliverResult(mContext);
2275            } break;
2276            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2277                mUserController.dispatchUserSwitchComplete(msg.arg1);
2278            } break;
2279            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2280                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2281                try {
2282                    connection.shutdown();
2283                } catch (RemoteException e) {
2284                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2285                }
2286                // Only a UiAutomation can set this flag and now that
2287                // it is finished we make sure it is reset to its default.
2288                mUserIsMonkey = false;
2289            } break;
2290            case APP_BOOST_DEACTIVATE_MSG: {
2291                synchronized(ActivityManagerService.this) {
2292                    if (mIsBoosted) {
2293                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2294                            nativeMigrateFromBoost();
2295                            mIsBoosted = false;
2296                            mBoostStartTime = 0;
2297                        } else {
2298                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2299                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2300                        }
2301                    }
2302                }
2303            } break;
2304            case IDLE_UIDS_MSG: {
2305                idleUids();
2306            } break;
2307            case LOG_STACK_STATE: {
2308                synchronized (ActivityManagerService.this) {
2309                    mStackSupervisor.logStackState();
2310                }
2311            } break;
2312            case VR_MODE_CHANGE_MSG: {
2313                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2314                final ActivityRecord r = (ActivityRecord) msg.obj;
2315                boolean vrMode;
2316                ComponentName requestedPackage;
2317                ComponentName callingPackage;
2318                int userId;
2319                synchronized (ActivityManagerService.this) {
2320                    vrMode = r.requestedVrComponent != null;
2321                    requestedPackage = r.requestedVrComponent;
2322                    userId = r.userId;
2323                    callingPackage = r.info.getComponentName();
2324                    if (mInVrMode != vrMode) {
2325                        mInVrMode = vrMode;
2326                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2327                        if (r.app != null) {
2328                            ProcessRecord proc = r.app;
2329                            if (proc.vrThreadTid > 0) {
2330                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2331                                    try {
2332                                        if (mInVrMode == true) {
2333                                            Process.setThreadScheduler(proc.vrThreadTid,
2334                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2335                                        } else {
2336                                            Process.setThreadScheduler(proc.vrThreadTid,
2337                                                Process.SCHED_OTHER, 0);
2338                                        }
2339                                    } catch (IllegalArgumentException e) {
2340                                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
2341                                                + " not exist:\n" + e);
2342                                    }
2343                                }
2344                            }
2345                        }
2346                    }
2347                }
2348                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2349            } break;
2350            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2351                final ActivityRecord r = (ActivityRecord) msg.obj;
2352                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2353                if (needsVrMode) {
2354                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2355                            r.info.getComponentName(), false);
2356                }
2357            } break;
2358            }
2359        }
2360    };
2361
2362    static final int COLLECT_PSS_BG_MSG = 1;
2363
2364    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2365        @Override
2366        public void handleMessage(Message msg) {
2367            switch (msg.what) {
2368            case COLLECT_PSS_BG_MSG: {
2369                long start = SystemClock.uptimeMillis();
2370                MemInfoReader memInfo = null;
2371                synchronized (ActivityManagerService.this) {
2372                    if (mFullPssPending) {
2373                        mFullPssPending = false;
2374                        memInfo = new MemInfoReader();
2375                    }
2376                }
2377                if (memInfo != null) {
2378                    updateCpuStatsNow();
2379                    long nativeTotalPss = 0;
2380                    synchronized (mProcessCpuTracker) {
2381                        final int N = mProcessCpuTracker.countStats();
2382                        for (int j=0; j<N; j++) {
2383                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2384                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2385                                // This is definitely an application process; skip it.
2386                                continue;
2387                            }
2388                            synchronized (mPidsSelfLocked) {
2389                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2390                                    // This is one of our own processes; skip it.
2391                                    continue;
2392                                }
2393                            }
2394                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2395                        }
2396                    }
2397                    memInfo.readMemInfo();
2398                    synchronized (ActivityManagerService.this) {
2399                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2400                                + (SystemClock.uptimeMillis()-start) + "ms");
2401                        final long cachedKb = memInfo.getCachedSizeKb();
2402                        final long freeKb = memInfo.getFreeSizeKb();
2403                        final long zramKb = memInfo.getZramTotalSizeKb();
2404                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2405                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2406                                kernelKb*1024, nativeTotalPss*1024);
2407                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2408                                nativeTotalPss);
2409                    }
2410                }
2411
2412                int num = 0;
2413                long[] tmp = new long[2];
2414                do {
2415                    ProcessRecord proc;
2416                    int procState;
2417                    int pid;
2418                    long lastPssTime;
2419                    synchronized (ActivityManagerService.this) {
2420                        if (mPendingPssProcesses.size() <= 0) {
2421                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2422                                    "Collected PSS of " + num + " processes in "
2423                                    + (SystemClock.uptimeMillis() - start) + "ms");
2424                            mPendingPssProcesses.clear();
2425                            return;
2426                        }
2427                        proc = mPendingPssProcesses.remove(0);
2428                        procState = proc.pssProcState;
2429                        lastPssTime = proc.lastPssTime;
2430                        if (proc.thread != null && procState == proc.setProcState
2431                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2432                                        < SystemClock.uptimeMillis()) {
2433                            pid = proc.pid;
2434                        } else {
2435                            proc = null;
2436                            pid = 0;
2437                        }
2438                    }
2439                    if (proc != null) {
2440                        long pss = Debug.getPss(pid, tmp, null);
2441                        synchronized (ActivityManagerService.this) {
2442                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2443                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2444                                num++;
2445                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2446                                        SystemClock.uptimeMillis());
2447                            }
2448                        }
2449                    }
2450                } while (true);
2451            }
2452            }
2453        }
2454    };
2455
2456    public void setSystemProcess() {
2457        try {
2458            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2459            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2460            ServiceManager.addService("meminfo", new MemBinder(this));
2461            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2462            ServiceManager.addService("dbinfo", new DbBinder(this));
2463            if (MONITOR_CPU_USAGE) {
2464                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2465            }
2466            ServiceManager.addService("permission", new PermissionController(this));
2467            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2468
2469            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2470                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2471            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2472
2473            synchronized (this) {
2474                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2475                app.persistent = true;
2476                app.pid = MY_PID;
2477                app.maxAdj = ProcessList.SYSTEM_ADJ;
2478                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2479                synchronized (mPidsSelfLocked) {
2480                    mPidsSelfLocked.put(app.pid, app);
2481                }
2482                updateLruProcessLocked(app, false, null);
2483                updateOomAdjLocked();
2484            }
2485        } catch (PackageManager.NameNotFoundException e) {
2486            throw new RuntimeException(
2487                    "Unable to find android system package", e);
2488        }
2489    }
2490
2491    public void setWindowManager(WindowManagerService wm) {
2492        mWindowManager = wm;
2493        mStackSupervisor.setWindowManager(wm);
2494        mActivityStarter.setWindowManager(wm);
2495    }
2496
2497    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2498        mUsageStatsService = usageStatsManager;
2499    }
2500
2501    public void startObservingNativeCrashes() {
2502        final NativeCrashListener ncl = new NativeCrashListener(this);
2503        ncl.start();
2504    }
2505
2506    public IAppOpsService getAppOpsService() {
2507        return mAppOpsService;
2508    }
2509
2510    static class MemBinder extends Binder {
2511        ActivityManagerService mActivityManagerService;
2512        MemBinder(ActivityManagerService activityManagerService) {
2513            mActivityManagerService = activityManagerService;
2514        }
2515
2516        @Override
2517        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2518            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2519                    != PackageManager.PERMISSION_GRANTED) {
2520                pw.println("Permission Denial: can't dump meminfo from from pid="
2521                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2522                        + " without permission " + android.Manifest.permission.DUMP);
2523                return;
2524            }
2525
2526            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2527        }
2528    }
2529
2530    static class GraphicsBinder extends Binder {
2531        ActivityManagerService mActivityManagerService;
2532        GraphicsBinder(ActivityManagerService activityManagerService) {
2533            mActivityManagerService = activityManagerService;
2534        }
2535
2536        @Override
2537        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2538            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2539                    != PackageManager.PERMISSION_GRANTED) {
2540                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2541                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2542                        + " without permission " + android.Manifest.permission.DUMP);
2543                return;
2544            }
2545
2546            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2547        }
2548    }
2549
2550    static class DbBinder extends Binder {
2551        ActivityManagerService mActivityManagerService;
2552        DbBinder(ActivityManagerService activityManagerService) {
2553            mActivityManagerService = activityManagerService;
2554        }
2555
2556        @Override
2557        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2558            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2559                    != PackageManager.PERMISSION_GRANTED) {
2560                pw.println("Permission Denial: can't dump dbinfo from from pid="
2561                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2562                        + " without permission " + android.Manifest.permission.DUMP);
2563                return;
2564            }
2565
2566            mActivityManagerService.dumpDbInfo(fd, pw, args);
2567        }
2568    }
2569
2570    static class CpuBinder extends Binder {
2571        ActivityManagerService mActivityManagerService;
2572        CpuBinder(ActivityManagerService activityManagerService) {
2573            mActivityManagerService = activityManagerService;
2574        }
2575
2576        @Override
2577        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2578            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2579                    != PackageManager.PERMISSION_GRANTED) {
2580                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2581                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2582                        + " without permission " + android.Manifest.permission.DUMP);
2583                return;
2584            }
2585
2586            synchronized (mActivityManagerService.mProcessCpuTracker) {
2587                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2588                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2589                        SystemClock.uptimeMillis()));
2590            }
2591        }
2592    }
2593
2594    public static final class Lifecycle extends SystemService {
2595        private final ActivityManagerService mService;
2596
2597        public Lifecycle(Context context) {
2598            super(context);
2599            mService = new ActivityManagerService(context);
2600        }
2601
2602        @Override
2603        public void onStart() {
2604            mService.start();
2605        }
2606
2607        public ActivityManagerService getService() {
2608            return mService;
2609        }
2610    }
2611
2612    // Note: This method is invoked on the main thread but may need to attach various
2613    // handlers to other threads.  So take care to be explicit about the looper.
2614    public ActivityManagerService(Context systemContext) {
2615        mContext = systemContext;
2616        mFactoryTest = FactoryTest.getMode();
2617        mSystemThread = ActivityThread.currentActivityThread();
2618
2619        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2620
2621        mHandlerThread = new ServiceThread(TAG,
2622                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2623        mHandlerThread.start();
2624        mHandler = new MainHandler(mHandlerThread.getLooper());
2625        mUiHandler = new UiHandler();
2626
2627        /* static; one-time init here */
2628        if (sKillHandler == null) {
2629            sKillThread = new ServiceThread(TAG + ":kill",
2630                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2631            sKillThread.start();
2632            sKillHandler = new KillHandler(sKillThread.getLooper());
2633        }
2634
2635        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2636                "foreground", BROADCAST_FG_TIMEOUT, false);
2637        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2638                "background", BROADCAST_BG_TIMEOUT, true);
2639        mBroadcastQueues[0] = mFgBroadcastQueue;
2640        mBroadcastQueues[1] = mBgBroadcastQueue;
2641
2642        mServices = new ActiveServices(this);
2643        mProviderMap = new ProviderMap(this);
2644        mAppErrors = new AppErrors(mContext, this);
2645
2646        // TODO: Move creation of battery stats service outside of activity manager service.
2647        File dataDir = Environment.getDataDirectory();
2648        File systemDir = new File(dataDir, "system");
2649        systemDir.mkdirs();
2650        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2651        mBatteryStatsService.getActiveStatistics().readLocked();
2652        mBatteryStatsService.scheduleWriteToDisk();
2653        mOnBattery = DEBUG_POWER ? true
2654                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2655        mBatteryStatsService.getActiveStatistics().setCallback(this);
2656
2657        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2658
2659        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2660        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2661                new IAppOpsCallback.Stub() {
2662                    @Override public void opChanged(int op, int uid, String packageName) {
2663                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2664                            if (mAppOpsService.checkOperation(op, uid, packageName)
2665                                    != AppOpsManager.MODE_ALLOWED) {
2666                                runInBackgroundDisabled(uid);
2667                            }
2668                        }
2669                    }
2670                });
2671
2672        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2673
2674        mUserController = new UserController(this);
2675
2676        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2677            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2678
2679        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2680            mUseFifoUiScheduling = true;
2681        }
2682
2683        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2684
2685        mConfiguration.setToDefaults();
2686        mConfiguration.setLocales(LocaleList.getDefault());
2687
2688        mConfigurationSeq = mConfiguration.seq = 1;
2689        mProcessCpuTracker.init();
2690
2691        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2692        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2693        mStackSupervisor = new ActivityStackSupervisor(this);
2694        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2695        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2696
2697        mProcessCpuThread = new Thread("CpuTracker") {
2698            @Override
2699            public void run() {
2700                while (true) {
2701                    try {
2702                        try {
2703                            synchronized(this) {
2704                                final long now = SystemClock.uptimeMillis();
2705                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2706                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2707                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2708                                //        + ", write delay=" + nextWriteDelay);
2709                                if (nextWriteDelay < nextCpuDelay) {
2710                                    nextCpuDelay = nextWriteDelay;
2711                                }
2712                                if (nextCpuDelay > 0) {
2713                                    mProcessCpuMutexFree.set(true);
2714                                    this.wait(nextCpuDelay);
2715                                }
2716                            }
2717                        } catch (InterruptedException e) {
2718                        }
2719                        updateCpuStatsNow();
2720                    } catch (Exception e) {
2721                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2722                    }
2723                }
2724            }
2725        };
2726
2727        Watchdog.getInstance().addMonitor(this);
2728        Watchdog.getInstance().addThread(mHandler);
2729    }
2730
2731    public void setSystemServiceManager(SystemServiceManager mgr) {
2732        mSystemServiceManager = mgr;
2733    }
2734
2735    public void setInstaller(Installer installer) {
2736        mInstaller = installer;
2737    }
2738
2739    private void start() {
2740        Process.removeAllProcessGroups();
2741        mProcessCpuThread.start();
2742
2743        mBatteryStatsService.publish(mContext);
2744        mAppOpsService.publish(mContext);
2745        Slog.d("AppOps", "AppOpsService published");
2746        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2747    }
2748
2749    void onUserStoppedLocked(int userId) {
2750        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2751    }
2752
2753    public void initPowerManagement() {
2754        mStackSupervisor.initPowerManagement();
2755        mBatteryStatsService.initPowerManagement();
2756        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2757        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2758        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2759        mVoiceWakeLock.setReferenceCounted(false);
2760    }
2761
2762    @Override
2763    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2764            throws RemoteException {
2765        if (code == SYSPROPS_TRANSACTION) {
2766            // We need to tell all apps about the system property change.
2767            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2768            synchronized(this) {
2769                final int NP = mProcessNames.getMap().size();
2770                for (int ip=0; ip<NP; ip++) {
2771                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2772                    final int NA = apps.size();
2773                    for (int ia=0; ia<NA; ia++) {
2774                        ProcessRecord app = apps.valueAt(ia);
2775                        if (app.thread != null) {
2776                            procs.add(app.thread.asBinder());
2777                        }
2778                    }
2779                }
2780            }
2781
2782            int N = procs.size();
2783            for (int i=0; i<N; i++) {
2784                Parcel data2 = Parcel.obtain();
2785                try {
2786                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2787                } catch (RemoteException e) {
2788                }
2789                data2.recycle();
2790            }
2791        }
2792        try {
2793            return super.onTransact(code, data, reply, flags);
2794        } catch (RuntimeException e) {
2795            // The activity manager only throws security exceptions, so let's
2796            // log all others.
2797            if (!(e instanceof SecurityException)) {
2798                Slog.wtf(TAG, "Activity Manager Crash", e);
2799            }
2800            throw e;
2801        }
2802    }
2803
2804    void updateCpuStats() {
2805        final long now = SystemClock.uptimeMillis();
2806        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2807            return;
2808        }
2809        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2810            synchronized (mProcessCpuThread) {
2811                mProcessCpuThread.notify();
2812            }
2813        }
2814    }
2815
2816    void updateCpuStatsNow() {
2817        synchronized (mProcessCpuTracker) {
2818            mProcessCpuMutexFree.set(false);
2819            final long now = SystemClock.uptimeMillis();
2820            boolean haveNewCpuStats = false;
2821
2822            if (MONITOR_CPU_USAGE &&
2823                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2824                mLastCpuTime.set(now);
2825                mProcessCpuTracker.update();
2826                if (mProcessCpuTracker.hasGoodLastStats()) {
2827                    haveNewCpuStats = true;
2828                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2829                    //Slog.i(TAG, "Total CPU usage: "
2830                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2831
2832                    // Slog the cpu usage if the property is set.
2833                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2834                        int user = mProcessCpuTracker.getLastUserTime();
2835                        int system = mProcessCpuTracker.getLastSystemTime();
2836                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2837                        int irq = mProcessCpuTracker.getLastIrqTime();
2838                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2839                        int idle = mProcessCpuTracker.getLastIdleTime();
2840
2841                        int total = user + system + iowait + irq + softIrq + idle;
2842                        if (total == 0) total = 1;
2843
2844                        EventLog.writeEvent(EventLogTags.CPU,
2845                                ((user+system+iowait+irq+softIrq) * 100) / total,
2846                                (user * 100) / total,
2847                                (system * 100) / total,
2848                                (iowait * 100) / total,
2849                                (irq * 100) / total,
2850                                (softIrq * 100) / total);
2851                    }
2852                }
2853            }
2854
2855            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2856            synchronized(bstats) {
2857                synchronized(mPidsSelfLocked) {
2858                    if (haveNewCpuStats) {
2859                        if (bstats.startAddingCpuLocked()) {
2860                            int totalUTime = 0;
2861                            int totalSTime = 0;
2862                            final int N = mProcessCpuTracker.countStats();
2863                            for (int i=0; i<N; i++) {
2864                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2865                                if (!st.working) {
2866                                    continue;
2867                                }
2868                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2869                                totalUTime += st.rel_utime;
2870                                totalSTime += st.rel_stime;
2871                                if (pr != null) {
2872                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2873                                    if (ps == null || !ps.isActive()) {
2874                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2875                                                pr.info.uid, pr.processName);
2876                                    }
2877                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2878                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2879                                } else {
2880                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2881                                    if (ps == null || !ps.isActive()) {
2882                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2883                                                bstats.mapUid(st.uid), st.name);
2884                                    }
2885                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2886                                }
2887                            }
2888                            final int userTime = mProcessCpuTracker.getLastUserTime();
2889                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2890                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2891                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2892                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2893                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2894                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2895                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2896                        }
2897                    }
2898                }
2899
2900                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2901                    mLastWriteTime = now;
2902                    mBatteryStatsService.scheduleWriteToDisk();
2903                }
2904            }
2905        }
2906    }
2907
2908    @Override
2909    public void batteryNeedsCpuUpdate() {
2910        updateCpuStatsNow();
2911    }
2912
2913    @Override
2914    public void batteryPowerChanged(boolean onBattery) {
2915        // When plugging in, update the CPU stats first before changing
2916        // the plug state.
2917        updateCpuStatsNow();
2918        synchronized (this) {
2919            synchronized(mPidsSelfLocked) {
2920                mOnBattery = DEBUG_POWER ? true : onBattery;
2921            }
2922        }
2923    }
2924
2925    @Override
2926    public void batterySendBroadcast(Intent intent) {
2927        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2928                AppOpsManager.OP_NONE, null, false, false,
2929                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2930    }
2931
2932    /**
2933     * Initialize the application bind args. These are passed to each
2934     * process when the bindApplication() IPC is sent to the process. They're
2935     * lazily setup to make sure the services are running when they're asked for.
2936     */
2937    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2938        if (mAppBindArgs == null) {
2939            mAppBindArgs = new HashMap<>();
2940
2941            // Isolated processes won't get this optimization, so that we don't
2942            // violate the rules about which services they have access to.
2943            if (!isolated) {
2944                // Setup the application init args
2945                mAppBindArgs.put("package", ServiceManager.getService("package"));
2946                mAppBindArgs.put("window", ServiceManager.getService("window"));
2947                mAppBindArgs.put(Context.ALARM_SERVICE,
2948                        ServiceManager.getService(Context.ALARM_SERVICE));
2949            }
2950        }
2951        return mAppBindArgs;
2952    }
2953
2954    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2955        if (r == null || mFocusedActivity == r) {
2956            return false;
2957        }
2958
2959        if (!r.isFocusable()) {
2960            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2961            return false;
2962        }
2963
2964        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2965
2966        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2967        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2968                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2969        mDoingSetFocusedActivity = true;
2970
2971        final ActivityRecord last = mFocusedActivity;
2972        mFocusedActivity = r;
2973        if (r.task.isApplicationTask()) {
2974            if (mCurAppTimeTracker != r.appTimeTracker) {
2975                // We are switching app tracking.  Complete the current one.
2976                if (mCurAppTimeTracker != null) {
2977                    mCurAppTimeTracker.stop();
2978                    mHandler.obtainMessage(
2979                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2980                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2981                    mCurAppTimeTracker = null;
2982                }
2983                if (r.appTimeTracker != null) {
2984                    mCurAppTimeTracker = r.appTimeTracker;
2985                    startTimeTrackingFocusedActivityLocked();
2986                }
2987            } else {
2988                startTimeTrackingFocusedActivityLocked();
2989            }
2990        } else {
2991            r.appTimeTracker = null;
2992        }
2993        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2994        // TODO: Probably not, because we don't want to resume voice on switching
2995        // back to this activity
2996        if (r.task.voiceInteractor != null) {
2997            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2998        } else {
2999            finishRunningVoiceLocked();
3000            IVoiceInteractionSession session;
3001            if (last != null && ((session = last.task.voiceSession) != null
3002                    || (session = last.voiceSession) != null)) {
3003                // We had been in a voice interaction session, but now focused has
3004                // move to something different.  Just finish the session, we can't
3005                // return to it and retain the proper state and synchronization with
3006                // the voice interaction service.
3007                finishVoiceTask(session);
3008            }
3009        }
3010        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3011            mWindowManager.setFocusedApp(r.appToken, true);
3012        }
3013        applyUpdateLockStateLocked(r);
3014        applyUpdateVrModeLocked(r);
3015        if (mFocusedActivity.userId != mLastFocusedUserId) {
3016            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3017            mHandler.obtainMessage(
3018                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3019            mLastFocusedUserId = mFocusedActivity.userId;
3020        }
3021
3022        // Log a warning if the focused app is changed during the process. This could
3023        // indicate a problem of the focus setting logic!
3024        if (mFocusedActivity != r) Slog.w(TAG,
3025                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3026        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3027
3028        EventLogTags.writeAmFocusedActivity(
3029                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3030                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3031                reason);
3032        return true;
3033    }
3034
3035    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3036        if (mFocusedActivity != goingAway) {
3037            return;
3038        }
3039
3040        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3041        if (focusedStack != null) {
3042            final ActivityRecord top = focusedStack.topActivity();
3043            if (top != null && top.userId != mLastFocusedUserId) {
3044                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3045                mHandler.sendMessage(
3046                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3047                mLastFocusedUserId = top.userId;
3048            }
3049        }
3050
3051        // Try to move focus to another activity if possible.
3052        if (setFocusedActivityLocked(
3053                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3054            return;
3055        }
3056
3057        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3058                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3059        mFocusedActivity = null;
3060        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3061    }
3062
3063    @Override
3064    public void setFocusedStack(int stackId) {
3065        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3066        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3067        final long callingId = Binder.clearCallingIdentity();
3068        try {
3069            synchronized (this) {
3070                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3071                if (stack == null) {
3072                    return;
3073                }
3074                final ActivityRecord r = stack.topRunningActivityLocked();
3075                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3076                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3077                }
3078            }
3079        } finally {
3080            Binder.restoreCallingIdentity(callingId);
3081        }
3082    }
3083
3084    @Override
3085    public void setFocusedTask(int taskId) {
3086        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3087        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3088        final long callingId = Binder.clearCallingIdentity();
3089        try {
3090            synchronized (this) {
3091                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3092                if (task == null) {
3093                    return;
3094                }
3095                final ActivityRecord r = task.topRunningActivityLocked();
3096                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3097                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3098                }
3099            }
3100        } finally {
3101            Binder.restoreCallingIdentity(callingId);
3102        }
3103    }
3104
3105    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3106    @Override
3107    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3108        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3109        synchronized (this) {
3110            if (listener != null) {
3111                mTaskStackListeners.register(listener);
3112            }
3113        }
3114    }
3115
3116    @Override
3117    public void notifyActivityDrawn(IBinder token) {
3118        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3119        synchronized (this) {
3120            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3121            if (r != null) {
3122                r.task.stack.notifyActivityDrawnLocked(r);
3123            }
3124        }
3125    }
3126
3127    final void applyUpdateLockStateLocked(ActivityRecord r) {
3128        // Modifications to the UpdateLock state are done on our handler, outside
3129        // the activity manager's locks.  The new state is determined based on the
3130        // state *now* of the relevant activity record.  The object is passed to
3131        // the handler solely for logging detail, not to be consulted/modified.
3132        final boolean nextState = r != null && r.immersive;
3133        mHandler.sendMessage(
3134                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3135    }
3136
3137    final void applyUpdateVrModeLocked(ActivityRecord r) {
3138        mHandler.sendMessage(
3139                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3140    }
3141
3142    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3143        mHandler.sendMessage(
3144                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3145    }
3146
3147    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3148            ComponentName callingPackage, boolean immediate) {
3149        VrManagerInternal vrService =
3150                LocalServices.getService(VrManagerInternal.class);
3151        if (immediate) {
3152            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3153        } else {
3154            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3155        }
3156    }
3157
3158    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3159        Message msg = Message.obtain();
3160        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3161        msg.obj = r.task.askedCompatMode ? null : r;
3162        mUiHandler.sendMessage(msg);
3163    }
3164
3165    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3166        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3167                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3168            final Message msg = Message.obtain();
3169            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3170            msg.obj = r;
3171            mUiHandler.sendMessage(msg);
3172        }
3173    }
3174
3175    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3176            String what, Object obj, ProcessRecord srcApp) {
3177        app.lastActivityTime = now;
3178
3179        if (app.activities.size() > 0) {
3180            // Don't want to touch dependent processes that are hosting activities.
3181            return index;
3182        }
3183
3184        int lrui = mLruProcesses.lastIndexOf(app);
3185        if (lrui < 0) {
3186            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3187                    + what + " " + obj + " from " + srcApp);
3188            return index;
3189        }
3190
3191        if (lrui >= index) {
3192            // Don't want to cause this to move dependent processes *back* in the
3193            // list as if they were less frequently used.
3194            return index;
3195        }
3196
3197        if (lrui >= mLruProcessActivityStart) {
3198            // Don't want to touch dependent processes that are hosting activities.
3199            return index;
3200        }
3201
3202        mLruProcesses.remove(lrui);
3203        if (index > 0) {
3204            index--;
3205        }
3206        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3207                + " in LRU list: " + app);
3208        mLruProcesses.add(index, app);
3209        return index;
3210    }
3211
3212    static void killProcessGroup(int uid, int pid) {
3213        if (sKillHandler != null) {
3214            sKillHandler.sendMessage(
3215                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3216        } else {
3217            Slog.w(TAG, "Asked to kill process group before system bringup!");
3218            Process.killProcessGroup(uid, pid);
3219        }
3220    }
3221
3222    final void removeLruProcessLocked(ProcessRecord app) {
3223        int lrui = mLruProcesses.lastIndexOf(app);
3224        if (lrui >= 0) {
3225            if (!app.killed) {
3226                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3227                Process.killProcessQuiet(app.pid);
3228                killProcessGroup(app.uid, app.pid);
3229            }
3230            if (lrui <= mLruProcessActivityStart) {
3231                mLruProcessActivityStart--;
3232            }
3233            if (lrui <= mLruProcessServiceStart) {
3234                mLruProcessServiceStart--;
3235            }
3236            mLruProcesses.remove(lrui);
3237        }
3238    }
3239
3240    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3241            ProcessRecord client) {
3242        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3243                || app.treatLikeActivity;
3244        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3245        if (!activityChange && hasActivity) {
3246            // The process has activities, so we are only allowing activity-based adjustments
3247            // to move it.  It should be kept in the front of the list with other
3248            // processes that have activities, and we don't want those to change their
3249            // order except due to activity operations.
3250            return;
3251        }
3252
3253        mLruSeq++;
3254        final long now = SystemClock.uptimeMillis();
3255        app.lastActivityTime = now;
3256
3257        // First a quick reject: if the app is already at the position we will
3258        // put it, then there is nothing to do.
3259        if (hasActivity) {
3260            final int N = mLruProcesses.size();
3261            if (N > 0 && mLruProcesses.get(N-1) == app) {
3262                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3263                return;
3264            }
3265        } else {
3266            if (mLruProcessServiceStart > 0
3267                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3268                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3269                return;
3270            }
3271        }
3272
3273        int lrui = mLruProcesses.lastIndexOf(app);
3274
3275        if (app.persistent && lrui >= 0) {
3276            // We don't care about the position of persistent processes, as long as
3277            // they are in the list.
3278            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3279            return;
3280        }
3281
3282        /* In progress: compute new position first, so we can avoid doing work
3283           if the process is not actually going to move.  Not yet working.
3284        int addIndex;
3285        int nextIndex;
3286        boolean inActivity = false, inService = false;
3287        if (hasActivity) {
3288            // Process has activities, put it at the very tipsy-top.
3289            addIndex = mLruProcesses.size();
3290            nextIndex = mLruProcessServiceStart;
3291            inActivity = true;
3292        } else if (hasService) {
3293            // Process has services, put it at the top of the service list.
3294            addIndex = mLruProcessActivityStart;
3295            nextIndex = mLruProcessServiceStart;
3296            inActivity = true;
3297            inService = true;
3298        } else  {
3299            // Process not otherwise of interest, it goes to the top of the non-service area.
3300            addIndex = mLruProcessServiceStart;
3301            if (client != null) {
3302                int clientIndex = mLruProcesses.lastIndexOf(client);
3303                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3304                        + app);
3305                if (clientIndex >= 0 && addIndex > clientIndex) {
3306                    addIndex = clientIndex;
3307                }
3308            }
3309            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3310        }
3311
3312        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3313                + mLruProcessActivityStart + "): " + app);
3314        */
3315
3316        if (lrui >= 0) {
3317            if (lrui < mLruProcessActivityStart) {
3318                mLruProcessActivityStart--;
3319            }
3320            if (lrui < mLruProcessServiceStart) {
3321                mLruProcessServiceStart--;
3322            }
3323            /*
3324            if (addIndex > lrui) {
3325                addIndex--;
3326            }
3327            if (nextIndex > lrui) {
3328                nextIndex--;
3329            }
3330            */
3331            mLruProcesses.remove(lrui);
3332        }
3333
3334        /*
3335        mLruProcesses.add(addIndex, app);
3336        if (inActivity) {
3337            mLruProcessActivityStart++;
3338        }
3339        if (inService) {
3340            mLruProcessActivityStart++;
3341        }
3342        */
3343
3344        int nextIndex;
3345        if (hasActivity) {
3346            final int N = mLruProcesses.size();
3347            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3348                // Process doesn't have activities, but has clients with
3349                // activities...  move it up, but one below the top (the top
3350                // should always have a real activity).
3351                if (DEBUG_LRU) Slog.d(TAG_LRU,
3352                        "Adding to second-top of LRU activity list: " + app);
3353                mLruProcesses.add(N - 1, app);
3354                // To keep it from spamming the LRU list (by making a bunch of clients),
3355                // we will push down any other entries owned by the app.
3356                final int uid = app.info.uid;
3357                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3358                    ProcessRecord subProc = mLruProcesses.get(i);
3359                    if (subProc.info.uid == uid) {
3360                        // We want to push this one down the list.  If the process after
3361                        // it is for the same uid, however, don't do so, because we don't
3362                        // want them internally to be re-ordered.
3363                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3364                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3365                                    "Pushing uid " + uid + " swapping at " + i + ": "
3366                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3367                            ProcessRecord tmp = mLruProcesses.get(i);
3368                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3369                            mLruProcesses.set(i - 1, tmp);
3370                            i--;
3371                        }
3372                    } else {
3373                        // A gap, we can stop here.
3374                        break;
3375                    }
3376                }
3377            } else {
3378                // Process has activities, put it at the very tipsy-top.
3379                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3380                mLruProcesses.add(app);
3381            }
3382            nextIndex = mLruProcessServiceStart;
3383        } else if (hasService) {
3384            // Process has services, put it at the top of the service list.
3385            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3386            mLruProcesses.add(mLruProcessActivityStart, app);
3387            nextIndex = mLruProcessServiceStart;
3388            mLruProcessActivityStart++;
3389        } else  {
3390            // Process not otherwise of interest, it goes to the top of the non-service area.
3391            int index = mLruProcessServiceStart;
3392            if (client != null) {
3393                // If there is a client, don't allow the process to be moved up higher
3394                // in the list than that client.
3395                int clientIndex = mLruProcesses.lastIndexOf(client);
3396                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3397                        + " when updating " + app);
3398                if (clientIndex <= lrui) {
3399                    // Don't allow the client index restriction to push it down farther in the
3400                    // list than it already is.
3401                    clientIndex = lrui;
3402                }
3403                if (clientIndex >= 0 && index > clientIndex) {
3404                    index = clientIndex;
3405                }
3406            }
3407            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3408            mLruProcesses.add(index, app);
3409            nextIndex = index-1;
3410            mLruProcessActivityStart++;
3411            mLruProcessServiceStart++;
3412        }
3413
3414        // If the app is currently using a content provider or service,
3415        // bump those processes as well.
3416        for (int j=app.connections.size()-1; j>=0; j--) {
3417            ConnectionRecord cr = app.connections.valueAt(j);
3418            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3419                    && cr.binding.service.app != null
3420                    && cr.binding.service.app.lruSeq != mLruSeq
3421                    && !cr.binding.service.app.persistent) {
3422                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3423                        "service connection", cr, app);
3424            }
3425        }
3426        for (int j=app.conProviders.size()-1; j>=0; j--) {
3427            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3428            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3429                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3430                        "provider reference", cpr, app);
3431            }
3432        }
3433    }
3434
3435    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3436        if (uid == Process.SYSTEM_UID) {
3437            // The system gets to run in any process.  If there are multiple
3438            // processes with the same uid, just pick the first (this
3439            // should never happen).
3440            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3441            if (procs == null) return null;
3442            final int procCount = procs.size();
3443            for (int i = 0; i < procCount; i++) {
3444                final int procUid = procs.keyAt(i);
3445                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3446                    // Don't use an app process or different user process for system component.
3447                    continue;
3448                }
3449                return procs.valueAt(i);
3450            }
3451        }
3452        ProcessRecord proc = mProcessNames.get(processName, uid);
3453        if (false && proc != null && !keepIfLarge
3454                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3455                && proc.lastCachedPss >= 4000) {
3456            // Turn this condition on to cause killing to happen regularly, for testing.
3457            if (proc.baseProcessTracker != null) {
3458                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3459            }
3460            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3461        } else if (proc != null && !keepIfLarge
3462                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3463                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3464            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3465            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3466                if (proc.baseProcessTracker != null) {
3467                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3468                }
3469                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3470            }
3471        }
3472        return proc;
3473    }
3474
3475    void notifyPackageUse(String packageName, int reason) {
3476        IPackageManager pm = AppGlobals.getPackageManager();
3477        try {
3478            pm.notifyPackageUse(packageName, reason);
3479        } catch (RemoteException e) {
3480        }
3481    }
3482
3483    boolean isNextTransitionForward() {
3484        int transit = mWindowManager.getPendingAppTransition();
3485        return transit == TRANSIT_ACTIVITY_OPEN
3486                || transit == TRANSIT_TASK_OPEN
3487                || transit == TRANSIT_TASK_TO_FRONT;
3488    }
3489
3490    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3491            String processName, String abiOverride, int uid, Runnable crashHandler) {
3492        synchronized(this) {
3493            ApplicationInfo info = new ApplicationInfo();
3494            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3495            // For isolated processes, the former contains the parent's uid and the latter the
3496            // actual uid of the isolated process.
3497            // In the special case introduced by this method (which is, starting an isolated
3498            // process directly from the SystemServer without an actual parent app process) the
3499            // closest thing to a parent's uid is SYSTEM_UID.
3500            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3501            // the |isolated| logic in the ProcessRecord constructor.
3502            info.uid = Process.SYSTEM_UID;
3503            info.processName = processName;
3504            info.className = entryPoint;
3505            info.packageName = "android";
3506            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3507                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3508                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3509                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3510                    crashHandler);
3511            return proc != null ? proc.pid : 0;
3512        }
3513    }
3514
3515    final ProcessRecord startProcessLocked(String processName,
3516            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3517            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3518            boolean isolated, boolean keepIfLarge) {
3519        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3520                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3521                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3522                null /* crashHandler */);
3523    }
3524
3525    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3526            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3527            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3528            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3529        long startTime = SystemClock.elapsedRealtime();
3530        ProcessRecord app;
3531        if (!isolated) {
3532            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3533            checkTime(startTime, "startProcess: after getProcessRecord");
3534
3535            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3536                // If we are in the background, then check to see if this process
3537                // is bad.  If so, we will just silently fail.
3538                if (mAppErrors.isBadProcessLocked(info)) {
3539                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3540                            + "/" + info.processName);
3541                    return null;
3542                }
3543            } else {
3544                // When the user is explicitly starting a process, then clear its
3545                // crash count so that we won't make it bad until they see at
3546                // least one crash dialog again, and make the process good again
3547                // if it had been bad.
3548                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3549                        + "/" + info.processName);
3550                mAppErrors.resetProcessCrashTimeLocked(info);
3551                if (mAppErrors.isBadProcessLocked(info)) {
3552                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3553                            UserHandle.getUserId(info.uid), info.uid,
3554                            info.processName);
3555                    mAppErrors.clearBadProcessLocked(info);
3556                    if (app != null) {
3557                        app.bad = false;
3558                    }
3559                }
3560            }
3561        } else {
3562            // If this is an isolated process, it can't re-use an existing process.
3563            app = null;
3564        }
3565
3566        // app launch boost for big.little configurations
3567        // use cpusets to migrate freshly launched tasks to big cores
3568        nativeMigrateToBoost();
3569        mIsBoosted = true;
3570        mBoostStartTime = SystemClock.uptimeMillis();
3571        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3572        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3573
3574        // We don't have to do anything more if:
3575        // (1) There is an existing application record; and
3576        // (2) The caller doesn't think it is dead, OR there is no thread
3577        //     object attached to it so we know it couldn't have crashed; and
3578        // (3) There is a pid assigned to it, so it is either starting or
3579        //     already running.
3580        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3581                + " app=" + app + " knownToBeDead=" + knownToBeDead
3582                + " thread=" + (app != null ? app.thread : null)
3583                + " pid=" + (app != null ? app.pid : -1));
3584        if (app != null && app.pid > 0) {
3585            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3586                // We already have the app running, or are waiting for it to
3587                // come up (we have a pid but not yet its thread), so keep it.
3588                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3589                // If this is a new package in the process, add the package to the list
3590                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3591                checkTime(startTime, "startProcess: done, added package to proc");
3592                return app;
3593            }
3594
3595            // An application record is attached to a previous process,
3596            // clean it up now.
3597            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3598            checkTime(startTime, "startProcess: bad proc running, killing");
3599            killProcessGroup(app.uid, app.pid);
3600            handleAppDiedLocked(app, true, true);
3601            checkTime(startTime, "startProcess: done killing old proc");
3602        }
3603
3604        String hostingNameStr = hostingName != null
3605                ? hostingName.flattenToShortString() : null;
3606
3607        if (app == null) {
3608            checkTime(startTime, "startProcess: creating new process record");
3609            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3610            if (app == null) {
3611                Slog.w(TAG, "Failed making new process record for "
3612                        + processName + "/" + info.uid + " isolated=" + isolated);
3613                return null;
3614            }
3615            app.crashHandler = crashHandler;
3616            checkTime(startTime, "startProcess: done creating new process record");
3617        } else {
3618            // If this is a new package in the process, add the package to the list
3619            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3620            checkTime(startTime, "startProcess: added package to existing proc");
3621        }
3622
3623        // If the system is not ready yet, then hold off on starting this
3624        // process until it is.
3625        if (!mProcessesReady
3626                && !isAllowedWhileBooting(info)
3627                && !allowWhileBooting) {
3628            if (!mProcessesOnHold.contains(app)) {
3629                mProcessesOnHold.add(app);
3630            }
3631            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3632                    "System not ready, putting on hold: " + app);
3633            checkTime(startTime, "startProcess: returning with proc on hold");
3634            return app;
3635        }
3636
3637        checkTime(startTime, "startProcess: stepping in to startProcess");
3638        startProcessLocked(
3639                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3640        checkTime(startTime, "startProcess: done starting proc!");
3641        return (app.pid != 0) ? app : null;
3642    }
3643
3644    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3645        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3646    }
3647
3648    private final void startProcessLocked(ProcessRecord app,
3649            String hostingType, String hostingNameStr) {
3650        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3651                null /* entryPoint */, null /* entryPointArgs */);
3652    }
3653
3654    private final void startProcessLocked(ProcessRecord app, String hostingType,
3655            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3656        long startTime = SystemClock.elapsedRealtime();
3657        if (app.pid > 0 && app.pid != MY_PID) {
3658            checkTime(startTime, "startProcess: removing from pids map");
3659            synchronized (mPidsSelfLocked) {
3660                mPidsSelfLocked.remove(app.pid);
3661                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3662            }
3663            checkTime(startTime, "startProcess: done removing from pids map");
3664            app.setPid(0);
3665        }
3666
3667        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3668                "startProcessLocked removing on hold: " + app);
3669        mProcessesOnHold.remove(app);
3670
3671        checkTime(startTime, "startProcess: starting to update cpu stats");
3672        updateCpuStats();
3673        checkTime(startTime, "startProcess: done updating cpu stats");
3674
3675        try {
3676            try {
3677                final int userId = UserHandle.getUserId(app.uid);
3678                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3679            } catch (RemoteException e) {
3680                throw e.rethrowAsRuntimeException();
3681            }
3682
3683            int uid = app.uid;
3684            int[] gids = null;
3685            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3686            if (!app.isolated) {
3687                int[] permGids = null;
3688                try {
3689                    checkTime(startTime, "startProcess: getting gids from package manager");
3690                    final IPackageManager pm = AppGlobals.getPackageManager();
3691                    permGids = pm.getPackageGids(app.info.packageName,
3692                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3693                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3694                            MountServiceInternal.class);
3695                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3696                            app.info.packageName);
3697                } catch (RemoteException e) {
3698                    throw e.rethrowAsRuntimeException();
3699                }
3700
3701                /*
3702                 * Add shared application and profile GIDs so applications can share some
3703                 * resources like shared libraries and access user-wide resources
3704                 */
3705                if (ArrayUtils.isEmpty(permGids)) {
3706                    gids = new int[2];
3707                } else {
3708                    gids = new int[permGids.length + 2];
3709                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3710                }
3711                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3712                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3713            }
3714            checkTime(startTime, "startProcess: building args");
3715            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3716                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3717                        && mTopComponent != null
3718                        && app.processName.equals(mTopComponent.getPackageName())) {
3719                    uid = 0;
3720                }
3721                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3722                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3723                    uid = 0;
3724                }
3725            }
3726            int debugFlags = 0;
3727            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3728                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3729                // Also turn on CheckJNI for debuggable apps. It's quite
3730                // awkward to turn on otherwise.
3731                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3732            }
3733            // Run the app in safe mode if its manifest requests so or the
3734            // system is booted in safe mode.
3735            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3736                mSafeMode == true) {
3737                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3738            }
3739            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3740                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3741            }
3742            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3743            if ("true".equals(genDebugInfoProperty)) {
3744                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3745            }
3746            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3747                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3748            }
3749            if ("1".equals(SystemProperties.get("debug.assert"))) {
3750                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3751            }
3752            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3753                // Enable all debug flags required by the native debugger.
3754                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3755                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3756                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3757                mNativeDebuggingApp = null;
3758            }
3759
3760            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3761            if (requiredAbi == null) {
3762                requiredAbi = Build.SUPPORTED_ABIS[0];
3763            }
3764
3765            String instructionSet = null;
3766            if (app.info.primaryCpuAbi != null) {
3767                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3768            }
3769
3770            app.gids = gids;
3771            app.requiredAbi = requiredAbi;
3772            app.instructionSet = instructionSet;
3773
3774            // Start the process.  It will either succeed and return a result containing
3775            // the PID of the new process, or else throw a RuntimeException.
3776            boolean isActivityProcess = (entryPoint == null);
3777            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3778            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3779                    app.processName);
3780            checkTime(startTime, "startProcess: asking zygote to start proc");
3781            Process.ProcessStartResult startResult = Process.start(entryPoint,
3782                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3783                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3784                    app.info.dataDir, entryPointArgs);
3785            checkTime(startTime, "startProcess: returned from zygote!");
3786            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3787
3788            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3789            checkTime(startTime, "startProcess: done updating battery stats");
3790
3791            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3792                    UserHandle.getUserId(uid), startResult.pid, uid,
3793                    app.processName, hostingType,
3794                    hostingNameStr != null ? hostingNameStr : "");
3795
3796            try {
3797                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3798                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3799            } catch (RemoteException ex) {
3800                // Ignore
3801            }
3802
3803            if (app.persistent) {
3804                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3805            }
3806
3807            checkTime(startTime, "startProcess: building log message");
3808            StringBuilder buf = mStringBuilder;
3809            buf.setLength(0);
3810            buf.append("Start proc ");
3811            buf.append(startResult.pid);
3812            buf.append(':');
3813            buf.append(app.processName);
3814            buf.append('/');
3815            UserHandle.formatUid(buf, uid);
3816            if (!isActivityProcess) {
3817                buf.append(" [");
3818                buf.append(entryPoint);
3819                buf.append("]");
3820            }
3821            buf.append(" for ");
3822            buf.append(hostingType);
3823            if (hostingNameStr != null) {
3824                buf.append(" ");
3825                buf.append(hostingNameStr);
3826            }
3827            Slog.i(TAG, buf.toString());
3828            app.setPid(startResult.pid);
3829            app.usingWrapper = startResult.usingWrapper;
3830            app.removed = false;
3831            app.killed = false;
3832            app.killedByAm = false;
3833            checkTime(startTime, "startProcess: starting to update pids map");
3834            synchronized (mPidsSelfLocked) {
3835                this.mPidsSelfLocked.put(startResult.pid, app);
3836                if (isActivityProcess) {
3837                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3838                    msg.obj = app;
3839                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3840                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3841                }
3842            }
3843            checkTime(startTime, "startProcess: done updating pids map");
3844        } catch (RuntimeException e) {
3845            Slog.e(TAG, "Failure starting process " + app.processName, e);
3846
3847            // Something went very wrong while trying to start this process; one
3848            // common case is when the package is frozen due to an active
3849            // upgrade. To recover, clean up any active bookkeeping related to
3850            // starting this process. (We already invoked this method once when
3851            // the package was initially frozen through KILL_APPLICATION_MSG, so
3852            // it doesn't hurt to use it again.)
3853            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3854                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3855        }
3856    }
3857
3858    void updateUsageStats(ActivityRecord component, boolean resumed) {
3859        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3860                "updateUsageStats: comp=" + component + "res=" + resumed);
3861        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3862        if (resumed) {
3863            if (mUsageStatsService != null) {
3864                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3865                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3866            }
3867            synchronized (stats) {
3868                stats.noteActivityResumedLocked(component.app.uid);
3869            }
3870        } else {
3871            if (mUsageStatsService != null) {
3872                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3873                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3874            }
3875            synchronized (stats) {
3876                stats.noteActivityPausedLocked(component.app.uid);
3877            }
3878        }
3879    }
3880
3881    Intent getHomeIntent() {
3882        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3883        intent.setComponent(mTopComponent);
3884        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3885        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3886            intent.addCategory(Intent.CATEGORY_HOME);
3887        }
3888        return intent;
3889    }
3890
3891    boolean startHomeActivityLocked(int userId, String reason) {
3892        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3893                && mTopAction == null) {
3894            // We are running in factory test mode, but unable to find
3895            // the factory test app, so just sit around displaying the
3896            // error message and don't try to start anything.
3897            return false;
3898        }
3899        Intent intent = getHomeIntent();
3900        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3901        if (aInfo != null) {
3902            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3903            // Don't do this if the home app is currently being
3904            // instrumented.
3905            aInfo = new ActivityInfo(aInfo);
3906            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3907            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3908                    aInfo.applicationInfo.uid, true);
3909            if (app == null || app.instrumentationClass == null) {
3910                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3911                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3912            }
3913        } else {
3914            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3915        }
3916
3917        return true;
3918    }
3919
3920    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3921        ActivityInfo ai = null;
3922        ComponentName comp = intent.getComponent();
3923        try {
3924            if (comp != null) {
3925                // Factory test.
3926                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3927            } else {
3928                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3929                        intent,
3930                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3931                        flags, userId);
3932
3933                if (info != null) {
3934                    ai = info.activityInfo;
3935                }
3936            }
3937        } catch (RemoteException e) {
3938            // ignore
3939        }
3940
3941        return ai;
3942    }
3943
3944    /**
3945     * Starts the "new version setup screen" if appropriate.
3946     */
3947    void startSetupActivityLocked() {
3948        // Only do this once per boot.
3949        if (mCheckedForSetup) {
3950            return;
3951        }
3952
3953        // We will show this screen if the current one is a different
3954        // version than the last one shown, and we are not running in
3955        // low-level factory test mode.
3956        final ContentResolver resolver = mContext.getContentResolver();
3957        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3958                Settings.Global.getInt(resolver,
3959                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3960            mCheckedForSetup = true;
3961
3962            // See if we should be showing the platform update setup UI.
3963            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3964            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3965                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3966            if (!ris.isEmpty()) {
3967                final ResolveInfo ri = ris.get(0);
3968                String vers = ri.activityInfo.metaData != null
3969                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3970                        : null;
3971                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3972                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3973                            Intent.METADATA_SETUP_VERSION);
3974                }
3975                String lastVers = Settings.Secure.getString(
3976                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3977                if (vers != null && !vers.equals(lastVers)) {
3978                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3979                    intent.setComponent(new ComponentName(
3980                            ri.activityInfo.packageName, ri.activityInfo.name));
3981                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3982                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3983                            null, 0, 0, 0, null, false, false, null, null, null);
3984                }
3985            }
3986        }
3987    }
3988
3989    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3990        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3991    }
3992
3993    void enforceNotIsolatedCaller(String caller) {
3994        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3995            throw new SecurityException("Isolated process not allowed to call " + caller);
3996        }
3997    }
3998
3999    void enforceShellRestriction(String restriction, int userHandle) {
4000        if (Binder.getCallingUid() == Process.SHELL_UID) {
4001            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4002                throw new SecurityException("Shell does not have permission to access user "
4003                        + userHandle);
4004            }
4005        }
4006    }
4007
4008    @Override
4009    public int getFrontActivityScreenCompatMode() {
4010        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4011        synchronized (this) {
4012            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4013        }
4014    }
4015
4016    @Override
4017    public void setFrontActivityScreenCompatMode(int mode) {
4018        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4019                "setFrontActivityScreenCompatMode");
4020        synchronized (this) {
4021            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4022        }
4023    }
4024
4025    @Override
4026    public int getPackageScreenCompatMode(String packageName) {
4027        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4028        synchronized (this) {
4029            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4030        }
4031    }
4032
4033    @Override
4034    public void setPackageScreenCompatMode(String packageName, int mode) {
4035        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4036                "setPackageScreenCompatMode");
4037        synchronized (this) {
4038            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4039        }
4040    }
4041
4042    @Override
4043    public boolean getPackageAskScreenCompat(String packageName) {
4044        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4045        synchronized (this) {
4046            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4047        }
4048    }
4049
4050    @Override
4051    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4052        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4053                "setPackageAskScreenCompat");
4054        synchronized (this) {
4055            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4056        }
4057    }
4058
4059    private boolean hasUsageStatsPermission(String callingPackage) {
4060        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4061                Binder.getCallingUid(), callingPackage);
4062        if (mode == AppOpsManager.MODE_DEFAULT) {
4063            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4064                    == PackageManager.PERMISSION_GRANTED;
4065        }
4066        return mode == AppOpsManager.MODE_ALLOWED;
4067    }
4068
4069    @Override
4070    public int getPackageProcessState(String packageName, String callingPackage) {
4071        if (!hasUsageStatsPermission(callingPackage)) {
4072            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4073                    "getPackageProcessState");
4074        }
4075
4076        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4077        synchronized (this) {
4078            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4079                final ProcessRecord proc = mLruProcesses.get(i);
4080                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4081                        || procState > proc.setProcState) {
4082                    boolean found = false;
4083                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4084                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4085                            procState = proc.setProcState;
4086                            found = true;
4087                        }
4088                    }
4089                    if (proc.pkgDeps != null && !found) {
4090                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4091                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4092                                procState = proc.setProcState;
4093                                break;
4094                            }
4095                        }
4096                    }
4097                }
4098            }
4099        }
4100        return procState;
4101    }
4102
4103    @Override
4104    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4105        synchronized (this) {
4106            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4107            if (app == null) {
4108                return false;
4109            }
4110            if (app.trimMemoryLevel < level && app.thread != null &&
4111                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4112                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4113                try {
4114                    app.thread.scheduleTrimMemory(level);
4115                    app.trimMemoryLevel = level;
4116                    return true;
4117                } catch (RemoteException e) {
4118                    // Fallthrough to failure case.
4119                }
4120            }
4121        }
4122        return false;
4123    }
4124
4125    private void dispatchProcessesChanged() {
4126        int N;
4127        synchronized (this) {
4128            N = mPendingProcessChanges.size();
4129            if (mActiveProcessChanges.length < N) {
4130                mActiveProcessChanges = new ProcessChangeItem[N];
4131            }
4132            mPendingProcessChanges.toArray(mActiveProcessChanges);
4133            mPendingProcessChanges.clear();
4134            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4135                    "*** Delivering " + N + " process changes");
4136        }
4137
4138        int i = mProcessObservers.beginBroadcast();
4139        while (i > 0) {
4140            i--;
4141            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4142            if (observer != null) {
4143                try {
4144                    for (int j=0; j<N; j++) {
4145                        ProcessChangeItem item = mActiveProcessChanges[j];
4146                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4147                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4148                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4149                                    + item.uid + ": " + item.foregroundActivities);
4150                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4151                                    item.foregroundActivities);
4152                        }
4153                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4154                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4155                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4156                                    + ": " + item.processState);
4157                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4158                        }
4159                    }
4160                } catch (RemoteException e) {
4161                }
4162            }
4163        }
4164        mProcessObservers.finishBroadcast();
4165
4166        synchronized (this) {
4167            for (int j=0; j<N; j++) {
4168                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4169            }
4170        }
4171    }
4172
4173    private void dispatchProcessDied(int pid, int uid) {
4174        int i = mProcessObservers.beginBroadcast();
4175        while (i > 0) {
4176            i--;
4177            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4178            if (observer != null) {
4179                try {
4180                    observer.onProcessDied(pid, uid);
4181                } catch (RemoteException e) {
4182                }
4183            }
4184        }
4185        mProcessObservers.finishBroadcast();
4186    }
4187
4188    private void dispatchUidsChanged() {
4189        int N;
4190        synchronized (this) {
4191            N = mPendingUidChanges.size();
4192            if (mActiveUidChanges.length < N) {
4193                mActiveUidChanges = new UidRecord.ChangeItem[N];
4194            }
4195            for (int i=0; i<N; i++) {
4196                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4197                mActiveUidChanges[i] = change;
4198                if (change.uidRecord != null) {
4199                    change.uidRecord.pendingChange = null;
4200                    change.uidRecord = null;
4201                }
4202            }
4203            mPendingUidChanges.clear();
4204            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4205                    "*** Delivering " + N + " uid changes");
4206        }
4207
4208        if (mLocalPowerManager != null) {
4209            for (int j=0; j<N; j++) {
4210                UidRecord.ChangeItem item = mActiveUidChanges[j];
4211                if (item.change == UidRecord.CHANGE_GONE
4212                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4213                    mLocalPowerManager.uidGone(item.uid);
4214                } else {
4215                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4216                }
4217            }
4218        }
4219
4220        int i = mUidObservers.beginBroadcast();
4221        while (i > 0) {
4222            i--;
4223            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4224            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4225            if (observer != null) {
4226                try {
4227                    for (int j=0; j<N; j++) {
4228                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4229                        final int change = item.change;
4230                        UidRecord validateUid = null;
4231                        if (VALIDATE_UID_STATES && i == 0) {
4232                            validateUid = mValidateUids.get(item.uid);
4233                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4234                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4235                                validateUid = new UidRecord(item.uid);
4236                                mValidateUids.put(item.uid, validateUid);
4237                            }
4238                        }
4239                        if (change == UidRecord.CHANGE_IDLE
4240                                || change == UidRecord.CHANGE_GONE_IDLE) {
4241                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4242                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4243                                        "UID idle uid=" + item.uid);
4244                                observer.onUidIdle(item.uid);
4245                            }
4246                            if (VALIDATE_UID_STATES && i == 0) {
4247                                if (validateUid != null) {
4248                                    validateUid.idle = true;
4249                                }
4250                            }
4251                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4252                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4253                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4254                                        "UID active uid=" + item.uid);
4255                                observer.onUidActive(item.uid);
4256                            }
4257                            if (VALIDATE_UID_STATES && i == 0) {
4258                                validateUid.idle = false;
4259                            }
4260                        }
4261                        if (change == UidRecord.CHANGE_GONE
4262                                || change == UidRecord.CHANGE_GONE_IDLE) {
4263                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4264                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4265                                        "UID gone uid=" + item.uid);
4266                                observer.onUidGone(item.uid);
4267                            }
4268                            if (VALIDATE_UID_STATES && i == 0) {
4269                                if (validateUid != null) {
4270                                    mValidateUids.remove(item.uid);
4271                                }
4272                            }
4273                        } else {
4274                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4275                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4276                                        "UID CHANGED uid=" + item.uid
4277                                                + ": " + item.processState);
4278                                observer.onUidStateChanged(item.uid, item.processState);
4279                            }
4280                            if (VALIDATE_UID_STATES && i == 0) {
4281                                validateUid.curProcState = validateUid.setProcState
4282                                        = item.processState;
4283                            }
4284                        }
4285                    }
4286                } catch (RemoteException e) {
4287                }
4288            }
4289        }
4290        mUidObservers.finishBroadcast();
4291
4292        synchronized (this) {
4293            for (int j=0; j<N; j++) {
4294                mAvailUidChanges.add(mActiveUidChanges[j]);
4295            }
4296        }
4297    }
4298
4299    @Override
4300    public final int startActivity(IApplicationThread caller, String callingPackage,
4301            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4302            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4303        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4304                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4305                UserHandle.getCallingUserId());
4306    }
4307
4308    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4309        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4310        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4311                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4312                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4313
4314        // TODO: Switch to user app stacks here.
4315        String mimeType = intent.getType();
4316        final Uri data = intent.getData();
4317        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4318            mimeType = getProviderMimeType(data, userId);
4319        }
4320        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4321
4322        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4323        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4324                null, 0, 0, null, null, null, null, false, userId, container, null);
4325    }
4326
4327    @Override
4328    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4329            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4330            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4331        enforceNotIsolatedCaller("startActivity");
4332        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4333                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4334        // TODO: Switch to user app stacks here.
4335        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4336                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4337                profilerInfo, null, null, bOptions, false, userId, null, null);
4338    }
4339
4340    @Override
4341    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4342            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4343            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4344            int userId) {
4345
4346        // This is very dangerous -- it allows you to perform a start activity (including
4347        // permission grants) as any app that may launch one of your own activities.  So
4348        // we will only allow this to be done from activities that are part of the core framework,
4349        // and then only when they are running as the system.
4350        final ActivityRecord sourceRecord;
4351        final int targetUid;
4352        final String targetPackage;
4353        synchronized (this) {
4354            if (resultTo == null) {
4355                throw new SecurityException("Must be called from an activity");
4356            }
4357            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4358            if (sourceRecord == null) {
4359                throw new SecurityException("Called with bad activity token: " + resultTo);
4360            }
4361            if (!sourceRecord.info.packageName.equals("android")) {
4362                throw new SecurityException(
4363                        "Must be called from an activity that is declared in the android package");
4364            }
4365            if (sourceRecord.app == null) {
4366                throw new SecurityException("Called without a process attached to activity");
4367            }
4368            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4369                // This is still okay, as long as this activity is running under the
4370                // uid of the original calling activity.
4371                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4372                    throw new SecurityException(
4373                            "Calling activity in uid " + sourceRecord.app.uid
4374                                    + " must be system uid or original calling uid "
4375                                    + sourceRecord.launchedFromUid);
4376                }
4377            }
4378            if (ignoreTargetSecurity) {
4379                if (intent.getComponent() == null) {
4380                    throw new SecurityException(
4381                            "Component must be specified with ignoreTargetSecurity");
4382                }
4383                if (intent.getSelector() != null) {
4384                    throw new SecurityException(
4385                            "Selector not allowed with ignoreTargetSecurity");
4386                }
4387            }
4388            targetUid = sourceRecord.launchedFromUid;
4389            targetPackage = sourceRecord.launchedFromPackage;
4390        }
4391
4392        if (userId == UserHandle.USER_NULL) {
4393            userId = UserHandle.getUserId(sourceRecord.app.uid);
4394        }
4395
4396        // TODO: Switch to user app stacks here.
4397        try {
4398            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4399                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4400                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4401            return ret;
4402        } catch (SecurityException e) {
4403            // XXX need to figure out how to propagate to original app.
4404            // A SecurityException here is generally actually a fault of the original
4405            // calling activity (such as a fairly granting permissions), so propagate it
4406            // back to them.
4407            /*
4408            StringBuilder msg = new StringBuilder();
4409            msg.append("While launching");
4410            msg.append(intent.toString());
4411            msg.append(": ");
4412            msg.append(e.getMessage());
4413            */
4414            throw e;
4415        }
4416    }
4417
4418    @Override
4419    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4420            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4421            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4422        enforceNotIsolatedCaller("startActivityAndWait");
4423        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4424                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4425        WaitResult res = new WaitResult();
4426        // TODO: Switch to user app stacks here.
4427        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4428                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4429                bOptions, false, userId, null, null);
4430        return res;
4431    }
4432
4433    @Override
4434    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4435            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4436            int startFlags, Configuration config, Bundle bOptions, int userId) {
4437        enforceNotIsolatedCaller("startActivityWithConfig");
4438        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4439                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4440        // TODO: Switch to user app stacks here.
4441        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4442                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4443                null, null, config, bOptions, false, userId, null, null);
4444        return ret;
4445    }
4446
4447    @Override
4448    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4449            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4450            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4451            throws TransactionTooLargeException {
4452        enforceNotIsolatedCaller("startActivityIntentSender");
4453        // Refuse possible leaked file descriptors
4454        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4455            throw new IllegalArgumentException("File descriptors passed in Intent");
4456        }
4457
4458        IIntentSender sender = intent.getTarget();
4459        if (!(sender instanceof PendingIntentRecord)) {
4460            throw new IllegalArgumentException("Bad PendingIntent object");
4461        }
4462
4463        PendingIntentRecord pir = (PendingIntentRecord)sender;
4464
4465        synchronized (this) {
4466            // If this is coming from the currently resumed activity, it is
4467            // effectively saying that app switches are allowed at this point.
4468            final ActivityStack stack = getFocusedStack();
4469            if (stack.mResumedActivity != null &&
4470                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4471                mAppSwitchesAllowedTime = 0;
4472            }
4473        }
4474        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4475                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4476        return ret;
4477    }
4478
4479    @Override
4480    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4481            Intent intent, String resolvedType, IVoiceInteractionSession session,
4482            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4483            Bundle bOptions, int userId) {
4484        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4485                != PackageManager.PERMISSION_GRANTED) {
4486            String msg = "Permission Denial: startVoiceActivity() from pid="
4487                    + Binder.getCallingPid()
4488                    + ", uid=" + Binder.getCallingUid()
4489                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4490            Slog.w(TAG, msg);
4491            throw new SecurityException(msg);
4492        }
4493        if (session == null || interactor == null) {
4494            throw new NullPointerException("null session or interactor");
4495        }
4496        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4497                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4498        // TODO: Switch to user app stacks here.
4499        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4500                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4501                null, bOptions, false, userId, null, null);
4502    }
4503
4504    @Override
4505    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4506            throws RemoteException {
4507        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4508        synchronized (this) {
4509            ActivityRecord activity = getFocusedStack().topActivity();
4510            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4511                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4512            }
4513            if (mRunningVoice != null || activity.task.voiceSession != null
4514                    || activity.voiceSession != null) {
4515                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4516                return;
4517            }
4518            if (activity.pendingVoiceInteractionStart) {
4519                Slog.w(TAG, "Pending start of voice interaction already.");
4520                return;
4521            }
4522            activity.pendingVoiceInteractionStart = true;
4523        }
4524        LocalServices.getService(VoiceInteractionManagerInternal.class)
4525                .startLocalVoiceInteraction(callingActivity, options);
4526    }
4527
4528    @Override
4529    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4530        LocalServices.getService(VoiceInteractionManagerInternal.class)
4531                .stopLocalVoiceInteraction(callingActivity);
4532    }
4533
4534    @Override
4535    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4536        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4537                .supportsLocalVoiceInteraction();
4538    }
4539
4540    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4541            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4542        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4543        if (activityToCallback == null) return;
4544        activityToCallback.setVoiceSessionLocked(voiceSession);
4545
4546        // Inform the activity
4547        try {
4548            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4549                    voiceInteractor);
4550            long token = Binder.clearCallingIdentity();
4551            try {
4552                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4553            } finally {
4554                Binder.restoreCallingIdentity(token);
4555            }
4556            // TODO: VI Should we cache the activity so that it's easier to find later
4557            // rather than scan through all the stacks and activities?
4558        } catch (RemoteException re) {
4559            activityToCallback.clearVoiceSessionLocked();
4560            // TODO: VI Should this terminate the voice session?
4561        }
4562    }
4563
4564    @Override
4565    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4566        synchronized (this) {
4567            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4568                if (keepAwake) {
4569                    mVoiceWakeLock.acquire();
4570                } else {
4571                    mVoiceWakeLock.release();
4572                }
4573            }
4574        }
4575    }
4576
4577    @Override
4578    public boolean startNextMatchingActivity(IBinder callingActivity,
4579            Intent intent, Bundle bOptions) {
4580        // Refuse possible leaked file descriptors
4581        if (intent != null && intent.hasFileDescriptors() == true) {
4582            throw new IllegalArgumentException("File descriptors passed in Intent");
4583        }
4584        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4585
4586        synchronized (this) {
4587            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4588            if (r == null) {
4589                ActivityOptions.abort(options);
4590                return false;
4591            }
4592            if (r.app == null || r.app.thread == null) {
4593                // The caller is not running...  d'oh!
4594                ActivityOptions.abort(options);
4595                return false;
4596            }
4597            intent = new Intent(intent);
4598            // The caller is not allowed to change the data.
4599            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4600            // And we are resetting to find the next component...
4601            intent.setComponent(null);
4602
4603            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4604
4605            ActivityInfo aInfo = null;
4606            try {
4607                List<ResolveInfo> resolves =
4608                    AppGlobals.getPackageManager().queryIntentActivities(
4609                            intent, r.resolvedType,
4610                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4611                            UserHandle.getCallingUserId()).getList();
4612
4613                // Look for the original activity in the list...
4614                final int N = resolves != null ? resolves.size() : 0;
4615                for (int i=0; i<N; i++) {
4616                    ResolveInfo rInfo = resolves.get(i);
4617                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4618                            && rInfo.activityInfo.name.equals(r.info.name)) {
4619                        // We found the current one...  the next matching is
4620                        // after it.
4621                        i++;
4622                        if (i<N) {
4623                            aInfo = resolves.get(i).activityInfo;
4624                        }
4625                        if (debug) {
4626                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4627                                    + "/" + r.info.name);
4628                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4629                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4630                        }
4631                        break;
4632                    }
4633                }
4634            } catch (RemoteException e) {
4635            }
4636
4637            if (aInfo == null) {
4638                // Nobody who is next!
4639                ActivityOptions.abort(options);
4640                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4641                return false;
4642            }
4643
4644            intent.setComponent(new ComponentName(
4645                    aInfo.applicationInfo.packageName, aInfo.name));
4646            intent.setFlags(intent.getFlags()&~(
4647                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4648                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4649                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4650                    Intent.FLAG_ACTIVITY_NEW_TASK));
4651
4652            // Okay now we need to start the new activity, replacing the
4653            // currently running activity.  This is a little tricky because
4654            // we want to start the new one as if the current one is finished,
4655            // but not finish the current one first so that there is no flicker.
4656            // And thus...
4657            final boolean wasFinishing = r.finishing;
4658            r.finishing = true;
4659
4660            // Propagate reply information over to the new activity.
4661            final ActivityRecord resultTo = r.resultTo;
4662            final String resultWho = r.resultWho;
4663            final int requestCode = r.requestCode;
4664            r.resultTo = null;
4665            if (resultTo != null) {
4666                resultTo.removeResultsLocked(r, resultWho, requestCode);
4667            }
4668
4669            final long origId = Binder.clearCallingIdentity();
4670            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4671                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4672                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4673                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4674                    false, false, null, null, null);
4675            Binder.restoreCallingIdentity(origId);
4676
4677            r.finishing = wasFinishing;
4678            if (res != ActivityManager.START_SUCCESS) {
4679                return false;
4680            }
4681            return true;
4682        }
4683    }
4684
4685    @Override
4686    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4687        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4688            String msg = "Permission Denial: startActivityFromRecents called without " +
4689                    START_TASKS_FROM_RECENTS;
4690            Slog.w(TAG, msg);
4691            throw new SecurityException(msg);
4692        }
4693        final long origId = Binder.clearCallingIdentity();
4694        try {
4695            synchronized (this) {
4696                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4697            }
4698        } finally {
4699            Binder.restoreCallingIdentity(origId);
4700        }
4701    }
4702
4703    final int startActivityInPackage(int uid, String callingPackage,
4704            Intent intent, String resolvedType, IBinder resultTo,
4705            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4706            IActivityContainer container, TaskRecord inTask) {
4707
4708        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4709                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4710
4711        // TODO: Switch to user app stacks here.
4712        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4713                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4714                null, null, null, bOptions, false, userId, container, inTask);
4715        return ret;
4716    }
4717
4718    @Override
4719    public final int startActivities(IApplicationThread caller, String callingPackage,
4720            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4721            int userId) {
4722        enforceNotIsolatedCaller("startActivities");
4723        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4724                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4725        // TODO: Switch to user app stacks here.
4726        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4727                resolvedTypes, resultTo, bOptions, userId);
4728        return ret;
4729    }
4730
4731    final int startActivitiesInPackage(int uid, String callingPackage,
4732            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4733            Bundle bOptions, int userId) {
4734
4735        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4736                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4737        // TODO: Switch to user app stacks here.
4738        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4739                resultTo, bOptions, userId);
4740        return ret;
4741    }
4742
4743    @Override
4744    public void reportActivityFullyDrawn(IBinder token) {
4745        synchronized (this) {
4746            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4747            if (r == null) {
4748                return;
4749            }
4750            r.reportFullyDrawnLocked();
4751        }
4752    }
4753
4754    @Override
4755    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4756        synchronized (this) {
4757            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4758            if (r == null) {
4759                return;
4760            }
4761            TaskRecord task = r.task;
4762            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4763                // Fixed screen orientation isn't supported when activities aren't in full screen
4764                // mode.
4765                return;
4766            }
4767            final long origId = Binder.clearCallingIdentity();
4768            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4769            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4770                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4771            if (config != null) {
4772                r.frozenBeforeDestroy = true;
4773                if (!updateConfigurationLocked(config, r, false)) {
4774                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4775                }
4776            }
4777            Binder.restoreCallingIdentity(origId);
4778        }
4779    }
4780
4781    @Override
4782    public int getRequestedOrientation(IBinder token) {
4783        synchronized (this) {
4784            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4785            if (r == null) {
4786                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4787            }
4788            return mWindowManager.getAppOrientation(r.appToken);
4789        }
4790    }
4791
4792    /**
4793     * This is the internal entry point for handling Activity.finish().
4794     *
4795     * @param token The Binder token referencing the Activity we want to finish.
4796     * @param resultCode Result code, if any, from this Activity.
4797     * @param resultData Result data (Intent), if any, from this Activity.
4798     * @param finishTask Whether to finish the task associated with this Activity.
4799     *
4800     * @return Returns true if the activity successfully finished, or false if it is still running.
4801     */
4802    @Override
4803    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4804            int finishTask) {
4805        // Refuse possible leaked file descriptors
4806        if (resultData != null && resultData.hasFileDescriptors() == true) {
4807            throw new IllegalArgumentException("File descriptors passed in Intent");
4808        }
4809
4810        synchronized(this) {
4811            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4812            if (r == null) {
4813                return true;
4814            }
4815            // Keep track of the root activity of the task before we finish it
4816            TaskRecord tr = r.task;
4817            ActivityRecord rootR = tr.getRootActivity();
4818            if (rootR == null) {
4819                Slog.w(TAG, "Finishing task with all activities already finished");
4820            }
4821            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4822            // finish.
4823            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4824                    mStackSupervisor.isLastLockedTask(tr)) {
4825                Slog.i(TAG, "Not finishing task in lock task mode");
4826                mStackSupervisor.showLockTaskToast();
4827                return false;
4828            }
4829            if (mController != null) {
4830                // Find the first activity that is not finishing.
4831                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4832                if (next != null) {
4833                    // ask watcher if this is allowed
4834                    boolean resumeOK = true;
4835                    try {
4836                        resumeOK = mController.activityResuming(next.packageName);
4837                    } catch (RemoteException e) {
4838                        mController = null;
4839                        Watchdog.getInstance().setActivityController(null);
4840                    }
4841
4842                    if (!resumeOK) {
4843                        Slog.i(TAG, "Not finishing activity because controller resumed");
4844                        return false;
4845                    }
4846                }
4847            }
4848            final long origId = Binder.clearCallingIdentity();
4849            try {
4850                boolean res;
4851                final boolean finishWithRootActivity =
4852                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4853                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4854                        || (finishWithRootActivity && r == rootR)) {
4855                    // If requested, remove the task that is associated to this activity only if it
4856                    // was the root activity in the task. The result code and data is ignored
4857                    // because we don't support returning them across task boundaries. Also, to
4858                    // keep backwards compatibility we remove the task from recents when finishing
4859                    // task with root activity.
4860                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4861                    if (!res) {
4862                        Slog.i(TAG, "Removing task failed to finish activity");
4863                    }
4864                } else {
4865                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4866                            resultData, "app-request", true);
4867                    if (!res) {
4868                        Slog.i(TAG, "Failed to finish by app-request");
4869                    }
4870                }
4871                return res;
4872            } finally {
4873                Binder.restoreCallingIdentity(origId);
4874            }
4875        }
4876    }
4877
4878    @Override
4879    public final void finishHeavyWeightApp() {
4880        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4881                != PackageManager.PERMISSION_GRANTED) {
4882            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4883                    + Binder.getCallingPid()
4884                    + ", uid=" + Binder.getCallingUid()
4885                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4886            Slog.w(TAG, msg);
4887            throw new SecurityException(msg);
4888        }
4889
4890        synchronized(this) {
4891            if (mHeavyWeightProcess == null) {
4892                return;
4893            }
4894
4895            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4896            for (int i = 0; i < activities.size(); i++) {
4897                ActivityRecord r = activities.get(i);
4898                if (!r.finishing && r.isInStackLocked()) {
4899                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4900                            null, "finish-heavy", true);
4901                }
4902            }
4903
4904            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4905                    mHeavyWeightProcess.userId, 0));
4906            mHeavyWeightProcess = null;
4907        }
4908    }
4909
4910    @Override
4911    public void crashApplication(int uid, int initialPid, String packageName,
4912            String message) {
4913        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4914                != PackageManager.PERMISSION_GRANTED) {
4915            String msg = "Permission Denial: crashApplication() from pid="
4916                    + Binder.getCallingPid()
4917                    + ", uid=" + Binder.getCallingUid()
4918                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4919            Slog.w(TAG, msg);
4920            throw new SecurityException(msg);
4921        }
4922
4923        synchronized(this) {
4924            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4925        }
4926    }
4927
4928    @Override
4929    public final void finishSubActivity(IBinder token, String resultWho,
4930            int requestCode) {
4931        synchronized(this) {
4932            final long origId = Binder.clearCallingIdentity();
4933            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4934            if (r != null) {
4935                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4936            }
4937            Binder.restoreCallingIdentity(origId);
4938        }
4939    }
4940
4941    @Override
4942    public boolean finishActivityAffinity(IBinder token) {
4943        synchronized(this) {
4944            final long origId = Binder.clearCallingIdentity();
4945            try {
4946                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4947                if (r == null) {
4948                    return false;
4949                }
4950
4951                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4952                // can finish.
4953                final TaskRecord task = r.task;
4954                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4955                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4956                    mStackSupervisor.showLockTaskToast();
4957                    return false;
4958                }
4959                return task.stack.finishActivityAffinityLocked(r);
4960            } finally {
4961                Binder.restoreCallingIdentity(origId);
4962            }
4963        }
4964    }
4965
4966    @Override
4967    public void finishVoiceTask(IVoiceInteractionSession session) {
4968        synchronized (this) {
4969            final long origId = Binder.clearCallingIdentity();
4970            try {
4971                // TODO: VI Consider treating local voice interactions and voice tasks
4972                // differently here
4973                mStackSupervisor.finishVoiceTask(session);
4974            } finally {
4975                Binder.restoreCallingIdentity(origId);
4976            }
4977        }
4978
4979    }
4980
4981    @Override
4982    public boolean releaseActivityInstance(IBinder token) {
4983        synchronized(this) {
4984            final long origId = Binder.clearCallingIdentity();
4985            try {
4986                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4987                if (r == null) {
4988                    return false;
4989                }
4990                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4991            } finally {
4992                Binder.restoreCallingIdentity(origId);
4993            }
4994        }
4995    }
4996
4997    @Override
4998    public void releaseSomeActivities(IApplicationThread appInt) {
4999        synchronized(this) {
5000            final long origId = Binder.clearCallingIdentity();
5001            try {
5002                ProcessRecord app = getRecordForAppLocked(appInt);
5003                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5004            } finally {
5005                Binder.restoreCallingIdentity(origId);
5006            }
5007        }
5008    }
5009
5010    @Override
5011    public boolean willActivityBeVisible(IBinder token) {
5012        synchronized(this) {
5013            ActivityStack stack = ActivityRecord.getStackLocked(token);
5014            if (stack != null) {
5015                return stack.willActivityBeVisibleLocked(token);
5016            }
5017            return false;
5018        }
5019    }
5020
5021    @Override
5022    public void overridePendingTransition(IBinder token, String packageName,
5023            int enterAnim, int exitAnim) {
5024        synchronized(this) {
5025            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5026            if (self == null) {
5027                return;
5028            }
5029
5030            final long origId = Binder.clearCallingIdentity();
5031
5032            if (self.state == ActivityState.RESUMED
5033                    || self.state == ActivityState.PAUSING) {
5034                mWindowManager.overridePendingAppTransition(packageName,
5035                        enterAnim, exitAnim, null);
5036            }
5037
5038            Binder.restoreCallingIdentity(origId);
5039        }
5040    }
5041
5042    /**
5043     * Main function for removing an existing process from the activity manager
5044     * as a result of that process going away.  Clears out all connections
5045     * to the process.
5046     */
5047    private final void handleAppDiedLocked(ProcessRecord app,
5048            boolean restarting, boolean allowRestart) {
5049        int pid = app.pid;
5050        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5051        if (!kept && !restarting) {
5052            removeLruProcessLocked(app);
5053            if (pid > 0) {
5054                ProcessList.remove(pid);
5055            }
5056        }
5057
5058        if (mProfileProc == app) {
5059            clearProfilerLocked();
5060        }
5061
5062        // Remove this application's activities from active lists.
5063        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5064
5065        app.activities.clear();
5066
5067        if (app.instrumentationClass != null) {
5068            Slog.w(TAG, "Crash of app " + app.processName
5069                  + " running instrumentation " + app.instrumentationClass);
5070            Bundle info = new Bundle();
5071            info.putString("shortMsg", "Process crashed.");
5072            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5073        }
5074
5075        if (!restarting && hasVisibleActivities
5076                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5077            // If there was nothing to resume, and we are not already restarting this process, but
5078            // there is a visible activity that is hosted by the process...  then make sure all
5079            // visible activities are running, taking care of restarting this process.
5080            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5081        }
5082    }
5083
5084    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5085        IBinder threadBinder = thread.asBinder();
5086        // Find the application record.
5087        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5088            ProcessRecord rec = mLruProcesses.get(i);
5089            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5090                return i;
5091            }
5092        }
5093        return -1;
5094    }
5095
5096    final ProcessRecord getRecordForAppLocked(
5097            IApplicationThread thread) {
5098        if (thread == null) {
5099            return null;
5100        }
5101
5102        int appIndex = getLRURecordIndexForAppLocked(thread);
5103        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5104    }
5105
5106    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5107        // If there are no longer any background processes running,
5108        // and the app that died was not running instrumentation,
5109        // then tell everyone we are now low on memory.
5110        boolean haveBg = false;
5111        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5112            ProcessRecord rec = mLruProcesses.get(i);
5113            if (rec.thread != null
5114                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5115                haveBg = true;
5116                break;
5117            }
5118        }
5119
5120        if (!haveBg) {
5121            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5122            if (doReport) {
5123                long now = SystemClock.uptimeMillis();
5124                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5125                    doReport = false;
5126                } else {
5127                    mLastMemUsageReportTime = now;
5128                }
5129            }
5130            final ArrayList<ProcessMemInfo> memInfos
5131                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5132            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5133            long now = SystemClock.uptimeMillis();
5134            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5135                ProcessRecord rec = mLruProcesses.get(i);
5136                if (rec == dyingProc || rec.thread == null) {
5137                    continue;
5138                }
5139                if (doReport) {
5140                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5141                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5142                }
5143                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5144                    // The low memory report is overriding any current
5145                    // state for a GC request.  Make sure to do
5146                    // heavy/important/visible/foreground processes first.
5147                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5148                        rec.lastRequestedGc = 0;
5149                    } else {
5150                        rec.lastRequestedGc = rec.lastLowMemory;
5151                    }
5152                    rec.reportLowMemory = true;
5153                    rec.lastLowMemory = now;
5154                    mProcessesToGc.remove(rec);
5155                    addProcessToGcListLocked(rec);
5156                }
5157            }
5158            if (doReport) {
5159                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5160                mHandler.sendMessage(msg);
5161            }
5162            scheduleAppGcsLocked();
5163        }
5164    }
5165
5166    final void appDiedLocked(ProcessRecord app) {
5167       appDiedLocked(app, app.pid, app.thread, false);
5168    }
5169
5170    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5171            boolean fromBinderDied) {
5172        // First check if this ProcessRecord is actually active for the pid.
5173        synchronized (mPidsSelfLocked) {
5174            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5175            if (curProc != app) {
5176                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5177                return;
5178            }
5179        }
5180
5181        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5182        synchronized (stats) {
5183            stats.noteProcessDiedLocked(app.info.uid, pid);
5184        }
5185
5186        if (!app.killed) {
5187            if (!fromBinderDied) {
5188                Process.killProcessQuiet(pid);
5189            }
5190            killProcessGroup(app.uid, pid);
5191            app.killed = true;
5192        }
5193
5194        // Clean up already done if the process has been re-started.
5195        if (app.pid == pid && app.thread != null &&
5196                app.thread.asBinder() == thread.asBinder()) {
5197            boolean doLowMem = app.instrumentationClass == null;
5198            boolean doOomAdj = doLowMem;
5199            if (!app.killedByAm) {
5200                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5201                        + ") has died");
5202                mAllowLowerMemLevel = true;
5203            } else {
5204                // Note that we always want to do oom adj to update our state with the
5205                // new number of procs.
5206                mAllowLowerMemLevel = false;
5207                doLowMem = false;
5208            }
5209            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5210            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5211                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5212            handleAppDiedLocked(app, false, true);
5213
5214            if (doOomAdj) {
5215                updateOomAdjLocked();
5216            }
5217            if (doLowMem) {
5218                doLowMemReportIfNeededLocked(app);
5219            }
5220        } else if (app.pid != pid) {
5221            // A new process has already been started.
5222            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5223                    + ") has died and restarted (pid " + app.pid + ").");
5224            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5225        } else if (DEBUG_PROCESSES) {
5226            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5227                    + thread.asBinder());
5228        }
5229    }
5230
5231    /**
5232     * If a stack trace dump file is configured, dump process stack traces.
5233     * @param clearTraces causes the dump file to be erased prior to the new
5234     *    traces being written, if true; when false, the new traces will be
5235     *    appended to any existing file content.
5236     * @param firstPids of dalvik VM processes to dump stack traces for first
5237     * @param lastPids of dalvik VM processes to dump stack traces for last
5238     * @param nativeProcs optional list of native process names to dump stack crawls
5239     * @return file containing stack traces, or null if no dump file is configured
5240     */
5241    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5242            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5243        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5244        if (tracesPath == null || tracesPath.length() == 0) {
5245            return null;
5246        }
5247
5248        File tracesFile = new File(tracesPath);
5249        try {
5250            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5251            tracesFile.createNewFile();
5252            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5253        } catch (IOException e) {
5254            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5255            return null;
5256        }
5257
5258        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5259        return tracesFile;
5260    }
5261
5262    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5263            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5264        // Use a FileObserver to detect when traces finish writing.
5265        // The order of traces is considered important to maintain for legibility.
5266        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5267            @Override
5268            public synchronized void onEvent(int event, String path) { notify(); }
5269        };
5270
5271        try {
5272            observer.startWatching();
5273
5274            // First collect all of the stacks of the most important pids.
5275            if (firstPids != null) {
5276                try {
5277                    int num = firstPids.size();
5278                    for (int i = 0; i < num; i++) {
5279                        synchronized (observer) {
5280                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5281                                    + firstPids.get(i));
5282                            final long sime = SystemClock.elapsedRealtime();
5283                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5284                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5285                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5286                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5287                        }
5288                    }
5289                } catch (InterruptedException e) {
5290                    Slog.wtf(TAG, e);
5291                }
5292            }
5293
5294            // Next collect the stacks of the native pids
5295            if (nativeProcs != null) {
5296                int[] pids = Process.getPidsForCommands(nativeProcs);
5297                if (pids != null) {
5298                    for (int pid : pids) {
5299                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5300                        final long sime = SystemClock.elapsedRealtime();
5301                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5302                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5303                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5304                    }
5305                }
5306            }
5307
5308            // Lastly, measure CPU usage.
5309            if (processCpuTracker != null) {
5310                processCpuTracker.init();
5311                System.gc();
5312                processCpuTracker.update();
5313                try {
5314                    synchronized (processCpuTracker) {
5315                        processCpuTracker.wait(500); // measure over 1/2 second.
5316                    }
5317                } catch (InterruptedException e) {
5318                }
5319                processCpuTracker.update();
5320
5321                // We'll take the stack crawls of just the top apps using CPU.
5322                final int N = processCpuTracker.countWorkingStats();
5323                int numProcs = 0;
5324                for (int i=0; i<N && numProcs<5; i++) {
5325                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5326                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5327                        numProcs++;
5328                        try {
5329                            synchronized (observer) {
5330                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5331                                        + stats.pid);
5332                                final long stime = SystemClock.elapsedRealtime();
5333                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5334                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5335                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5336                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5337                            }
5338                        } catch (InterruptedException e) {
5339                            Slog.wtf(TAG, e);
5340                        }
5341                    } else if (DEBUG_ANR) {
5342                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5343                                + stats.pid);
5344                    }
5345                }
5346            }
5347        } finally {
5348            observer.stopWatching();
5349        }
5350    }
5351
5352    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5353        if (true || IS_USER_BUILD) {
5354            return;
5355        }
5356        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5357        if (tracesPath == null || tracesPath.length() == 0) {
5358            return;
5359        }
5360
5361        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5362        StrictMode.allowThreadDiskWrites();
5363        try {
5364            final File tracesFile = new File(tracesPath);
5365            final File tracesDir = tracesFile.getParentFile();
5366            final File tracesTmp = new File(tracesDir, "__tmp__");
5367            try {
5368                if (tracesFile.exists()) {
5369                    tracesTmp.delete();
5370                    tracesFile.renameTo(tracesTmp);
5371                }
5372                StringBuilder sb = new StringBuilder();
5373                Time tobj = new Time();
5374                tobj.set(System.currentTimeMillis());
5375                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5376                sb.append(": ");
5377                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5378                sb.append(" since ");
5379                sb.append(msg);
5380                FileOutputStream fos = new FileOutputStream(tracesFile);
5381                fos.write(sb.toString().getBytes());
5382                if (app == null) {
5383                    fos.write("\n*** No application process!".getBytes());
5384                }
5385                fos.close();
5386                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5387            } catch (IOException e) {
5388                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5389                return;
5390            }
5391
5392            if (app != null) {
5393                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5394                firstPids.add(app.pid);
5395                dumpStackTraces(tracesPath, firstPids, null, null, null);
5396            }
5397
5398            File lastTracesFile = null;
5399            File curTracesFile = null;
5400            for (int i=9; i>=0; i--) {
5401                String name = String.format(Locale.US, "slow%02d.txt", i);
5402                curTracesFile = new File(tracesDir, name);
5403                if (curTracesFile.exists()) {
5404                    if (lastTracesFile != null) {
5405                        curTracesFile.renameTo(lastTracesFile);
5406                    } else {
5407                        curTracesFile.delete();
5408                    }
5409                }
5410                lastTracesFile = curTracesFile;
5411            }
5412            tracesFile.renameTo(curTracesFile);
5413            if (tracesTmp.exists()) {
5414                tracesTmp.renameTo(tracesFile);
5415            }
5416        } finally {
5417            StrictMode.setThreadPolicy(oldPolicy);
5418        }
5419    }
5420
5421    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5422        if (!mLaunchWarningShown) {
5423            mLaunchWarningShown = true;
5424            mUiHandler.post(new Runnable() {
5425                @Override
5426                public void run() {
5427                    synchronized (ActivityManagerService.this) {
5428                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5429                        d.show();
5430                        mUiHandler.postDelayed(new Runnable() {
5431                            @Override
5432                            public void run() {
5433                                synchronized (ActivityManagerService.this) {
5434                                    d.dismiss();
5435                                    mLaunchWarningShown = false;
5436                                }
5437                            }
5438                        }, 4000);
5439                    }
5440                }
5441            });
5442        }
5443    }
5444
5445    @Override
5446    public boolean clearApplicationUserData(final String packageName,
5447            final IPackageDataObserver observer, int userId) {
5448        enforceNotIsolatedCaller("clearApplicationUserData");
5449        int uid = Binder.getCallingUid();
5450        int pid = Binder.getCallingPid();
5451        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5452                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5453
5454
5455        long callingId = Binder.clearCallingIdentity();
5456        try {
5457            IPackageManager pm = AppGlobals.getPackageManager();
5458            int pkgUid = -1;
5459            synchronized(this) {
5460                if (getPackageManagerInternalLocked().isPackageDataProtected(
5461                        userId, packageName)) {
5462                    throw new SecurityException(
5463                            "Cannot clear data for a protected package: " + packageName);
5464                }
5465
5466                try {
5467                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5468                } catch (RemoteException e) {
5469                }
5470                if (pkgUid == -1) {
5471                    Slog.w(TAG, "Invalid packageName: " + packageName);
5472                    if (observer != null) {
5473                        try {
5474                            observer.onRemoveCompleted(packageName, false);
5475                        } catch (RemoteException e) {
5476                            Slog.i(TAG, "Observer no longer exists.");
5477                        }
5478                    }
5479                    return false;
5480                }
5481                if (uid == pkgUid || checkComponentPermission(
5482                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5483                        pid, uid, -1, true)
5484                        == PackageManager.PERMISSION_GRANTED) {
5485                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5486                } else {
5487                    throw new SecurityException("PID " + pid + " does not have permission "
5488                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5489                                    + " of package " + packageName);
5490                }
5491
5492                // Remove all tasks match the cleared application package and user
5493                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5494                    final TaskRecord tr = mRecentTasks.get(i);
5495                    final String taskPackageName =
5496                            tr.getBaseIntent().getComponent().getPackageName();
5497                    if (tr.userId != userId) continue;
5498                    if (!taskPackageName.equals(packageName)) continue;
5499                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5500                }
5501            }
5502
5503            final int pkgUidF = pkgUid;
5504            final int userIdF = userId;
5505            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5506                @Override
5507                public void onRemoveCompleted(String packageName, boolean succeeded)
5508                        throws RemoteException {
5509                    synchronized (ActivityManagerService.this) {
5510                        finishForceStopPackageLocked(packageName, pkgUidF);
5511                    }
5512
5513                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5514                            Uri.fromParts("package", packageName, null));
5515                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5516                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5517                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5518                            null, null, 0, null, null, null, null, false, false, userIdF);
5519
5520                    if (observer != null) {
5521                        observer.onRemoveCompleted(packageName, succeeded);
5522                    }
5523                }
5524            };
5525
5526            try {
5527                // Clear application user data
5528                pm.clearApplicationUserData(packageName, localObserver, userId);
5529
5530                synchronized(this) {
5531                    // Remove all permissions granted from/to this package
5532                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5533                }
5534
5535                // Remove all zen rules created by this package; revoke it's zen access.
5536                INotificationManager inm = NotificationManager.getService();
5537                inm.removeAutomaticZenRules(packageName);
5538                inm.setNotificationPolicyAccessGranted(packageName, false);
5539
5540            } catch (RemoteException e) {
5541            }
5542        } finally {
5543            Binder.restoreCallingIdentity(callingId);
5544        }
5545        return true;
5546    }
5547
5548    @Override
5549    public void killBackgroundProcesses(final String packageName, int userId) {
5550        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5551                != PackageManager.PERMISSION_GRANTED &&
5552                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5553                        != PackageManager.PERMISSION_GRANTED) {
5554            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5555                    + Binder.getCallingPid()
5556                    + ", uid=" + Binder.getCallingUid()
5557                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5558            Slog.w(TAG, msg);
5559            throw new SecurityException(msg);
5560        }
5561
5562        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5563                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5564        long callingId = Binder.clearCallingIdentity();
5565        try {
5566            IPackageManager pm = AppGlobals.getPackageManager();
5567            synchronized(this) {
5568                int appId = -1;
5569                try {
5570                    appId = UserHandle.getAppId(
5571                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5572                } catch (RemoteException e) {
5573                }
5574                if (appId == -1) {
5575                    Slog.w(TAG, "Invalid packageName: " + packageName);
5576                    return;
5577                }
5578                killPackageProcessesLocked(packageName, appId, userId,
5579                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5580            }
5581        } finally {
5582            Binder.restoreCallingIdentity(callingId);
5583        }
5584    }
5585
5586    @Override
5587    public void killAllBackgroundProcesses() {
5588        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5589                != PackageManager.PERMISSION_GRANTED) {
5590            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5591                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5592                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5593            Slog.w(TAG, msg);
5594            throw new SecurityException(msg);
5595        }
5596
5597        final long callingId = Binder.clearCallingIdentity();
5598        try {
5599            synchronized (this) {
5600                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5601                final int NP = mProcessNames.getMap().size();
5602                for (int ip = 0; ip < NP; ip++) {
5603                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5604                    final int NA = apps.size();
5605                    for (int ia = 0; ia < NA; ia++) {
5606                        final ProcessRecord app = apps.valueAt(ia);
5607                        if (app.persistent) {
5608                            // We don't kill persistent processes.
5609                            continue;
5610                        }
5611                        if (app.removed) {
5612                            procs.add(app);
5613                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5614                            app.removed = true;
5615                            procs.add(app);
5616                        }
5617                    }
5618                }
5619
5620                final int N = procs.size();
5621                for (int i = 0; i < N; i++) {
5622                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5623                }
5624
5625                mAllowLowerMemLevel = true;
5626
5627                updateOomAdjLocked();
5628                doLowMemReportIfNeededLocked(null);
5629            }
5630        } finally {
5631            Binder.restoreCallingIdentity(callingId);
5632        }
5633    }
5634
5635    /**
5636     * Kills all background processes, except those matching any of the
5637     * specified properties.
5638     *
5639     * @param minTargetSdk the target SDK version at or above which to preserve
5640     *                     processes, or {@code -1} to ignore the target SDK
5641     * @param maxProcState the process state at or below which to preserve
5642     *                     processes, or {@code -1} to ignore the process state
5643     */
5644    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5645        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5646                != PackageManager.PERMISSION_GRANTED) {
5647            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5648                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5649                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5650            Slog.w(TAG, msg);
5651            throw new SecurityException(msg);
5652        }
5653
5654        final long callingId = Binder.clearCallingIdentity();
5655        try {
5656            synchronized (this) {
5657                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5658                final int NP = mProcessNames.getMap().size();
5659                for (int ip = 0; ip < NP; ip++) {
5660                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5661                    final int NA = apps.size();
5662                    for (int ia = 0; ia < NA; ia++) {
5663                        final ProcessRecord app = apps.valueAt(ia);
5664                        if (app.removed) {
5665                            procs.add(app);
5666                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5667                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5668                            app.removed = true;
5669                            procs.add(app);
5670                        }
5671                    }
5672                }
5673
5674                final int N = procs.size();
5675                for (int i = 0; i < N; i++) {
5676                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5677                }
5678            }
5679        } finally {
5680            Binder.restoreCallingIdentity(callingId);
5681        }
5682    }
5683
5684    @Override
5685    public void forceStopPackage(final String packageName, int userId) {
5686        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5687                != PackageManager.PERMISSION_GRANTED) {
5688            String msg = "Permission Denial: forceStopPackage() from pid="
5689                    + Binder.getCallingPid()
5690                    + ", uid=" + Binder.getCallingUid()
5691                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5692            Slog.w(TAG, msg);
5693            throw new SecurityException(msg);
5694        }
5695        final int callingPid = Binder.getCallingPid();
5696        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5697                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5698        long callingId = Binder.clearCallingIdentity();
5699        try {
5700            IPackageManager pm = AppGlobals.getPackageManager();
5701            synchronized(this) {
5702                int[] users = userId == UserHandle.USER_ALL
5703                        ? mUserController.getUsers() : new int[] { userId };
5704                for (int user : users) {
5705                    int pkgUid = -1;
5706                    try {
5707                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5708                                user);
5709                    } catch (RemoteException e) {
5710                    }
5711                    if (pkgUid == -1) {
5712                        Slog.w(TAG, "Invalid packageName: " + packageName);
5713                        continue;
5714                    }
5715                    try {
5716                        pm.setPackageStoppedState(packageName, true, user);
5717                    } catch (RemoteException e) {
5718                    } catch (IllegalArgumentException e) {
5719                        Slog.w(TAG, "Failed trying to unstop package "
5720                                + packageName + ": " + e);
5721                    }
5722                    if (mUserController.isUserRunningLocked(user, 0)) {
5723                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5724                        finishForceStopPackageLocked(packageName, pkgUid);
5725                    }
5726                }
5727            }
5728        } finally {
5729            Binder.restoreCallingIdentity(callingId);
5730        }
5731    }
5732
5733    @Override
5734    public void addPackageDependency(String packageName) {
5735        synchronized (this) {
5736            int callingPid = Binder.getCallingPid();
5737            if (callingPid == Process.myPid()) {
5738                //  Yeah, um, no.
5739                return;
5740            }
5741            ProcessRecord proc;
5742            synchronized (mPidsSelfLocked) {
5743                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5744            }
5745            if (proc != null) {
5746                if (proc.pkgDeps == null) {
5747                    proc.pkgDeps = new ArraySet<String>(1);
5748                }
5749                proc.pkgDeps.add(packageName);
5750            }
5751        }
5752    }
5753
5754    /*
5755     * The pkg name and app id have to be specified.
5756     */
5757    @Override
5758    public void killApplication(String pkg, int appId, int userId, String reason) {
5759        if (pkg == null) {
5760            return;
5761        }
5762        // Make sure the uid is valid.
5763        if (appId < 0) {
5764            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5765            return;
5766        }
5767        int callerUid = Binder.getCallingUid();
5768        // Only the system server can kill an application
5769        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5770            // Post an aysnc message to kill the application
5771            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5772            msg.arg1 = appId;
5773            msg.arg2 = userId;
5774            Bundle bundle = new Bundle();
5775            bundle.putString("pkg", pkg);
5776            bundle.putString("reason", reason);
5777            msg.obj = bundle;
5778            mHandler.sendMessage(msg);
5779        } else {
5780            throw new SecurityException(callerUid + " cannot kill pkg: " +
5781                    pkg);
5782        }
5783    }
5784
5785    @Override
5786    public void closeSystemDialogs(String reason) {
5787        enforceNotIsolatedCaller("closeSystemDialogs");
5788
5789        final int pid = Binder.getCallingPid();
5790        final int uid = Binder.getCallingUid();
5791        final long origId = Binder.clearCallingIdentity();
5792        try {
5793            synchronized (this) {
5794                // Only allow this from foreground processes, so that background
5795                // applications can't abuse it to prevent system UI from being shown.
5796                if (uid >= Process.FIRST_APPLICATION_UID) {
5797                    ProcessRecord proc;
5798                    synchronized (mPidsSelfLocked) {
5799                        proc = mPidsSelfLocked.get(pid);
5800                    }
5801                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5802                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5803                                + " from background process " + proc);
5804                        return;
5805                    }
5806                }
5807                closeSystemDialogsLocked(reason);
5808            }
5809        } finally {
5810            Binder.restoreCallingIdentity(origId);
5811        }
5812    }
5813
5814    void closeSystemDialogsLocked(String reason) {
5815        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5816        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5817                | Intent.FLAG_RECEIVER_FOREGROUND);
5818        if (reason != null) {
5819            intent.putExtra("reason", reason);
5820        }
5821        mWindowManager.closeSystemDialogs(reason);
5822
5823        mStackSupervisor.closeSystemDialogsLocked();
5824
5825        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5826                AppOpsManager.OP_NONE, null, false, false,
5827                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5828    }
5829
5830    @Override
5831    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5832        enforceNotIsolatedCaller("getProcessMemoryInfo");
5833        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5834        for (int i=pids.length-1; i>=0; i--) {
5835            ProcessRecord proc;
5836            int oomAdj;
5837            synchronized (this) {
5838                synchronized (mPidsSelfLocked) {
5839                    proc = mPidsSelfLocked.get(pids[i]);
5840                    oomAdj = proc != null ? proc.setAdj : 0;
5841                }
5842            }
5843            infos[i] = new Debug.MemoryInfo();
5844            Debug.getMemoryInfo(pids[i], infos[i]);
5845            if (proc != null) {
5846                synchronized (this) {
5847                    if (proc.thread != null && proc.setAdj == oomAdj) {
5848                        // Record this for posterity if the process has been stable.
5849                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5850                                infos[i].getTotalUss(), false, proc.pkgList);
5851                    }
5852                }
5853            }
5854        }
5855        return infos;
5856    }
5857
5858    @Override
5859    public long[] getProcessPss(int[] pids) {
5860        enforceNotIsolatedCaller("getProcessPss");
5861        long[] pss = new long[pids.length];
5862        for (int i=pids.length-1; i>=0; i--) {
5863            ProcessRecord proc;
5864            int oomAdj;
5865            synchronized (this) {
5866                synchronized (mPidsSelfLocked) {
5867                    proc = mPidsSelfLocked.get(pids[i]);
5868                    oomAdj = proc != null ? proc.setAdj : 0;
5869                }
5870            }
5871            long[] tmpUss = new long[1];
5872            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5873            if (proc != null) {
5874                synchronized (this) {
5875                    if (proc.thread != null && proc.setAdj == oomAdj) {
5876                        // Record this for posterity if the process has been stable.
5877                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5878                    }
5879                }
5880            }
5881        }
5882        return pss;
5883    }
5884
5885    @Override
5886    public void killApplicationProcess(String processName, int uid) {
5887        if (processName == null) {
5888            return;
5889        }
5890
5891        int callerUid = Binder.getCallingUid();
5892        // Only the system server can kill an application
5893        if (callerUid == Process.SYSTEM_UID) {
5894            synchronized (this) {
5895                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5896                if (app != null && app.thread != null) {
5897                    try {
5898                        app.thread.scheduleSuicide();
5899                    } catch (RemoteException e) {
5900                        // If the other end already died, then our work here is done.
5901                    }
5902                } else {
5903                    Slog.w(TAG, "Process/uid not found attempting kill of "
5904                            + processName + " / " + uid);
5905                }
5906            }
5907        } else {
5908            throw new SecurityException(callerUid + " cannot kill app process: " +
5909                    processName);
5910        }
5911    }
5912
5913    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5914        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5915                false, true, false, false, UserHandle.getUserId(uid), reason);
5916    }
5917
5918    private void finishForceStopPackageLocked(final String packageName, int uid) {
5919        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5920                Uri.fromParts("package", packageName, null));
5921        if (!mProcessesReady) {
5922            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5923                    | Intent.FLAG_RECEIVER_FOREGROUND);
5924        }
5925        intent.putExtra(Intent.EXTRA_UID, uid);
5926        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5927        broadcastIntentLocked(null, null, intent,
5928                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5929                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5930    }
5931
5932
5933    private final boolean killPackageProcessesLocked(String packageName, int appId,
5934            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5935            boolean doit, boolean evenPersistent, String reason) {
5936        ArrayList<ProcessRecord> procs = new ArrayList<>();
5937
5938        // Remove all processes this package may have touched: all with the
5939        // same UID (except for the system or root user), and all whose name
5940        // matches the package name.
5941        final int NP = mProcessNames.getMap().size();
5942        for (int ip=0; ip<NP; ip++) {
5943            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5944            final int NA = apps.size();
5945            for (int ia=0; ia<NA; ia++) {
5946                ProcessRecord app = apps.valueAt(ia);
5947                if (app.persistent && !evenPersistent) {
5948                    // we don't kill persistent processes
5949                    continue;
5950                }
5951                if (app.removed) {
5952                    if (doit) {
5953                        procs.add(app);
5954                    }
5955                    continue;
5956                }
5957
5958                // Skip process if it doesn't meet our oom adj requirement.
5959                if (app.setAdj < minOomAdj) {
5960                    continue;
5961                }
5962
5963                // If no package is specified, we call all processes under the
5964                // give user id.
5965                if (packageName == null) {
5966                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5967                        continue;
5968                    }
5969                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5970                        continue;
5971                    }
5972                // Package has been specified, we want to hit all processes
5973                // that match it.  We need to qualify this by the processes
5974                // that are running under the specified app and user ID.
5975                } else {
5976                    final boolean isDep = app.pkgDeps != null
5977                            && app.pkgDeps.contains(packageName);
5978                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5979                        continue;
5980                    }
5981                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5982                        continue;
5983                    }
5984                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5985                        continue;
5986                    }
5987                }
5988
5989                // Process has passed all conditions, kill it!
5990                if (!doit) {
5991                    return true;
5992                }
5993                app.removed = true;
5994                procs.add(app);
5995            }
5996        }
5997
5998        int N = procs.size();
5999        for (int i=0; i<N; i++) {
6000            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6001        }
6002        updateOomAdjLocked();
6003        return N > 0;
6004    }
6005
6006    private void cleanupDisabledPackageComponentsLocked(
6007            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6008
6009        Set<String> disabledClasses = null;
6010        boolean packageDisabled = false;
6011        IPackageManager pm = AppGlobals.getPackageManager();
6012
6013        if (changedClasses == null) {
6014            // Nothing changed...
6015            return;
6016        }
6017
6018        // Determine enable/disable state of the package and its components.
6019        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6020        for (int i = changedClasses.length - 1; i >= 0; i--) {
6021            final String changedClass = changedClasses[i];
6022
6023            if (changedClass.equals(packageName)) {
6024                try {
6025                    // Entire package setting changed
6026                    enabled = pm.getApplicationEnabledSetting(packageName,
6027                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6028                } catch (Exception e) {
6029                    // No such package/component; probably racing with uninstall.  In any
6030                    // event it means we have nothing further to do here.
6031                    return;
6032                }
6033                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6034                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6035                if (packageDisabled) {
6036                    // Entire package is disabled.
6037                    // No need to continue to check component states.
6038                    disabledClasses = null;
6039                    break;
6040                }
6041            } else {
6042                try {
6043                    enabled = pm.getComponentEnabledSetting(
6044                            new ComponentName(packageName, changedClass),
6045                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6046                } catch (Exception e) {
6047                    // As above, probably racing with uninstall.
6048                    return;
6049                }
6050                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6051                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6052                    if (disabledClasses == null) {
6053                        disabledClasses = new ArraySet<>(changedClasses.length);
6054                    }
6055                    disabledClasses.add(changedClass);
6056                }
6057            }
6058        }
6059
6060        if (!packageDisabled && disabledClasses == null) {
6061            // Nothing to do here...
6062            return;
6063        }
6064
6065        // Clean-up disabled activities.
6066        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6067                packageName, disabledClasses, true, false, userId) && mBooted) {
6068            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6069            mStackSupervisor.scheduleIdleLocked();
6070        }
6071
6072        // Clean-up disabled tasks
6073        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6074
6075        // Clean-up disabled services.
6076        mServices.bringDownDisabledPackageServicesLocked(
6077                packageName, disabledClasses, userId, false, killProcess, true);
6078
6079        // Clean-up disabled providers.
6080        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6081        mProviderMap.collectPackageProvidersLocked(
6082                packageName, disabledClasses, true, false, userId, providers);
6083        for (int i = providers.size() - 1; i >= 0; i--) {
6084            removeDyingProviderLocked(null, providers.get(i), true);
6085        }
6086
6087        // Clean-up disabled broadcast receivers.
6088        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6089            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6090                    packageName, disabledClasses, userId, true);
6091        }
6092
6093    }
6094
6095    final boolean clearBroadcastQueueForUserLocked(int userId) {
6096        boolean didSomething = false;
6097        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6098            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6099                    null, null, userId, true);
6100        }
6101        return didSomething;
6102    }
6103
6104    final boolean forceStopPackageLocked(String packageName, int appId,
6105            boolean callerWillRestart, boolean purgeCache, boolean doit,
6106            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6107        int i;
6108
6109        if (userId == UserHandle.USER_ALL && packageName == null) {
6110            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6111        }
6112
6113        if (appId < 0 && packageName != null) {
6114            try {
6115                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6116                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6117            } catch (RemoteException e) {
6118            }
6119        }
6120
6121        if (doit) {
6122            if (packageName != null) {
6123                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6124                        + " user=" + userId + ": " + reason);
6125            } else {
6126                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6127            }
6128
6129            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6130        }
6131
6132        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6133                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6134                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6135
6136        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6137                packageName, null, doit, evenPersistent, userId)) {
6138            if (!doit) {
6139                return true;
6140            }
6141            didSomething = true;
6142        }
6143
6144        if (mServices.bringDownDisabledPackageServicesLocked(
6145                packageName, null, userId, evenPersistent, true, doit)) {
6146            if (!doit) {
6147                return true;
6148            }
6149            didSomething = true;
6150        }
6151
6152        if (packageName == null) {
6153            // Remove all sticky broadcasts from this user.
6154            mStickyBroadcasts.remove(userId);
6155        }
6156
6157        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6158        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6159                userId, providers)) {
6160            if (!doit) {
6161                return true;
6162            }
6163            didSomething = true;
6164        }
6165        for (i = providers.size() - 1; i >= 0; i--) {
6166            removeDyingProviderLocked(null, providers.get(i), true);
6167        }
6168
6169        // Remove transient permissions granted from/to this package/user
6170        removeUriPermissionsForPackageLocked(packageName, userId, false);
6171
6172        if (doit) {
6173            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6174                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6175                        packageName, null, userId, doit);
6176            }
6177        }
6178
6179        if (packageName == null || uninstalling) {
6180            // Remove pending intents.  For now we only do this when force
6181            // stopping users, because we have some problems when doing this
6182            // for packages -- app widgets are not currently cleaned up for
6183            // such packages, so they can be left with bad pending intents.
6184            if (mIntentSenderRecords.size() > 0) {
6185                Iterator<WeakReference<PendingIntentRecord>> it
6186                        = mIntentSenderRecords.values().iterator();
6187                while (it.hasNext()) {
6188                    WeakReference<PendingIntentRecord> wpir = it.next();
6189                    if (wpir == null) {
6190                        it.remove();
6191                        continue;
6192                    }
6193                    PendingIntentRecord pir = wpir.get();
6194                    if (pir == null) {
6195                        it.remove();
6196                        continue;
6197                    }
6198                    if (packageName == null) {
6199                        // Stopping user, remove all objects for the user.
6200                        if (pir.key.userId != userId) {
6201                            // Not the same user, skip it.
6202                            continue;
6203                        }
6204                    } else {
6205                        if (UserHandle.getAppId(pir.uid) != appId) {
6206                            // Different app id, skip it.
6207                            continue;
6208                        }
6209                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6210                            // Different user, skip it.
6211                            continue;
6212                        }
6213                        if (!pir.key.packageName.equals(packageName)) {
6214                            // Different package, skip it.
6215                            continue;
6216                        }
6217                    }
6218                    if (!doit) {
6219                        return true;
6220                    }
6221                    didSomething = true;
6222                    it.remove();
6223                    pir.canceled = true;
6224                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6225                        pir.key.activity.pendingResults.remove(pir.ref);
6226                    }
6227                }
6228            }
6229        }
6230
6231        if (doit) {
6232            if (purgeCache && packageName != null) {
6233                AttributeCache ac = AttributeCache.instance();
6234                if (ac != null) {
6235                    ac.removePackage(packageName);
6236                }
6237            }
6238            if (mBooted) {
6239                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6240                mStackSupervisor.scheduleIdleLocked();
6241            }
6242        }
6243
6244        return didSomething;
6245    }
6246
6247    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6248        ProcessRecord old = mProcessNames.remove(name, uid);
6249        if (old != null) {
6250            old.uidRecord.numProcs--;
6251            if (old.uidRecord.numProcs == 0) {
6252                // No more processes using this uid, tell clients it is gone.
6253                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6254                        "No more processes in " + old.uidRecord);
6255                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6256                mActiveUids.remove(uid);
6257                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6258            }
6259            old.uidRecord = null;
6260        }
6261        mIsolatedProcesses.remove(uid);
6262        return old;
6263    }
6264
6265    private final void addProcessNameLocked(ProcessRecord proc) {
6266        // We shouldn't already have a process under this name, but just in case we
6267        // need to clean up whatever may be there now.
6268        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6269        if (old == proc && proc.persistent) {
6270            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6271            Slog.w(TAG, "Re-adding persistent process " + proc);
6272        } else if (old != null) {
6273            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6274        }
6275        UidRecord uidRec = mActiveUids.get(proc.uid);
6276        if (uidRec == null) {
6277            uidRec = new UidRecord(proc.uid);
6278            // This is the first appearance of the uid, report it now!
6279            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6280                    "Creating new process uid: " + uidRec);
6281            mActiveUids.put(proc.uid, uidRec);
6282            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6283            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6284        }
6285        proc.uidRecord = uidRec;
6286
6287        // Reset render thread tid if it was already set, so new process can set it again.
6288        proc.renderThreadTid = 0;
6289        uidRec.numProcs++;
6290        mProcessNames.put(proc.processName, proc.uid, proc);
6291        if (proc.isolated) {
6292            mIsolatedProcesses.put(proc.uid, proc);
6293        }
6294    }
6295
6296    boolean removeProcessLocked(ProcessRecord app,
6297            boolean callerWillRestart, boolean allowRestart, String reason) {
6298        final String name = app.processName;
6299        final int uid = app.uid;
6300        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6301            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6302
6303        ProcessRecord old = mProcessNames.get(name, uid);
6304        if (old != app) {
6305            // This process is no longer active, so nothing to do.
6306            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6307            return false;
6308        }
6309        removeProcessNameLocked(name, uid);
6310        if (mHeavyWeightProcess == app) {
6311            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6312                    mHeavyWeightProcess.userId, 0));
6313            mHeavyWeightProcess = null;
6314        }
6315        boolean needRestart = false;
6316        if (app.pid > 0 && app.pid != MY_PID) {
6317            int pid = app.pid;
6318            synchronized (mPidsSelfLocked) {
6319                mPidsSelfLocked.remove(pid);
6320                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6321            }
6322            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6323            if (app.isolated) {
6324                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6325            }
6326            boolean willRestart = false;
6327            if (app.persistent && !app.isolated) {
6328                if (!callerWillRestart) {
6329                    willRestart = true;
6330                } else {
6331                    needRestart = true;
6332                }
6333            }
6334            app.kill(reason, true);
6335            handleAppDiedLocked(app, willRestart, allowRestart);
6336            if (willRestart) {
6337                removeLruProcessLocked(app);
6338                addAppLocked(app.info, false, null /* ABI override */);
6339            }
6340        } else {
6341            mRemovedProcesses.add(app);
6342        }
6343
6344        return needRestart;
6345    }
6346
6347    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6348        cleanupAppInLaunchingProvidersLocked(app, true);
6349        removeProcessLocked(app, false, true, "timeout publishing content providers");
6350    }
6351
6352    private final void processStartTimedOutLocked(ProcessRecord app) {
6353        final int pid = app.pid;
6354        boolean gone = false;
6355        synchronized (mPidsSelfLocked) {
6356            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6357            if (knownApp != null && knownApp.thread == null) {
6358                mPidsSelfLocked.remove(pid);
6359                gone = true;
6360            }
6361        }
6362
6363        if (gone) {
6364            Slog.w(TAG, "Process " + app + " failed to attach");
6365            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6366                    pid, app.uid, app.processName);
6367            removeProcessNameLocked(app.processName, app.uid);
6368            if (mHeavyWeightProcess == app) {
6369                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6370                        mHeavyWeightProcess.userId, 0));
6371                mHeavyWeightProcess = null;
6372            }
6373            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6374            if (app.isolated) {
6375                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6376            }
6377            // Take care of any launching providers waiting for this process.
6378            cleanupAppInLaunchingProvidersLocked(app, true);
6379            // Take care of any services that are waiting for the process.
6380            mServices.processStartTimedOutLocked(app);
6381            app.kill("start timeout", true);
6382            removeLruProcessLocked(app);
6383            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6384                Slog.w(TAG, "Unattached app died before backup, skipping");
6385                try {
6386                    IBackupManager bm = IBackupManager.Stub.asInterface(
6387                            ServiceManager.getService(Context.BACKUP_SERVICE));
6388                    bm.agentDisconnected(app.info.packageName);
6389                } catch (RemoteException e) {
6390                    // Can't happen; the backup manager is local
6391                }
6392            }
6393            if (isPendingBroadcastProcessLocked(pid)) {
6394                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6395                skipPendingBroadcastLocked(pid);
6396            }
6397        } else {
6398            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6399        }
6400    }
6401
6402    private final boolean attachApplicationLocked(IApplicationThread thread,
6403            int pid) {
6404
6405        // Find the application record that is being attached...  either via
6406        // the pid if we are running in multiple processes, or just pull the
6407        // next app record if we are emulating process with anonymous threads.
6408        ProcessRecord app;
6409        if (pid != MY_PID && pid >= 0) {
6410            synchronized (mPidsSelfLocked) {
6411                app = mPidsSelfLocked.get(pid);
6412            }
6413        } else {
6414            app = null;
6415        }
6416
6417        if (app == null) {
6418            Slog.w(TAG, "No pending application record for pid " + pid
6419                    + " (IApplicationThread " + thread + "); dropping process");
6420            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6421            if (pid > 0 && pid != MY_PID) {
6422                Process.killProcessQuiet(pid);
6423                //TODO: killProcessGroup(app.info.uid, pid);
6424            } else {
6425                try {
6426                    thread.scheduleExit();
6427                } catch (Exception e) {
6428                    // Ignore exceptions.
6429                }
6430            }
6431            return false;
6432        }
6433
6434        // If this application record is still attached to a previous
6435        // process, clean it up now.
6436        if (app.thread != null) {
6437            handleAppDiedLocked(app, true, true);
6438        }
6439
6440        // Tell the process all about itself.
6441
6442        if (DEBUG_ALL) Slog.v(
6443                TAG, "Binding process pid " + pid + " to record " + app);
6444
6445        final String processName = app.processName;
6446        try {
6447            AppDeathRecipient adr = new AppDeathRecipient(
6448                    app, pid, thread);
6449            thread.asBinder().linkToDeath(adr, 0);
6450            app.deathRecipient = adr;
6451        } catch (RemoteException e) {
6452            app.resetPackageList(mProcessStats);
6453            startProcessLocked(app, "link fail", processName);
6454            return false;
6455        }
6456
6457        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6458
6459        app.makeActive(thread, mProcessStats);
6460        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6461        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6462        app.forcingToForeground = null;
6463        updateProcessForegroundLocked(app, false, false);
6464        app.hasShownUi = false;
6465        app.debugging = false;
6466        app.cached = false;
6467        app.killedByAm = false;
6468
6469        // We carefully use the same state that PackageManager uses for
6470        // filtering, since we use this flag to decide if we need to install
6471        // providers when user is unlocked later
6472        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6473
6474        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6475
6476        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6477        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6478
6479        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6480            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6481            msg.obj = app;
6482            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6483        }
6484
6485        if (!normalMode) {
6486            Slog.i(TAG, "Launching preboot mode app: " + app);
6487        }
6488
6489        if (DEBUG_ALL) Slog.v(
6490            TAG, "New app record " + app
6491            + " thread=" + thread.asBinder() + " pid=" + pid);
6492        try {
6493            int testMode = IApplicationThread.DEBUG_OFF;
6494            if (mDebugApp != null && mDebugApp.equals(processName)) {
6495                testMode = mWaitForDebugger
6496                    ? IApplicationThread.DEBUG_WAIT
6497                    : IApplicationThread.DEBUG_ON;
6498                app.debugging = true;
6499                if (mDebugTransient) {
6500                    mDebugApp = mOrigDebugApp;
6501                    mWaitForDebugger = mOrigWaitForDebugger;
6502                }
6503            }
6504            String profileFile = app.instrumentationProfileFile;
6505            ParcelFileDescriptor profileFd = null;
6506            int samplingInterval = 0;
6507            boolean profileAutoStop = false;
6508            if (mProfileApp != null && mProfileApp.equals(processName)) {
6509                mProfileProc = app;
6510                profileFile = mProfileFile;
6511                profileFd = mProfileFd;
6512                samplingInterval = mSamplingInterval;
6513                profileAutoStop = mAutoStopProfiler;
6514            }
6515            boolean enableTrackAllocation = false;
6516            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6517                enableTrackAllocation = true;
6518                mTrackAllocationApp = null;
6519            }
6520
6521            // If the app is being launched for restore or full backup, set it up specially
6522            boolean isRestrictedBackupMode = false;
6523            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6524                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6525                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6526                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6527                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6528            }
6529
6530            if (app.instrumentationClass != null) {
6531                notifyPackageUse(app.instrumentationClass.getPackageName(),
6532                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6533            }
6534            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6535                    + processName + " with config " + mConfiguration);
6536            ApplicationInfo appInfo = app.instrumentationInfo != null
6537                    ? app.instrumentationInfo : app.info;
6538            app.compat = compatibilityInfoForPackageLocked(appInfo);
6539            if (profileFd != null) {
6540                profileFd = profileFd.dup();
6541            }
6542            ProfilerInfo profilerInfo = profileFile == null ? null
6543                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6544            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6545                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6546                    app.instrumentationUiAutomationConnection, testMode,
6547                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6548                    isRestrictedBackupMode || !normalMode, app.persistent,
6549                    new Configuration(mConfiguration), app.compat,
6550                    getCommonServicesLocked(app.isolated),
6551                    mCoreSettingsObserver.getCoreSettingsLocked());
6552            updateLruProcessLocked(app, false, null);
6553            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6554        } catch (Exception e) {
6555            // todo: Yikes!  What should we do?  For now we will try to
6556            // start another process, but that could easily get us in
6557            // an infinite loop of restarting processes...
6558            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6559
6560            app.resetPackageList(mProcessStats);
6561            app.unlinkDeathRecipient();
6562            startProcessLocked(app, "bind fail", processName);
6563            return false;
6564        }
6565
6566        // Remove this record from the list of starting applications.
6567        mPersistentStartingProcesses.remove(app);
6568        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6569                "Attach application locked removing on hold: " + app);
6570        mProcessesOnHold.remove(app);
6571
6572        boolean badApp = false;
6573        boolean didSomething = false;
6574
6575        // See if the top visible activity is waiting to run in this process...
6576        if (normalMode) {
6577            try {
6578                if (mStackSupervisor.attachApplicationLocked(app)) {
6579                    didSomething = true;
6580                }
6581            } catch (Exception e) {
6582                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6583                badApp = true;
6584            }
6585        }
6586
6587        // Find any services that should be running in this process...
6588        if (!badApp) {
6589            try {
6590                didSomething |= mServices.attachApplicationLocked(app, processName);
6591            } catch (Exception e) {
6592                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6593                badApp = true;
6594            }
6595        }
6596
6597        // Check if a next-broadcast receiver is in this process...
6598        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6599            try {
6600                didSomething |= sendPendingBroadcastsLocked(app);
6601            } catch (Exception e) {
6602                // If the app died trying to launch the receiver we declare it 'bad'
6603                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6604                badApp = true;
6605            }
6606        }
6607
6608        // Check whether the next backup agent is in this process...
6609        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6610            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6611                    "New app is backup target, launching agent for " + app);
6612            notifyPackageUse(mBackupTarget.appInfo.packageName,
6613                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6614            try {
6615                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6616                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6617                        mBackupTarget.backupMode);
6618            } catch (Exception e) {
6619                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6620                badApp = true;
6621            }
6622        }
6623
6624        if (badApp) {
6625            app.kill("error during init", true);
6626            handleAppDiedLocked(app, false, true);
6627            return false;
6628        }
6629
6630        if (!didSomething) {
6631            updateOomAdjLocked();
6632        }
6633
6634        return true;
6635    }
6636
6637    @Override
6638    public final void attachApplication(IApplicationThread thread) {
6639        synchronized (this) {
6640            int callingPid = Binder.getCallingPid();
6641            final long origId = Binder.clearCallingIdentity();
6642            attachApplicationLocked(thread, callingPid);
6643            Binder.restoreCallingIdentity(origId);
6644        }
6645    }
6646
6647    @Override
6648    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6649        final long origId = Binder.clearCallingIdentity();
6650        synchronized (this) {
6651            ActivityStack stack = ActivityRecord.getStackLocked(token);
6652            if (stack != null) {
6653                ActivityRecord r =
6654                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6655                if (stopProfiling) {
6656                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6657                        try {
6658                            mProfileFd.close();
6659                        } catch (IOException e) {
6660                        }
6661                        clearProfilerLocked();
6662                    }
6663                }
6664            }
6665        }
6666        Binder.restoreCallingIdentity(origId);
6667    }
6668
6669    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6670        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6671                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6672    }
6673
6674    void enableScreenAfterBoot() {
6675        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6676                SystemClock.uptimeMillis());
6677        mWindowManager.enableScreenAfterBoot();
6678
6679        synchronized (this) {
6680            updateEventDispatchingLocked();
6681        }
6682    }
6683
6684    @Override
6685    public void showBootMessage(final CharSequence msg, final boolean always) {
6686        if (Binder.getCallingUid() != Process.myUid()) {
6687            throw new SecurityException();
6688        }
6689        mWindowManager.showBootMessage(msg, always);
6690    }
6691
6692    @Override
6693    public void keyguardWaitingForActivityDrawn() {
6694        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6695        final long token = Binder.clearCallingIdentity();
6696        try {
6697            synchronized (this) {
6698                if (DEBUG_LOCKSCREEN) logLockScreen("");
6699                mWindowManager.keyguardWaitingForActivityDrawn();
6700                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6701                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6702                    updateSleepIfNeededLocked();
6703                }
6704            }
6705        } finally {
6706            Binder.restoreCallingIdentity(token);
6707        }
6708    }
6709
6710    @Override
6711    public void keyguardGoingAway(int flags) {
6712        enforceNotIsolatedCaller("keyguardGoingAway");
6713        final long token = Binder.clearCallingIdentity();
6714        try {
6715            synchronized (this) {
6716                if (DEBUG_LOCKSCREEN) logLockScreen("");
6717                mWindowManager.keyguardGoingAway(flags);
6718                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6719                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6720                    updateSleepIfNeededLocked();
6721
6722                    // Some stack visibility might change (e.g. docked stack)
6723                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6724                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6725                }
6726            }
6727        } finally {
6728            Binder.restoreCallingIdentity(token);
6729        }
6730    }
6731
6732    final void finishBooting() {
6733        synchronized (this) {
6734            if (!mBootAnimationComplete) {
6735                mCallFinishBooting = true;
6736                return;
6737            }
6738            mCallFinishBooting = false;
6739        }
6740
6741        ArraySet<String> completedIsas = new ArraySet<String>();
6742        for (String abi : Build.SUPPORTED_ABIS) {
6743            Process.establishZygoteConnectionForAbi(abi);
6744            final String instructionSet = VMRuntime.getInstructionSet(abi);
6745            if (!completedIsas.contains(instructionSet)) {
6746                try {
6747                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6748                } catch (InstallerException e) {
6749                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6750                            e.getMessage() +")");
6751                }
6752                completedIsas.add(instructionSet);
6753            }
6754        }
6755
6756        IntentFilter pkgFilter = new IntentFilter();
6757        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6758        pkgFilter.addDataScheme("package");
6759        mContext.registerReceiver(new BroadcastReceiver() {
6760            @Override
6761            public void onReceive(Context context, Intent intent) {
6762                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6763                if (pkgs != null) {
6764                    for (String pkg : pkgs) {
6765                        synchronized (ActivityManagerService.this) {
6766                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6767                                    0, "query restart")) {
6768                                setResultCode(Activity.RESULT_OK);
6769                                return;
6770                            }
6771                        }
6772                    }
6773                }
6774            }
6775        }, pkgFilter);
6776
6777        IntentFilter dumpheapFilter = new IntentFilter();
6778        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6779        mContext.registerReceiver(new BroadcastReceiver() {
6780            @Override
6781            public void onReceive(Context context, Intent intent) {
6782                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6783                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6784                } else {
6785                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6786                }
6787            }
6788        }, dumpheapFilter);
6789
6790        // Let system services know.
6791        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6792
6793        synchronized (this) {
6794            // Ensure that any processes we had put on hold are now started
6795            // up.
6796            final int NP = mProcessesOnHold.size();
6797            if (NP > 0) {
6798                ArrayList<ProcessRecord> procs =
6799                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6800                for (int ip=0; ip<NP; ip++) {
6801                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6802                            + procs.get(ip));
6803                    startProcessLocked(procs.get(ip), "on-hold", null);
6804                }
6805            }
6806
6807            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6808                // Start looking for apps that are abusing wake locks.
6809                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6810                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6811                // Tell anyone interested that we are done booting!
6812                SystemProperties.set("sys.boot_completed", "1");
6813
6814                // And trigger dev.bootcomplete if we are not showing encryption progress
6815                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6816                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6817                    SystemProperties.set("dev.bootcomplete", "1");
6818                }
6819                mUserController.sendBootCompletedLocked(
6820                        new IIntentReceiver.Stub() {
6821                            @Override
6822                            public void performReceive(Intent intent, int resultCode,
6823                                    String data, Bundle extras, boolean ordered,
6824                                    boolean sticky, int sendingUser) {
6825                                synchronized (ActivityManagerService.this) {
6826                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6827                                            true, false);
6828                                }
6829                            }
6830                        });
6831                scheduleStartProfilesLocked();
6832            }
6833        }
6834    }
6835
6836    @Override
6837    public void bootAnimationComplete() {
6838        final boolean callFinishBooting;
6839        synchronized (this) {
6840            callFinishBooting = mCallFinishBooting;
6841            mBootAnimationComplete = true;
6842        }
6843        if (callFinishBooting) {
6844            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6845            finishBooting();
6846            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6847        }
6848    }
6849
6850    final void ensureBootCompleted() {
6851        boolean booting;
6852        boolean enableScreen;
6853        synchronized (this) {
6854            booting = mBooting;
6855            mBooting = false;
6856            enableScreen = !mBooted;
6857            mBooted = true;
6858        }
6859
6860        if (booting) {
6861            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6862            finishBooting();
6863            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6864        }
6865
6866        if (enableScreen) {
6867            enableScreenAfterBoot();
6868        }
6869    }
6870
6871    @Override
6872    public final void activityResumed(IBinder token) {
6873        final long origId = Binder.clearCallingIdentity();
6874        synchronized(this) {
6875            ActivityStack stack = ActivityRecord.getStackLocked(token);
6876            if (stack != null) {
6877                stack.activityResumedLocked(token);
6878            }
6879        }
6880        Binder.restoreCallingIdentity(origId);
6881    }
6882
6883    @Override
6884    public final void activityPaused(IBinder token) {
6885        final long origId = Binder.clearCallingIdentity();
6886        synchronized(this) {
6887            ActivityStack stack = ActivityRecord.getStackLocked(token);
6888            if (stack != null) {
6889                stack.activityPausedLocked(token, false);
6890            }
6891        }
6892        Binder.restoreCallingIdentity(origId);
6893    }
6894
6895    @Override
6896    public final void activityStopped(IBinder token, Bundle icicle,
6897            PersistableBundle persistentState, CharSequence description) {
6898        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6899
6900        // Refuse possible leaked file descriptors
6901        if (icicle != null && icicle.hasFileDescriptors()) {
6902            throw new IllegalArgumentException("File descriptors passed in Bundle");
6903        }
6904
6905        final long origId = Binder.clearCallingIdentity();
6906
6907        synchronized (this) {
6908            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6909            if (r != null) {
6910                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6911            }
6912        }
6913
6914        trimApplications();
6915
6916        Binder.restoreCallingIdentity(origId);
6917    }
6918
6919    @Override
6920    public final void activityDestroyed(IBinder token) {
6921        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6922        synchronized (this) {
6923            ActivityStack stack = ActivityRecord.getStackLocked(token);
6924            if (stack != null) {
6925                stack.activityDestroyedLocked(token, "activityDestroyed");
6926            }
6927        }
6928    }
6929
6930    @Override
6931    public final void activityRelaunched(IBinder token) {
6932        final long origId = Binder.clearCallingIdentity();
6933        synchronized (this) {
6934            mStackSupervisor.activityRelaunchedLocked(token);
6935        }
6936        Binder.restoreCallingIdentity(origId);
6937    }
6938
6939    @Override
6940    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6941            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6942        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6943                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6944        synchronized (this) {
6945            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6946            if (record == null) {
6947                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6948                        + "found for: " + token);
6949            }
6950            record.setSizeConfigurations(horizontalSizeConfiguration,
6951                    verticalSizeConfigurations, smallestSizeConfigurations);
6952        }
6953    }
6954
6955    @Override
6956    public final void backgroundResourcesReleased(IBinder token) {
6957        final long origId = Binder.clearCallingIdentity();
6958        try {
6959            synchronized (this) {
6960                ActivityStack stack = ActivityRecord.getStackLocked(token);
6961                if (stack != null) {
6962                    stack.backgroundResourcesReleased();
6963                }
6964            }
6965        } finally {
6966            Binder.restoreCallingIdentity(origId);
6967        }
6968    }
6969
6970    @Override
6971    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6972        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6973    }
6974
6975    @Override
6976    public final void notifyEnterAnimationComplete(IBinder token) {
6977        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6978    }
6979
6980    @Override
6981    public String getCallingPackage(IBinder token) {
6982        synchronized (this) {
6983            ActivityRecord r = getCallingRecordLocked(token);
6984            return r != null ? r.info.packageName : null;
6985        }
6986    }
6987
6988    @Override
6989    public ComponentName getCallingActivity(IBinder token) {
6990        synchronized (this) {
6991            ActivityRecord r = getCallingRecordLocked(token);
6992            return r != null ? r.intent.getComponent() : null;
6993        }
6994    }
6995
6996    private ActivityRecord getCallingRecordLocked(IBinder token) {
6997        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6998        if (r == null) {
6999            return null;
7000        }
7001        return r.resultTo;
7002    }
7003
7004    @Override
7005    public ComponentName getActivityClassForToken(IBinder token) {
7006        synchronized(this) {
7007            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7008            if (r == null) {
7009                return null;
7010            }
7011            return r.intent.getComponent();
7012        }
7013    }
7014
7015    @Override
7016    public String getPackageForToken(IBinder token) {
7017        synchronized(this) {
7018            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7019            if (r == null) {
7020                return null;
7021            }
7022            return r.packageName;
7023        }
7024    }
7025
7026    @Override
7027    public boolean isRootVoiceInteraction(IBinder token) {
7028        synchronized(this) {
7029            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7030            if (r == null) {
7031                return false;
7032            }
7033            return r.rootVoiceInteraction;
7034        }
7035    }
7036
7037    @Override
7038    public IIntentSender getIntentSender(int type,
7039            String packageName, IBinder token, String resultWho,
7040            int requestCode, Intent[] intents, String[] resolvedTypes,
7041            int flags, Bundle bOptions, int userId) {
7042        enforceNotIsolatedCaller("getIntentSender");
7043        // Refuse possible leaked file descriptors
7044        if (intents != null) {
7045            if (intents.length < 1) {
7046                throw new IllegalArgumentException("Intents array length must be >= 1");
7047            }
7048            for (int i=0; i<intents.length; i++) {
7049                Intent intent = intents[i];
7050                if (intent != null) {
7051                    if (intent.hasFileDescriptors()) {
7052                        throw new IllegalArgumentException("File descriptors passed in Intent");
7053                    }
7054                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7055                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7056                        throw new IllegalArgumentException(
7057                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7058                    }
7059                    intents[i] = new Intent(intent);
7060                }
7061            }
7062            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7063                throw new IllegalArgumentException(
7064                        "Intent array length does not match resolvedTypes length");
7065            }
7066        }
7067        if (bOptions != null) {
7068            if (bOptions.hasFileDescriptors()) {
7069                throw new IllegalArgumentException("File descriptors passed in options");
7070            }
7071        }
7072
7073        synchronized(this) {
7074            int callingUid = Binder.getCallingUid();
7075            int origUserId = userId;
7076            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7077                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7078                    ALLOW_NON_FULL, "getIntentSender", null);
7079            if (origUserId == UserHandle.USER_CURRENT) {
7080                // We don't want to evaluate this until the pending intent is
7081                // actually executed.  However, we do want to always do the
7082                // security checking for it above.
7083                userId = UserHandle.USER_CURRENT;
7084            }
7085            try {
7086                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7087                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7088                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7089                    if (!UserHandle.isSameApp(callingUid, uid)) {
7090                        String msg = "Permission Denial: getIntentSender() from pid="
7091                            + Binder.getCallingPid()
7092                            + ", uid=" + Binder.getCallingUid()
7093                            + ", (need uid=" + uid + ")"
7094                            + " is not allowed to send as package " + packageName;
7095                        Slog.w(TAG, msg);
7096                        throw new SecurityException(msg);
7097                    }
7098                }
7099
7100                return getIntentSenderLocked(type, packageName, callingUid, userId,
7101                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7102
7103            } catch (RemoteException e) {
7104                throw new SecurityException(e);
7105            }
7106        }
7107    }
7108
7109    IIntentSender getIntentSenderLocked(int type, String packageName,
7110            int callingUid, int userId, IBinder token, String resultWho,
7111            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7112            Bundle bOptions) {
7113        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7114        ActivityRecord activity = null;
7115        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7116            activity = ActivityRecord.isInStackLocked(token);
7117            if (activity == null) {
7118                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7119                return null;
7120            }
7121            if (activity.finishing) {
7122                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7123                return null;
7124            }
7125        }
7126
7127        // We're going to be splicing together extras before sending, so we're
7128        // okay poking into any contained extras.
7129        if (intents != null) {
7130            for (int i = 0; i < intents.length; i++) {
7131                intents[i].setDefusable(true);
7132            }
7133        }
7134        Bundle.setDefusable(bOptions, true);
7135
7136        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7137        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7138        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7139        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7140                |PendingIntent.FLAG_UPDATE_CURRENT);
7141
7142        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7143                type, packageName, activity, resultWho,
7144                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7145        WeakReference<PendingIntentRecord> ref;
7146        ref = mIntentSenderRecords.get(key);
7147        PendingIntentRecord rec = ref != null ? ref.get() : null;
7148        if (rec != null) {
7149            if (!cancelCurrent) {
7150                if (updateCurrent) {
7151                    if (rec.key.requestIntent != null) {
7152                        rec.key.requestIntent.replaceExtras(intents != null ?
7153                                intents[intents.length - 1] : null);
7154                    }
7155                    if (intents != null) {
7156                        intents[intents.length-1] = rec.key.requestIntent;
7157                        rec.key.allIntents = intents;
7158                        rec.key.allResolvedTypes = resolvedTypes;
7159                    } else {
7160                        rec.key.allIntents = null;
7161                        rec.key.allResolvedTypes = null;
7162                    }
7163                }
7164                return rec;
7165            }
7166            rec.canceled = true;
7167            mIntentSenderRecords.remove(key);
7168        }
7169        if (noCreate) {
7170            return rec;
7171        }
7172        rec = new PendingIntentRecord(this, key, callingUid);
7173        mIntentSenderRecords.put(key, rec.ref);
7174        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7175            if (activity.pendingResults == null) {
7176                activity.pendingResults
7177                        = new HashSet<WeakReference<PendingIntentRecord>>();
7178            }
7179            activity.pendingResults.add(rec.ref);
7180        }
7181        return rec;
7182    }
7183
7184    @Override
7185    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7186            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7187        if (target instanceof PendingIntentRecord) {
7188            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7189                    finishedReceiver, requiredPermission, options);
7190        } else {
7191            if (intent == null) {
7192                // Weird case: someone has given us their own custom IIntentSender, and now
7193                // they have someone else trying to send to it but of course this isn't
7194                // really a PendingIntent, so there is no base Intent, and the caller isn't
7195                // supplying an Intent... but we never want to dispatch a null Intent to
7196                // a receiver, so um...  let's make something up.
7197                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7198                intent = new Intent(Intent.ACTION_MAIN);
7199            }
7200            try {
7201                target.send(code, intent, resolvedType, null, requiredPermission, options);
7202            } catch (RemoteException e) {
7203            }
7204            // Platform code can rely on getting a result back when the send is done, but if
7205            // this intent sender is from outside of the system we can't rely on it doing that.
7206            // So instead we don't give it the result receiver, and instead just directly
7207            // report the finish immediately.
7208            if (finishedReceiver != null) {
7209                try {
7210                    finishedReceiver.performReceive(intent, 0,
7211                            null, null, false, false, UserHandle.getCallingUserId());
7212                } catch (RemoteException e) {
7213                }
7214            }
7215            return 0;
7216        }
7217    }
7218
7219    /**
7220     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7221     *
7222     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7223     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7224     */
7225    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7226        if (DEBUG_WHITELISTS) {
7227            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7228                    + targetUid + ", " + duration + ")");
7229        }
7230        synchronized (mPidsSelfLocked) {
7231            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7232            if (pr == null) {
7233                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7234                return;
7235            }
7236            if (!pr.whitelistManager) {
7237                if (DEBUG_WHITELISTS) {
7238                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7239                            + callerPid + " is not allowed");
7240                }
7241                return;
7242            }
7243        }
7244
7245        final long token = Binder.clearCallingIdentity();
7246        try {
7247            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7248                    true, "pe from uid:" + callerUid);
7249        } finally {
7250            Binder.restoreCallingIdentity(token);
7251        }
7252    }
7253
7254    @Override
7255    public void cancelIntentSender(IIntentSender sender) {
7256        if (!(sender instanceof PendingIntentRecord)) {
7257            return;
7258        }
7259        synchronized(this) {
7260            PendingIntentRecord rec = (PendingIntentRecord)sender;
7261            try {
7262                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7263                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7264                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7265                    String msg = "Permission Denial: cancelIntentSender() from pid="
7266                        + Binder.getCallingPid()
7267                        + ", uid=" + Binder.getCallingUid()
7268                        + " is not allowed to cancel packges "
7269                        + rec.key.packageName;
7270                    Slog.w(TAG, msg);
7271                    throw new SecurityException(msg);
7272                }
7273            } catch (RemoteException e) {
7274                throw new SecurityException(e);
7275            }
7276            cancelIntentSenderLocked(rec, true);
7277        }
7278    }
7279
7280    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7281        rec.canceled = true;
7282        mIntentSenderRecords.remove(rec.key);
7283        if (cleanActivity && rec.key.activity != null) {
7284            rec.key.activity.pendingResults.remove(rec.ref);
7285        }
7286    }
7287
7288    @Override
7289    public String getPackageForIntentSender(IIntentSender pendingResult) {
7290        if (!(pendingResult instanceof PendingIntentRecord)) {
7291            return null;
7292        }
7293        try {
7294            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7295            return res.key.packageName;
7296        } catch (ClassCastException e) {
7297        }
7298        return null;
7299    }
7300
7301    @Override
7302    public int getUidForIntentSender(IIntentSender sender) {
7303        if (sender instanceof PendingIntentRecord) {
7304            try {
7305                PendingIntentRecord res = (PendingIntentRecord)sender;
7306                return res.uid;
7307            } catch (ClassCastException e) {
7308            }
7309        }
7310        return -1;
7311    }
7312
7313    @Override
7314    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7315        if (!(pendingResult instanceof PendingIntentRecord)) {
7316            return false;
7317        }
7318        try {
7319            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7320            if (res.key.allIntents == null) {
7321                return false;
7322            }
7323            for (int i=0; i<res.key.allIntents.length; i++) {
7324                Intent intent = res.key.allIntents[i];
7325                if (intent.getPackage() != null && intent.getComponent() != null) {
7326                    return false;
7327                }
7328            }
7329            return true;
7330        } catch (ClassCastException e) {
7331        }
7332        return false;
7333    }
7334
7335    @Override
7336    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7337        if (!(pendingResult instanceof PendingIntentRecord)) {
7338            return false;
7339        }
7340        try {
7341            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7342            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7343                return true;
7344            }
7345            return false;
7346        } catch (ClassCastException e) {
7347        }
7348        return false;
7349    }
7350
7351    @Override
7352    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7353        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7354                "getIntentForIntentSender()");
7355        if (!(pendingResult instanceof PendingIntentRecord)) {
7356            return null;
7357        }
7358        try {
7359            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7360            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7361        } catch (ClassCastException e) {
7362        }
7363        return null;
7364    }
7365
7366    @Override
7367    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7368        if (!(pendingResult instanceof PendingIntentRecord)) {
7369            return null;
7370        }
7371        try {
7372            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7373            synchronized (this) {
7374                return getTagForIntentSenderLocked(res, prefix);
7375            }
7376        } catch (ClassCastException e) {
7377        }
7378        return null;
7379    }
7380
7381    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7382        final Intent intent = res.key.requestIntent;
7383        if (intent != null) {
7384            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7385                    || res.lastTagPrefix.equals(prefix))) {
7386                return res.lastTag;
7387            }
7388            res.lastTagPrefix = prefix;
7389            final StringBuilder sb = new StringBuilder(128);
7390            if (prefix != null) {
7391                sb.append(prefix);
7392            }
7393            if (intent.getAction() != null) {
7394                sb.append(intent.getAction());
7395            } else if (intent.getComponent() != null) {
7396                intent.getComponent().appendShortString(sb);
7397            } else {
7398                sb.append("?");
7399            }
7400            return res.lastTag = sb.toString();
7401        }
7402        return null;
7403    }
7404
7405    @Override
7406    public void setProcessLimit(int max) {
7407        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7408                "setProcessLimit()");
7409        synchronized (this) {
7410            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7411            mProcessLimitOverride = max;
7412        }
7413        trimApplications();
7414    }
7415
7416    @Override
7417    public int getProcessLimit() {
7418        synchronized (this) {
7419            return mProcessLimitOverride;
7420        }
7421    }
7422
7423    void foregroundTokenDied(ForegroundToken token) {
7424        synchronized (ActivityManagerService.this) {
7425            synchronized (mPidsSelfLocked) {
7426                ForegroundToken cur
7427                    = mForegroundProcesses.get(token.pid);
7428                if (cur != token) {
7429                    return;
7430                }
7431                mForegroundProcesses.remove(token.pid);
7432                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7433                if (pr == null) {
7434                    return;
7435                }
7436                pr.forcingToForeground = null;
7437                updateProcessForegroundLocked(pr, false, false);
7438            }
7439            updateOomAdjLocked();
7440        }
7441    }
7442
7443    @Override
7444    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7445        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7446                "setProcessForeground()");
7447        synchronized(this) {
7448            boolean changed = false;
7449
7450            synchronized (mPidsSelfLocked) {
7451                ProcessRecord pr = mPidsSelfLocked.get(pid);
7452                if (pr == null && isForeground) {
7453                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7454                    return;
7455                }
7456                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7457                if (oldToken != null) {
7458                    oldToken.token.unlinkToDeath(oldToken, 0);
7459                    mForegroundProcesses.remove(pid);
7460                    if (pr != null) {
7461                        pr.forcingToForeground = null;
7462                    }
7463                    changed = true;
7464                }
7465                if (isForeground && token != null) {
7466                    ForegroundToken newToken = new ForegroundToken() {
7467                        @Override
7468                        public void binderDied() {
7469                            foregroundTokenDied(this);
7470                        }
7471                    };
7472                    newToken.pid = pid;
7473                    newToken.token = token;
7474                    try {
7475                        token.linkToDeath(newToken, 0);
7476                        mForegroundProcesses.put(pid, newToken);
7477                        pr.forcingToForeground = token;
7478                        changed = true;
7479                    } catch (RemoteException e) {
7480                        // If the process died while doing this, we will later
7481                        // do the cleanup with the process death link.
7482                    }
7483                }
7484            }
7485
7486            if (changed) {
7487                updateOomAdjLocked();
7488            }
7489        }
7490    }
7491
7492    @Override
7493    public boolean isAppForeground(int uid) throws RemoteException {
7494        synchronized (this) {
7495            UidRecord uidRec = mActiveUids.get(uid);
7496            if (uidRec == null || uidRec.idle) {
7497                return false;
7498            }
7499            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7500        }
7501    }
7502
7503    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7504    // be guarded by permission checking.
7505    int getUidState(int uid) {
7506        synchronized (this) {
7507            UidRecord uidRec = mActiveUids.get(uid);
7508            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7509        }
7510    }
7511
7512    @Override
7513    public boolean isInMultiWindowMode(IBinder token) {
7514        final long origId = Binder.clearCallingIdentity();
7515        try {
7516            synchronized(this) {
7517                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7518                if (r == null) {
7519                    return false;
7520                }
7521                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7522                return !r.task.mFullscreen;
7523            }
7524        } finally {
7525            Binder.restoreCallingIdentity(origId);
7526        }
7527    }
7528
7529    @Override
7530    public boolean isInPictureInPictureMode(IBinder token) {
7531        final long origId = Binder.clearCallingIdentity();
7532        try {
7533            synchronized(this) {
7534                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7535                if (stack == null) {
7536                    return false;
7537                }
7538                return stack.mStackId == PINNED_STACK_ID;
7539            }
7540        } finally {
7541            Binder.restoreCallingIdentity(origId);
7542        }
7543    }
7544
7545    @Override
7546    public void enterPictureInPictureMode(IBinder token) {
7547        final long origId = Binder.clearCallingIdentity();
7548        try {
7549            synchronized(this) {
7550                if (!mSupportsPictureInPicture) {
7551                    throw new IllegalStateException("enterPictureInPictureMode: "
7552                            + "Device doesn't support picture-in-picture mode.");
7553                }
7554
7555                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7556
7557                if (r == null) {
7558                    throw new IllegalStateException("enterPictureInPictureMode: "
7559                            + "Can't find activity for token=" + token);
7560                }
7561
7562                if (!r.supportsPictureInPicture()) {
7563                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7564                            + "Picture-In-Picture not supported for r=" + r);
7565                }
7566
7567                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7568                // current bounds.
7569                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7570                final Rect bounds = (pinnedStack != null)
7571                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7572
7573                mStackSupervisor.moveActivityToPinnedStackLocked(
7574                        r, "enterPictureInPictureMode", bounds);
7575            }
7576        } finally {
7577            Binder.restoreCallingIdentity(origId);
7578        }
7579    }
7580
7581    // =========================================================
7582    // PROCESS INFO
7583    // =========================================================
7584
7585    static class ProcessInfoService extends IProcessInfoService.Stub {
7586        final ActivityManagerService mActivityManagerService;
7587        ProcessInfoService(ActivityManagerService activityManagerService) {
7588            mActivityManagerService = activityManagerService;
7589        }
7590
7591        @Override
7592        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7593            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7594                    /*in*/ pids, /*out*/ states, null);
7595        }
7596
7597        @Override
7598        public void getProcessStatesAndOomScoresFromPids(
7599                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7600            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7601                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7602        }
7603    }
7604
7605    /**
7606     * For each PID in the given input array, write the current process state
7607     * for that process into the states array, or -1 to indicate that no
7608     * process with the given PID exists. If scores array is provided, write
7609     * the oom score for the process into the scores array, with INVALID_ADJ
7610     * indicating the PID doesn't exist.
7611     */
7612    public void getProcessStatesAndOomScoresForPIDs(
7613            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7614        if (scores != null) {
7615            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7616                    "getProcessStatesAndOomScoresForPIDs()");
7617        }
7618
7619        if (pids == null) {
7620            throw new NullPointerException("pids");
7621        } else if (states == null) {
7622            throw new NullPointerException("states");
7623        } else if (pids.length != states.length) {
7624            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7625        } else if (scores != null && pids.length != scores.length) {
7626            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7627        }
7628
7629        synchronized (mPidsSelfLocked) {
7630            for (int i = 0; i < pids.length; i++) {
7631                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7632                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7633                        pr.curProcState;
7634                if (scores != null) {
7635                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7636                }
7637            }
7638        }
7639    }
7640
7641    // =========================================================
7642    // PERMISSIONS
7643    // =========================================================
7644
7645    static class PermissionController extends IPermissionController.Stub {
7646        ActivityManagerService mActivityManagerService;
7647        PermissionController(ActivityManagerService activityManagerService) {
7648            mActivityManagerService = activityManagerService;
7649        }
7650
7651        @Override
7652        public boolean checkPermission(String permission, int pid, int uid) {
7653            return mActivityManagerService.checkPermission(permission, pid,
7654                    uid) == PackageManager.PERMISSION_GRANTED;
7655        }
7656
7657        @Override
7658        public String[] getPackagesForUid(int uid) {
7659            return mActivityManagerService.mContext.getPackageManager()
7660                    .getPackagesForUid(uid);
7661        }
7662
7663        @Override
7664        public boolean isRuntimePermission(String permission) {
7665            try {
7666                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7667                        .getPermissionInfo(permission, 0);
7668                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7669            } catch (NameNotFoundException nnfe) {
7670                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7671            }
7672            return false;
7673        }
7674    }
7675
7676    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7677        @Override
7678        public int checkComponentPermission(String permission, int pid, int uid,
7679                int owningUid, boolean exported) {
7680            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7681                    owningUid, exported);
7682        }
7683
7684        @Override
7685        public Object getAMSLock() {
7686            return ActivityManagerService.this;
7687        }
7688    }
7689
7690    /**
7691     * This can be called with or without the global lock held.
7692     */
7693    int checkComponentPermission(String permission, int pid, int uid,
7694            int owningUid, boolean exported) {
7695        if (pid == MY_PID) {
7696            return PackageManager.PERMISSION_GRANTED;
7697        }
7698        return ActivityManager.checkComponentPermission(permission, uid,
7699                owningUid, exported);
7700    }
7701
7702    /**
7703     * As the only public entry point for permissions checking, this method
7704     * can enforce the semantic that requesting a check on a null global
7705     * permission is automatically denied.  (Internally a null permission
7706     * string is used when calling {@link #checkComponentPermission} in cases
7707     * when only uid-based security is needed.)
7708     *
7709     * This can be called with or without the global lock held.
7710     */
7711    @Override
7712    public int checkPermission(String permission, int pid, int uid) {
7713        if (permission == null) {
7714            return PackageManager.PERMISSION_DENIED;
7715        }
7716        return checkComponentPermission(permission, pid, uid, -1, true);
7717    }
7718
7719    @Override
7720    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7721        if (permission == null) {
7722            return PackageManager.PERMISSION_DENIED;
7723        }
7724
7725        // We might be performing an operation on behalf of an indirect binder
7726        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7727        // client identity accordingly before proceeding.
7728        Identity tlsIdentity = sCallerIdentity.get();
7729        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7730            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7731                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7732            uid = tlsIdentity.uid;
7733            pid = tlsIdentity.pid;
7734        }
7735
7736        return checkComponentPermission(permission, pid, uid, -1, true);
7737    }
7738
7739    /**
7740     * Binder IPC calls go through the public entry point.
7741     * This can be called with or without the global lock held.
7742     */
7743    int checkCallingPermission(String permission) {
7744        return checkPermission(permission,
7745                Binder.getCallingPid(),
7746                UserHandle.getAppId(Binder.getCallingUid()));
7747    }
7748
7749    /**
7750     * This can be called with or without the global lock held.
7751     */
7752    void enforceCallingPermission(String permission, String func) {
7753        if (checkCallingPermission(permission)
7754                == PackageManager.PERMISSION_GRANTED) {
7755            return;
7756        }
7757
7758        String msg = "Permission Denial: " + func + " from pid="
7759                + Binder.getCallingPid()
7760                + ", uid=" + Binder.getCallingUid()
7761                + " requires " + permission;
7762        Slog.w(TAG, msg);
7763        throw new SecurityException(msg);
7764    }
7765
7766    /**
7767     * Determine if UID is holding permissions required to access {@link Uri} in
7768     * the given {@link ProviderInfo}. Final permission checking is always done
7769     * in {@link ContentProvider}.
7770     */
7771    private final boolean checkHoldingPermissionsLocked(
7772            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7773        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7774                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7775        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7776            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7777                    != PERMISSION_GRANTED) {
7778                return false;
7779            }
7780        }
7781        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7782    }
7783
7784    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7785            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7786        if (pi.applicationInfo.uid == uid) {
7787            return true;
7788        } else if (!pi.exported) {
7789            return false;
7790        }
7791
7792        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7793        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7794        try {
7795            // check if target holds top-level <provider> permissions
7796            if (!readMet && pi.readPermission != null && considerUidPermissions
7797                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7798                readMet = true;
7799            }
7800            if (!writeMet && pi.writePermission != null && considerUidPermissions
7801                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7802                writeMet = true;
7803            }
7804
7805            // track if unprotected read/write is allowed; any denied
7806            // <path-permission> below removes this ability
7807            boolean allowDefaultRead = pi.readPermission == null;
7808            boolean allowDefaultWrite = pi.writePermission == null;
7809
7810            // check if target holds any <path-permission> that match uri
7811            final PathPermission[] pps = pi.pathPermissions;
7812            if (pps != null) {
7813                final String path = grantUri.uri.getPath();
7814                int i = pps.length;
7815                while (i > 0 && (!readMet || !writeMet)) {
7816                    i--;
7817                    PathPermission pp = pps[i];
7818                    if (pp.match(path)) {
7819                        if (!readMet) {
7820                            final String pprperm = pp.getReadPermission();
7821                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7822                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7823                                    + ": match=" + pp.match(path)
7824                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7825                            if (pprperm != null) {
7826                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7827                                        == PERMISSION_GRANTED) {
7828                                    readMet = true;
7829                                } else {
7830                                    allowDefaultRead = false;
7831                                }
7832                            }
7833                        }
7834                        if (!writeMet) {
7835                            final String ppwperm = pp.getWritePermission();
7836                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7837                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7838                                    + ": match=" + pp.match(path)
7839                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7840                            if (ppwperm != null) {
7841                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7842                                        == PERMISSION_GRANTED) {
7843                                    writeMet = true;
7844                                } else {
7845                                    allowDefaultWrite = false;
7846                                }
7847                            }
7848                        }
7849                    }
7850                }
7851            }
7852
7853            // grant unprotected <provider> read/write, if not blocked by
7854            // <path-permission> above
7855            if (allowDefaultRead) readMet = true;
7856            if (allowDefaultWrite) writeMet = true;
7857
7858        } catch (RemoteException e) {
7859            return false;
7860        }
7861
7862        return readMet && writeMet;
7863    }
7864
7865    public int getAppStartMode(int uid, String packageName) {
7866        synchronized (this) {
7867            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7868        }
7869    }
7870
7871    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7872            boolean allowWhenForeground) {
7873        UidRecord uidRec = mActiveUids.get(uid);
7874        if (!mLenientBackgroundCheck) {
7875            if (!allowWhenForeground || uidRec == null
7876                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7877                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7878                        packageName) != AppOpsManager.MODE_ALLOWED) {
7879                    return ActivityManager.APP_START_MODE_DELAYED;
7880                }
7881            }
7882
7883        } else if (uidRec == null || uidRec.idle) {
7884            if (callingPid >= 0) {
7885                ProcessRecord proc;
7886                synchronized (mPidsSelfLocked) {
7887                    proc = mPidsSelfLocked.get(callingPid);
7888                }
7889                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7890                    // Whoever is instigating this is in the foreground, so we will allow it
7891                    // to go through.
7892                    return ActivityManager.APP_START_MODE_NORMAL;
7893                }
7894            }
7895            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7896                    != AppOpsManager.MODE_ALLOWED) {
7897                return ActivityManager.APP_START_MODE_DELAYED;
7898            }
7899        }
7900        return ActivityManager.APP_START_MODE_NORMAL;
7901    }
7902
7903    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7904        ProviderInfo pi = null;
7905        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7906        if (cpr != null) {
7907            pi = cpr.info;
7908        } else {
7909            try {
7910                pi = AppGlobals.getPackageManager().resolveContentProvider(
7911                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7912                        userHandle);
7913            } catch (RemoteException ex) {
7914            }
7915        }
7916        return pi;
7917    }
7918
7919    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7920        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7921        if (targetUris != null) {
7922            return targetUris.get(grantUri);
7923        }
7924        return null;
7925    }
7926
7927    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7928            String targetPkg, int targetUid, GrantUri grantUri) {
7929        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7930        if (targetUris == null) {
7931            targetUris = Maps.newArrayMap();
7932            mGrantedUriPermissions.put(targetUid, targetUris);
7933        }
7934
7935        UriPermission perm = targetUris.get(grantUri);
7936        if (perm == null) {
7937            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7938            targetUris.put(grantUri, perm);
7939        }
7940
7941        return perm;
7942    }
7943
7944    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7945            final int modeFlags) {
7946        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7947        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7948                : UriPermission.STRENGTH_OWNED;
7949
7950        // Root gets to do everything.
7951        if (uid == 0) {
7952            return true;
7953        }
7954
7955        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7956        if (perms == null) return false;
7957
7958        // First look for exact match
7959        final UriPermission exactPerm = perms.get(grantUri);
7960        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7961            return true;
7962        }
7963
7964        // No exact match, look for prefixes
7965        final int N = perms.size();
7966        for (int i = 0; i < N; i++) {
7967            final UriPermission perm = perms.valueAt(i);
7968            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7969                    && perm.getStrength(modeFlags) >= minStrength) {
7970                return true;
7971            }
7972        }
7973
7974        return false;
7975    }
7976
7977    /**
7978     * @param uri This uri must NOT contain an embedded userId.
7979     * @param userId The userId in which the uri is to be resolved.
7980     */
7981    @Override
7982    public int checkUriPermission(Uri uri, int pid, int uid,
7983            final int modeFlags, int userId, IBinder callerToken) {
7984        enforceNotIsolatedCaller("checkUriPermission");
7985
7986        // Another redirected-binder-call permissions check as in
7987        // {@link checkPermissionWithToken}.
7988        Identity tlsIdentity = sCallerIdentity.get();
7989        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7990            uid = tlsIdentity.uid;
7991            pid = tlsIdentity.pid;
7992        }
7993
7994        // Our own process gets to do everything.
7995        if (pid == MY_PID) {
7996            return PackageManager.PERMISSION_GRANTED;
7997        }
7998        synchronized (this) {
7999            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8000                    ? PackageManager.PERMISSION_GRANTED
8001                    : PackageManager.PERMISSION_DENIED;
8002        }
8003    }
8004
8005    /**
8006     * Check if the targetPkg can be granted permission to access uri by
8007     * the callingUid using the given modeFlags.  Throws a security exception
8008     * if callingUid is not allowed to do this.  Returns the uid of the target
8009     * if the URI permission grant should be performed; returns -1 if it is not
8010     * needed (for example targetPkg already has permission to access the URI).
8011     * If you already know the uid of the target, you can supply it in
8012     * lastTargetUid else set that to -1.
8013     */
8014    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8015            final int modeFlags, int lastTargetUid) {
8016        if (!Intent.isAccessUriMode(modeFlags)) {
8017            return -1;
8018        }
8019
8020        if (targetPkg != null) {
8021            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8022                    "Checking grant " + targetPkg + " permission to " + grantUri);
8023        }
8024
8025        final IPackageManager pm = AppGlobals.getPackageManager();
8026
8027        // If this is not a content: uri, we can't do anything with it.
8028        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8029            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8030                    "Can't grant URI permission for non-content URI: " + grantUri);
8031            return -1;
8032        }
8033
8034        final String authority = grantUri.uri.getAuthority();
8035        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8036                MATCH_DEBUG_TRIAGED_MISSING);
8037        if (pi == null) {
8038            Slog.w(TAG, "No content provider found for permission check: " +
8039                    grantUri.uri.toSafeString());
8040            return -1;
8041        }
8042
8043        int targetUid = lastTargetUid;
8044        if (targetUid < 0 && targetPkg != null) {
8045            try {
8046                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8047                        UserHandle.getUserId(callingUid));
8048                if (targetUid < 0) {
8049                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8050                            "Can't grant URI permission no uid for: " + targetPkg);
8051                    return -1;
8052                }
8053            } catch (RemoteException ex) {
8054                return -1;
8055            }
8056        }
8057
8058        if (targetUid >= 0) {
8059            // First...  does the target actually need this permission?
8060            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8061                // No need to grant the target this permission.
8062                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8063                        "Target " + targetPkg + " already has full permission to " + grantUri);
8064                return -1;
8065            }
8066        } else {
8067            // First...  there is no target package, so can anyone access it?
8068            boolean allowed = pi.exported;
8069            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8070                if (pi.readPermission != null) {
8071                    allowed = false;
8072                }
8073            }
8074            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8075                if (pi.writePermission != null) {
8076                    allowed = false;
8077                }
8078            }
8079            if (allowed) {
8080                return -1;
8081            }
8082        }
8083
8084        /* There is a special cross user grant if:
8085         * - The target is on another user.
8086         * - Apps on the current user can access the uri without any uid permissions.
8087         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8088         * grant uri permissions.
8089         */
8090        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8091                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8092                modeFlags, false /*without considering the uid permissions*/);
8093
8094        // Second...  is the provider allowing granting of URI permissions?
8095        if (!specialCrossUserGrant) {
8096            if (!pi.grantUriPermissions) {
8097                throw new SecurityException("Provider " + pi.packageName
8098                        + "/" + pi.name
8099                        + " does not allow granting of Uri permissions (uri "
8100                        + grantUri + ")");
8101            }
8102            if (pi.uriPermissionPatterns != null) {
8103                final int N = pi.uriPermissionPatterns.length;
8104                boolean allowed = false;
8105                for (int i=0; i<N; i++) {
8106                    if (pi.uriPermissionPatterns[i] != null
8107                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8108                        allowed = true;
8109                        break;
8110                    }
8111                }
8112                if (!allowed) {
8113                    throw new SecurityException("Provider " + pi.packageName
8114                            + "/" + pi.name
8115                            + " does not allow granting of permission to path of Uri "
8116                            + grantUri);
8117                }
8118            }
8119        }
8120
8121        // Third...  does the caller itself have permission to access
8122        // this uri?
8123        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8124            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8125                // Require they hold a strong enough Uri permission
8126                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8127                    throw new SecurityException("Uid " + callingUid
8128                            + " does not have permission to uri " + grantUri);
8129                }
8130            }
8131        }
8132        return targetUid;
8133    }
8134
8135    /**
8136     * @param uri This uri must NOT contain an embedded userId.
8137     * @param userId The userId in which the uri is to be resolved.
8138     */
8139    @Override
8140    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8141            final int modeFlags, int userId) {
8142        enforceNotIsolatedCaller("checkGrantUriPermission");
8143        synchronized(this) {
8144            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8145                    new GrantUri(userId, uri, false), modeFlags, -1);
8146        }
8147    }
8148
8149    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8150            final int modeFlags, UriPermissionOwner owner) {
8151        if (!Intent.isAccessUriMode(modeFlags)) {
8152            return;
8153        }
8154
8155        // So here we are: the caller has the assumed permission
8156        // to the uri, and the target doesn't.  Let's now give this to
8157        // the target.
8158
8159        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8160                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8161
8162        final String authority = grantUri.uri.getAuthority();
8163        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8164                MATCH_DEBUG_TRIAGED_MISSING);
8165        if (pi == null) {
8166            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8167            return;
8168        }
8169
8170        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8171            grantUri.prefix = true;
8172        }
8173        final UriPermission perm = findOrCreateUriPermissionLocked(
8174                pi.packageName, targetPkg, targetUid, grantUri);
8175        perm.grantModes(modeFlags, owner);
8176    }
8177
8178    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8179            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8180        if (targetPkg == null) {
8181            throw new NullPointerException("targetPkg");
8182        }
8183        int targetUid;
8184        final IPackageManager pm = AppGlobals.getPackageManager();
8185        try {
8186            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8187        } catch (RemoteException ex) {
8188            return;
8189        }
8190
8191        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8192                targetUid);
8193        if (targetUid < 0) {
8194            return;
8195        }
8196
8197        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8198                owner);
8199    }
8200
8201    static class NeededUriGrants extends ArrayList<GrantUri> {
8202        final String targetPkg;
8203        final int targetUid;
8204        final int flags;
8205
8206        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8207            this.targetPkg = targetPkg;
8208            this.targetUid = targetUid;
8209            this.flags = flags;
8210        }
8211    }
8212
8213    /**
8214     * Like checkGrantUriPermissionLocked, but takes an Intent.
8215     */
8216    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8217            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8218        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8219                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8220                + " clip=" + (intent != null ? intent.getClipData() : null)
8221                + " from " + intent + "; flags=0x"
8222                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8223
8224        if (targetPkg == null) {
8225            throw new NullPointerException("targetPkg");
8226        }
8227
8228        if (intent == null) {
8229            return null;
8230        }
8231        Uri data = intent.getData();
8232        ClipData clip = intent.getClipData();
8233        if (data == null && clip == null) {
8234            return null;
8235        }
8236        // Default userId for uris in the intent (if they don't specify it themselves)
8237        int contentUserHint = intent.getContentUserHint();
8238        if (contentUserHint == UserHandle.USER_CURRENT) {
8239            contentUserHint = UserHandle.getUserId(callingUid);
8240        }
8241        final IPackageManager pm = AppGlobals.getPackageManager();
8242        int targetUid;
8243        if (needed != null) {
8244            targetUid = needed.targetUid;
8245        } else {
8246            try {
8247                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8248                        targetUserId);
8249            } catch (RemoteException ex) {
8250                return null;
8251            }
8252            if (targetUid < 0) {
8253                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8254                        "Can't grant URI permission no uid for: " + targetPkg
8255                        + " on user " + targetUserId);
8256                return null;
8257            }
8258        }
8259        if (data != null) {
8260            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8261            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8262                    targetUid);
8263            if (targetUid > 0) {
8264                if (needed == null) {
8265                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8266                }
8267                needed.add(grantUri);
8268            }
8269        }
8270        if (clip != null) {
8271            for (int i=0; i<clip.getItemCount(); i++) {
8272                Uri uri = clip.getItemAt(i).getUri();
8273                if (uri != null) {
8274                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8275                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8276                            targetUid);
8277                    if (targetUid > 0) {
8278                        if (needed == null) {
8279                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8280                        }
8281                        needed.add(grantUri);
8282                    }
8283                } else {
8284                    Intent clipIntent = clip.getItemAt(i).getIntent();
8285                    if (clipIntent != null) {
8286                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8287                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8288                        if (newNeeded != null) {
8289                            needed = newNeeded;
8290                        }
8291                    }
8292                }
8293            }
8294        }
8295
8296        return needed;
8297    }
8298
8299    /**
8300     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8301     */
8302    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8303            UriPermissionOwner owner) {
8304        if (needed != null) {
8305            for (int i=0; i<needed.size(); i++) {
8306                GrantUri grantUri = needed.get(i);
8307                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8308                        grantUri, needed.flags, owner);
8309            }
8310        }
8311    }
8312
8313    void grantUriPermissionFromIntentLocked(int callingUid,
8314            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8315        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8316                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8317        if (needed == null) {
8318            return;
8319        }
8320
8321        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8322    }
8323
8324    /**
8325     * @param uri This uri must NOT contain an embedded userId.
8326     * @param userId The userId in which the uri is to be resolved.
8327     */
8328    @Override
8329    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8330            final int modeFlags, int userId) {
8331        enforceNotIsolatedCaller("grantUriPermission");
8332        GrantUri grantUri = new GrantUri(userId, uri, false);
8333        synchronized(this) {
8334            final ProcessRecord r = getRecordForAppLocked(caller);
8335            if (r == null) {
8336                throw new SecurityException("Unable to find app for caller "
8337                        + caller
8338                        + " when granting permission to uri " + grantUri);
8339            }
8340            if (targetPkg == null) {
8341                throw new IllegalArgumentException("null target");
8342            }
8343            if (grantUri == null) {
8344                throw new IllegalArgumentException("null uri");
8345            }
8346
8347            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8348                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8349                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8350                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8351
8352            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8353                    UserHandle.getUserId(r.uid));
8354        }
8355    }
8356
8357    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8358        if (perm.modeFlags == 0) {
8359            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8360                    perm.targetUid);
8361            if (perms != null) {
8362                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8363                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8364
8365                perms.remove(perm.uri);
8366                if (perms.isEmpty()) {
8367                    mGrantedUriPermissions.remove(perm.targetUid);
8368                }
8369            }
8370        }
8371    }
8372
8373    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8374        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8375                "Revoking all granted permissions to " + grantUri);
8376
8377        final IPackageManager pm = AppGlobals.getPackageManager();
8378        final String authority = grantUri.uri.getAuthority();
8379        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8380                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8381        if (pi == null) {
8382            Slog.w(TAG, "No content provider found for permission revoke: "
8383                    + grantUri.toSafeString());
8384            return;
8385        }
8386
8387        // Does the caller have this permission on the URI?
8388        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8389            // If they don't have direct access to the URI, then revoke any
8390            // ownerless URI permissions that have been granted to them.
8391            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8392            if (perms != null) {
8393                boolean persistChanged = false;
8394                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8395                    final UriPermission perm = it.next();
8396                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8397                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8398                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8399                                "Revoking non-owned " + perm.targetUid
8400                                + " permission to " + perm.uri);
8401                        persistChanged |= perm.revokeModes(
8402                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8403                        if (perm.modeFlags == 0) {
8404                            it.remove();
8405                        }
8406                    }
8407                }
8408                if (perms.isEmpty()) {
8409                    mGrantedUriPermissions.remove(callingUid);
8410                }
8411                if (persistChanged) {
8412                    schedulePersistUriGrants();
8413                }
8414            }
8415            return;
8416        }
8417
8418        boolean persistChanged = false;
8419
8420        // Go through all of the permissions and remove any that match.
8421        int N = mGrantedUriPermissions.size();
8422        for (int i = 0; i < N; i++) {
8423            final int targetUid = mGrantedUriPermissions.keyAt(i);
8424            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8425
8426            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8427                final UriPermission perm = it.next();
8428                if (perm.uri.sourceUserId == grantUri.sourceUserId
8429                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8430                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8431                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8432                    persistChanged |= perm.revokeModes(
8433                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8434                    if (perm.modeFlags == 0) {
8435                        it.remove();
8436                    }
8437                }
8438            }
8439
8440            if (perms.isEmpty()) {
8441                mGrantedUriPermissions.remove(targetUid);
8442                N--;
8443                i--;
8444            }
8445        }
8446
8447        if (persistChanged) {
8448            schedulePersistUriGrants();
8449        }
8450    }
8451
8452    /**
8453     * @param uri This uri must NOT contain an embedded userId.
8454     * @param userId The userId in which the uri is to be resolved.
8455     */
8456    @Override
8457    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8458            int userId) {
8459        enforceNotIsolatedCaller("revokeUriPermission");
8460        synchronized(this) {
8461            final ProcessRecord r = getRecordForAppLocked(caller);
8462            if (r == null) {
8463                throw new SecurityException("Unable to find app for caller "
8464                        + caller
8465                        + " when revoking permission to uri " + uri);
8466            }
8467            if (uri == null) {
8468                Slog.w(TAG, "revokeUriPermission: null uri");
8469                return;
8470            }
8471
8472            if (!Intent.isAccessUriMode(modeFlags)) {
8473                return;
8474            }
8475
8476            final String authority = uri.getAuthority();
8477            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8478                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8479            if (pi == null) {
8480                Slog.w(TAG, "No content provider found for permission revoke: "
8481                        + uri.toSafeString());
8482                return;
8483            }
8484
8485            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8486        }
8487    }
8488
8489    /**
8490     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8491     * given package.
8492     *
8493     * @param packageName Package name to match, or {@code null} to apply to all
8494     *            packages.
8495     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8496     *            to all users.
8497     * @param persistable If persistable grants should be removed.
8498     */
8499    private void removeUriPermissionsForPackageLocked(
8500            String packageName, int userHandle, boolean persistable) {
8501        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8502            throw new IllegalArgumentException("Must narrow by either package or user");
8503        }
8504
8505        boolean persistChanged = false;
8506
8507        int N = mGrantedUriPermissions.size();
8508        for (int i = 0; i < N; i++) {
8509            final int targetUid = mGrantedUriPermissions.keyAt(i);
8510            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8511
8512            // Only inspect grants matching user
8513            if (userHandle == UserHandle.USER_ALL
8514                    || userHandle == UserHandle.getUserId(targetUid)) {
8515                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8516                    final UriPermission perm = it.next();
8517
8518                    // Only inspect grants matching package
8519                    if (packageName == null || perm.sourcePkg.equals(packageName)
8520                            || perm.targetPkg.equals(packageName)) {
8521                        persistChanged |= perm.revokeModes(persistable
8522                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8523
8524                        // Only remove when no modes remain; any persisted grants
8525                        // will keep this alive.
8526                        if (perm.modeFlags == 0) {
8527                            it.remove();
8528                        }
8529                    }
8530                }
8531
8532                if (perms.isEmpty()) {
8533                    mGrantedUriPermissions.remove(targetUid);
8534                    N--;
8535                    i--;
8536                }
8537            }
8538        }
8539
8540        if (persistChanged) {
8541            schedulePersistUriGrants();
8542        }
8543    }
8544
8545    @Override
8546    public IBinder newUriPermissionOwner(String name) {
8547        enforceNotIsolatedCaller("newUriPermissionOwner");
8548        synchronized(this) {
8549            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8550            return owner.getExternalTokenLocked();
8551        }
8552    }
8553
8554    @Override
8555    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8556        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8557        synchronized(this) {
8558            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8559            if (r == null) {
8560                throw new IllegalArgumentException("Activity does not exist; token="
8561                        + activityToken);
8562            }
8563            return r.getUriPermissionsLocked().getExternalTokenLocked();
8564        }
8565    }
8566    /**
8567     * @param uri This uri must NOT contain an embedded userId.
8568     * @param sourceUserId The userId in which the uri is to be resolved.
8569     * @param targetUserId The userId of the app that receives the grant.
8570     */
8571    @Override
8572    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8573            final int modeFlags, int sourceUserId, int targetUserId) {
8574        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8575                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8576                "grantUriPermissionFromOwner", null);
8577        synchronized(this) {
8578            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8579            if (owner == null) {
8580                throw new IllegalArgumentException("Unknown owner: " + token);
8581            }
8582            if (fromUid != Binder.getCallingUid()) {
8583                if (Binder.getCallingUid() != Process.myUid()) {
8584                    // Only system code can grant URI permissions on behalf
8585                    // of other users.
8586                    throw new SecurityException("nice try");
8587                }
8588            }
8589            if (targetPkg == null) {
8590                throw new IllegalArgumentException("null target");
8591            }
8592            if (uri == null) {
8593                throw new IllegalArgumentException("null uri");
8594            }
8595
8596            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8597                    modeFlags, owner, targetUserId);
8598        }
8599    }
8600
8601    /**
8602     * @param uri This uri must NOT contain an embedded userId.
8603     * @param userId The userId in which the uri is to be resolved.
8604     */
8605    @Override
8606    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8607        synchronized(this) {
8608            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8609            if (owner == null) {
8610                throw new IllegalArgumentException("Unknown owner: " + token);
8611            }
8612
8613            if (uri == null) {
8614                owner.removeUriPermissionsLocked(mode);
8615            } else {
8616                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8617                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8618            }
8619        }
8620    }
8621
8622    private void schedulePersistUriGrants() {
8623        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8624            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8625                    10 * DateUtils.SECOND_IN_MILLIS);
8626        }
8627    }
8628
8629    private void writeGrantedUriPermissions() {
8630        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8631
8632        // Snapshot permissions so we can persist without lock
8633        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8634        synchronized (this) {
8635            final int size = mGrantedUriPermissions.size();
8636            for (int i = 0; i < size; i++) {
8637                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8638                for (UriPermission perm : perms.values()) {
8639                    if (perm.persistedModeFlags != 0) {
8640                        persist.add(perm.snapshot());
8641                    }
8642                }
8643            }
8644        }
8645
8646        FileOutputStream fos = null;
8647        try {
8648            fos = mGrantFile.startWrite();
8649
8650            XmlSerializer out = new FastXmlSerializer();
8651            out.setOutput(fos, StandardCharsets.UTF_8.name());
8652            out.startDocument(null, true);
8653            out.startTag(null, TAG_URI_GRANTS);
8654            for (UriPermission.Snapshot perm : persist) {
8655                out.startTag(null, TAG_URI_GRANT);
8656                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8657                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8658                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8659                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8660                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8661                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8662                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8663                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8664                out.endTag(null, TAG_URI_GRANT);
8665            }
8666            out.endTag(null, TAG_URI_GRANTS);
8667            out.endDocument();
8668
8669            mGrantFile.finishWrite(fos);
8670        } catch (IOException e) {
8671            if (fos != null) {
8672                mGrantFile.failWrite(fos);
8673            }
8674        }
8675    }
8676
8677    private void readGrantedUriPermissionsLocked() {
8678        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8679
8680        final long now = System.currentTimeMillis();
8681
8682        FileInputStream fis = null;
8683        try {
8684            fis = mGrantFile.openRead();
8685            final XmlPullParser in = Xml.newPullParser();
8686            in.setInput(fis, StandardCharsets.UTF_8.name());
8687
8688            int type;
8689            while ((type = in.next()) != END_DOCUMENT) {
8690                final String tag = in.getName();
8691                if (type == START_TAG) {
8692                    if (TAG_URI_GRANT.equals(tag)) {
8693                        final int sourceUserId;
8694                        final int targetUserId;
8695                        final int userHandle = readIntAttribute(in,
8696                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8697                        if (userHandle != UserHandle.USER_NULL) {
8698                            // For backwards compatibility.
8699                            sourceUserId = userHandle;
8700                            targetUserId = userHandle;
8701                        } else {
8702                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8703                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8704                        }
8705                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8706                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8707                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8708                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8709                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8710                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8711
8712                        // Sanity check that provider still belongs to source package
8713                        // Both direct boot aware and unaware packages are fine as we
8714                        // will do filtering at query time to avoid multiple parsing.
8715                        final ProviderInfo pi = getProviderInfoLocked(
8716                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8717                                        | MATCH_DIRECT_BOOT_UNAWARE);
8718                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8719                            int targetUid = -1;
8720                            try {
8721                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8722                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8723                            } catch (RemoteException e) {
8724                            }
8725                            if (targetUid != -1) {
8726                                final UriPermission perm = findOrCreateUriPermissionLocked(
8727                                        sourcePkg, targetPkg, targetUid,
8728                                        new GrantUri(sourceUserId, uri, prefix));
8729                                perm.initPersistedModes(modeFlags, createdTime);
8730                            }
8731                        } else {
8732                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8733                                    + " but instead found " + pi);
8734                        }
8735                    }
8736                }
8737            }
8738        } catch (FileNotFoundException e) {
8739            // Missing grants is okay
8740        } catch (IOException e) {
8741            Slog.wtf(TAG, "Failed reading Uri grants", e);
8742        } catch (XmlPullParserException e) {
8743            Slog.wtf(TAG, "Failed reading Uri grants", e);
8744        } finally {
8745            IoUtils.closeQuietly(fis);
8746        }
8747    }
8748
8749    /**
8750     * @param uri This uri must NOT contain an embedded userId.
8751     * @param userId The userId in which the uri is to be resolved.
8752     */
8753    @Override
8754    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8755        enforceNotIsolatedCaller("takePersistableUriPermission");
8756
8757        Preconditions.checkFlagsArgument(modeFlags,
8758                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8759
8760        synchronized (this) {
8761            final int callingUid = Binder.getCallingUid();
8762            boolean persistChanged = false;
8763            GrantUri grantUri = new GrantUri(userId, uri, false);
8764
8765            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8766                    new GrantUri(userId, uri, false));
8767            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8768                    new GrantUri(userId, uri, true));
8769
8770            final boolean exactValid = (exactPerm != null)
8771                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8772            final boolean prefixValid = (prefixPerm != null)
8773                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8774
8775            if (!(exactValid || prefixValid)) {
8776                throw new SecurityException("No persistable permission grants found for UID "
8777                        + callingUid + " and Uri " + grantUri.toSafeString());
8778            }
8779
8780            if (exactValid) {
8781                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8782            }
8783            if (prefixValid) {
8784                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8785            }
8786
8787            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8788
8789            if (persistChanged) {
8790                schedulePersistUriGrants();
8791            }
8792        }
8793    }
8794
8795    /**
8796     * @param uri This uri must NOT contain an embedded userId.
8797     * @param userId The userId in which the uri is to be resolved.
8798     */
8799    @Override
8800    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8801        enforceNotIsolatedCaller("releasePersistableUriPermission");
8802
8803        Preconditions.checkFlagsArgument(modeFlags,
8804                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8805
8806        synchronized (this) {
8807            final int callingUid = Binder.getCallingUid();
8808            boolean persistChanged = false;
8809
8810            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8811                    new GrantUri(userId, uri, false));
8812            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8813                    new GrantUri(userId, uri, true));
8814            if (exactPerm == null && prefixPerm == null) {
8815                throw new SecurityException("No permission grants found for UID " + callingUid
8816                        + " and Uri " + uri.toSafeString());
8817            }
8818
8819            if (exactPerm != null) {
8820                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8821                removeUriPermissionIfNeededLocked(exactPerm);
8822            }
8823            if (prefixPerm != null) {
8824                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8825                removeUriPermissionIfNeededLocked(prefixPerm);
8826            }
8827
8828            if (persistChanged) {
8829                schedulePersistUriGrants();
8830            }
8831        }
8832    }
8833
8834    /**
8835     * Prune any older {@link UriPermission} for the given UID until outstanding
8836     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8837     *
8838     * @return if any mutations occured that require persisting.
8839     */
8840    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8841        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8842        if (perms == null) return false;
8843        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8844
8845        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8846        for (UriPermission perm : perms.values()) {
8847            if (perm.persistedModeFlags != 0) {
8848                persisted.add(perm);
8849            }
8850        }
8851
8852        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8853        if (trimCount <= 0) return false;
8854
8855        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8856        for (int i = 0; i < trimCount; i++) {
8857            final UriPermission perm = persisted.get(i);
8858
8859            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8860                    "Trimming grant created at " + perm.persistedCreateTime);
8861
8862            perm.releasePersistableModes(~0);
8863            removeUriPermissionIfNeededLocked(perm);
8864        }
8865
8866        return true;
8867    }
8868
8869    @Override
8870    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8871            String packageName, boolean incoming) {
8872        enforceNotIsolatedCaller("getPersistedUriPermissions");
8873        Preconditions.checkNotNull(packageName, "packageName");
8874
8875        final int callingUid = Binder.getCallingUid();
8876        final int callingUserId = UserHandle.getUserId(callingUid);
8877        final IPackageManager pm = AppGlobals.getPackageManager();
8878        try {
8879            final int packageUid = pm.getPackageUid(packageName,
8880                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8881            if (packageUid != callingUid) {
8882                throw new SecurityException(
8883                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8884            }
8885        } catch (RemoteException e) {
8886            throw new SecurityException("Failed to verify package name ownership");
8887        }
8888
8889        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8890        synchronized (this) {
8891            if (incoming) {
8892                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8893                        callingUid);
8894                if (perms == null) {
8895                    Slog.w(TAG, "No permission grants found for " + packageName);
8896                } else {
8897                    for (UriPermission perm : perms.values()) {
8898                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8899                            result.add(perm.buildPersistedPublicApiObject());
8900                        }
8901                    }
8902                }
8903            } else {
8904                final int size = mGrantedUriPermissions.size();
8905                for (int i = 0; i < size; i++) {
8906                    final ArrayMap<GrantUri, UriPermission> perms =
8907                            mGrantedUriPermissions.valueAt(i);
8908                    for (UriPermission perm : perms.values()) {
8909                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8910                            result.add(perm.buildPersistedPublicApiObject());
8911                        }
8912                    }
8913                }
8914            }
8915        }
8916        return new ParceledListSlice<android.content.UriPermission>(result);
8917    }
8918
8919    @Override
8920    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8921            String packageName, int userId) {
8922        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8923                "getGrantedUriPermissions");
8924
8925        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8926        synchronized (this) {
8927            final int size = mGrantedUriPermissions.size();
8928            for (int i = 0; i < size; i++) {
8929                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8930                for (UriPermission perm : perms.values()) {
8931                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8932                            && perm.persistedModeFlags != 0) {
8933                        result.add(perm.buildPersistedPublicApiObject());
8934                    }
8935                }
8936            }
8937        }
8938        return new ParceledListSlice<android.content.UriPermission>(result);
8939    }
8940
8941    @Override
8942    public void clearGrantedUriPermissions(String packageName, int userId) {
8943        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8944                "clearGrantedUriPermissions");
8945        removeUriPermissionsForPackageLocked(packageName, userId, true);
8946    }
8947
8948    @Override
8949    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8950        synchronized (this) {
8951            ProcessRecord app =
8952                who != null ? getRecordForAppLocked(who) : null;
8953            if (app == null) return;
8954
8955            Message msg = Message.obtain();
8956            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8957            msg.obj = app;
8958            msg.arg1 = waiting ? 1 : 0;
8959            mUiHandler.sendMessage(msg);
8960        }
8961    }
8962
8963    @Override
8964    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8965        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8966        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8967        outInfo.availMem = Process.getFreeMemory();
8968        outInfo.totalMem = Process.getTotalMemory();
8969        outInfo.threshold = homeAppMem;
8970        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8971        outInfo.hiddenAppThreshold = cachedAppMem;
8972        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8973                ProcessList.SERVICE_ADJ);
8974        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8975                ProcessList.VISIBLE_APP_ADJ);
8976        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8977                ProcessList.FOREGROUND_APP_ADJ);
8978    }
8979
8980    // =========================================================
8981    // TASK MANAGEMENT
8982    // =========================================================
8983
8984    @Override
8985    public List<IAppTask> getAppTasks(String callingPackage) {
8986        int callingUid = Binder.getCallingUid();
8987        long ident = Binder.clearCallingIdentity();
8988
8989        synchronized(this) {
8990            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8991            try {
8992                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8993
8994                final int N = mRecentTasks.size();
8995                for (int i = 0; i < N; i++) {
8996                    TaskRecord tr = mRecentTasks.get(i);
8997                    // Skip tasks that do not match the caller.  We don't need to verify
8998                    // callingPackage, because we are also limiting to callingUid and know
8999                    // that will limit to the correct security sandbox.
9000                    if (tr.effectiveUid != callingUid) {
9001                        continue;
9002                    }
9003                    Intent intent = tr.getBaseIntent();
9004                    if (intent == null ||
9005                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9006                        continue;
9007                    }
9008                    ActivityManager.RecentTaskInfo taskInfo =
9009                            createRecentTaskInfoFromTaskRecord(tr);
9010                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9011                    list.add(taskImpl);
9012                }
9013            } finally {
9014                Binder.restoreCallingIdentity(ident);
9015            }
9016            return list;
9017        }
9018    }
9019
9020    @Override
9021    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9022        final int callingUid = Binder.getCallingUid();
9023        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9024
9025        synchronized(this) {
9026            if (DEBUG_ALL) Slog.v(
9027                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9028
9029            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9030                    callingUid);
9031
9032            // TODO: Improve with MRU list from all ActivityStacks.
9033            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9034        }
9035
9036        return list;
9037    }
9038
9039    /**
9040     * Creates a new RecentTaskInfo from a TaskRecord.
9041     */
9042    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9043        // Update the task description to reflect any changes in the task stack
9044        tr.updateTaskDescription();
9045
9046        // Compose the recent task info
9047        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9048        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9049        rti.persistentId = tr.taskId;
9050        rti.baseIntent = new Intent(tr.getBaseIntent());
9051        rti.origActivity = tr.origActivity;
9052        rti.realActivity = tr.realActivity;
9053        rti.description = tr.lastDescription;
9054        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9055        rti.userId = tr.userId;
9056        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9057        rti.firstActiveTime = tr.firstActiveTime;
9058        rti.lastActiveTime = tr.lastActiveTime;
9059        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9060        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9061        rti.numActivities = 0;
9062        if (tr.mBounds != null) {
9063            rti.bounds = new Rect(tr.mBounds);
9064        }
9065        rti.isDockable = tr.canGoInDockedStack();
9066        rti.resizeMode = tr.mResizeMode;
9067
9068        ActivityRecord base = null;
9069        ActivityRecord top = null;
9070        ActivityRecord tmp;
9071
9072        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9073            tmp = tr.mActivities.get(i);
9074            if (tmp.finishing) {
9075                continue;
9076            }
9077            base = tmp;
9078            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9079                top = base;
9080            }
9081            rti.numActivities++;
9082        }
9083
9084        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9085        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9086
9087        return rti;
9088    }
9089
9090    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9091        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9092                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9093        if (!allowed) {
9094            if (checkPermission(android.Manifest.permission.GET_TASKS,
9095                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9096                // Temporary compatibility: some existing apps on the system image may
9097                // still be requesting the old permission and not switched to the new
9098                // one; if so, we'll still allow them full access.  This means we need
9099                // to see if they are holding the old permission and are a system app.
9100                try {
9101                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9102                        allowed = true;
9103                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9104                                + " is using old GET_TASKS but privileged; allowing");
9105                    }
9106                } catch (RemoteException e) {
9107                }
9108            }
9109        }
9110        if (!allowed) {
9111            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9112                    + " does not hold REAL_GET_TASKS; limiting output");
9113        }
9114        return allowed;
9115    }
9116
9117    @Override
9118    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9119            int userId) {
9120        final int callingUid = Binder.getCallingUid();
9121        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9122                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9123
9124        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9125        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9126        synchronized (this) {
9127            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9128                    callingUid);
9129            final boolean detailed = checkCallingPermission(
9130                    android.Manifest.permission.GET_DETAILED_TASKS)
9131                    == PackageManager.PERMISSION_GRANTED;
9132
9133            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9134                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9135                return ParceledListSlice.emptyList();
9136            }
9137            mRecentTasks.loadUserRecentsLocked(userId);
9138
9139            final int recentsCount = mRecentTasks.size();
9140            ArrayList<ActivityManager.RecentTaskInfo> res =
9141                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9142
9143            final Set<Integer> includedUsers;
9144            if (includeProfiles) {
9145                includedUsers = mUserController.getProfileIds(userId);
9146            } else {
9147                includedUsers = new HashSet<>();
9148            }
9149            includedUsers.add(Integer.valueOf(userId));
9150
9151            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9152                TaskRecord tr = mRecentTasks.get(i);
9153                // Only add calling user or related users recent tasks
9154                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9155                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9156                    continue;
9157                }
9158
9159                if (tr.realActivitySuspended) {
9160                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9161                    continue;
9162                }
9163
9164                // Return the entry if desired by the caller.  We always return
9165                // the first entry, because callers always expect this to be the
9166                // foreground app.  We may filter others if the caller has
9167                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9168                // we should exclude the entry.
9169
9170                if (i == 0
9171                        || withExcluded
9172                        || (tr.intent == null)
9173                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9174                                == 0)) {
9175                    if (!allowed) {
9176                        // If the caller doesn't have the GET_TASKS permission, then only
9177                        // allow them to see a small subset of tasks -- their own and home.
9178                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9179                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9180                            continue;
9181                        }
9182                    }
9183                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9184                        if (tr.stack != null && tr.stack.isHomeStack()) {
9185                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9186                                    "Skipping, home stack task: " + tr);
9187                            continue;
9188                        }
9189                    }
9190                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9191                        final ActivityStack stack = tr.stack;
9192                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9193                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9194                                    "Skipping, top task in docked stack: " + tr);
9195                            continue;
9196                        }
9197                    }
9198                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9199                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9200                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9201                                    "Skipping, pinned stack task: " + tr);
9202                            continue;
9203                        }
9204                    }
9205                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9206                        // Don't include auto remove tasks that are finished or finishing.
9207                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9208                                "Skipping, auto-remove without activity: " + tr);
9209                        continue;
9210                    }
9211                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9212                            && !tr.isAvailable) {
9213                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9214                                "Skipping, unavail real act: " + tr);
9215                        continue;
9216                    }
9217
9218                    if (!tr.mUserSetupComplete) {
9219                        // Don't include task launched while user is not done setting-up.
9220                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9221                                "Skipping, user setup not complete: " + tr);
9222                        continue;
9223                    }
9224
9225                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9226                    if (!detailed) {
9227                        rti.baseIntent.replaceExtras((Bundle)null);
9228                    }
9229
9230                    res.add(rti);
9231                    maxNum--;
9232                }
9233            }
9234            return new ParceledListSlice<>(res);
9235        }
9236    }
9237
9238    @Override
9239    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9240        synchronized (this) {
9241            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9242                    "getTaskThumbnail()");
9243            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9244                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9245            if (tr != null) {
9246                return tr.getTaskThumbnailLocked();
9247            }
9248        }
9249        return null;
9250    }
9251
9252    @Override
9253    public int addAppTask(IBinder activityToken, Intent intent,
9254            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9255        final int callingUid = Binder.getCallingUid();
9256        final long callingIdent = Binder.clearCallingIdentity();
9257
9258        try {
9259            synchronized (this) {
9260                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9261                if (r == null) {
9262                    throw new IllegalArgumentException("Activity does not exist; token="
9263                            + activityToken);
9264                }
9265                ComponentName comp = intent.getComponent();
9266                if (comp == null) {
9267                    throw new IllegalArgumentException("Intent " + intent
9268                            + " must specify explicit component");
9269                }
9270                if (thumbnail.getWidth() != mThumbnailWidth
9271                        || thumbnail.getHeight() != mThumbnailHeight) {
9272                    throw new IllegalArgumentException("Bad thumbnail size: got "
9273                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9274                            + mThumbnailWidth + "x" + mThumbnailHeight);
9275                }
9276                if (intent.getSelector() != null) {
9277                    intent.setSelector(null);
9278                }
9279                if (intent.getSourceBounds() != null) {
9280                    intent.setSourceBounds(null);
9281                }
9282                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9283                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9284                        // The caller has added this as an auto-remove task...  that makes no
9285                        // sense, so turn off auto-remove.
9286                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9287                    }
9288                }
9289                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9290                    mLastAddedTaskActivity = null;
9291                }
9292                ActivityInfo ainfo = mLastAddedTaskActivity;
9293                if (ainfo == null) {
9294                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9295                            comp, 0, UserHandle.getUserId(callingUid));
9296                    if (ainfo.applicationInfo.uid != callingUid) {
9297                        throw new SecurityException(
9298                                "Can't add task for another application: target uid="
9299                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9300                    }
9301                }
9302
9303                // Use the full screen as the context for the task thumbnail
9304                final Point displaySize = new Point();
9305                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9306                r.task.stack.getDisplaySize(displaySize);
9307                thumbnailInfo.taskWidth = displaySize.x;
9308                thumbnailInfo.taskHeight = displaySize.y;
9309                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9310
9311                TaskRecord task = new TaskRecord(this,
9312                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9313                        ainfo, intent, description, thumbnailInfo);
9314
9315                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9316                if (trimIdx >= 0) {
9317                    // If this would have caused a trim, then we'll abort because that
9318                    // means it would be added at the end of the list but then just removed.
9319                    return INVALID_TASK_ID;
9320                }
9321
9322                final int N = mRecentTasks.size();
9323                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9324                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9325                    tr.removedFromRecents();
9326                }
9327
9328                task.inRecents = true;
9329                mRecentTasks.add(task);
9330                r.task.stack.addTask(task, false, "addAppTask");
9331
9332                task.setLastThumbnailLocked(thumbnail);
9333                task.freeLastThumbnail();
9334
9335                return task.taskId;
9336            }
9337        } finally {
9338            Binder.restoreCallingIdentity(callingIdent);
9339        }
9340    }
9341
9342    @Override
9343    public Point getAppTaskThumbnailSize() {
9344        synchronized (this) {
9345            return new Point(mThumbnailWidth,  mThumbnailHeight);
9346        }
9347    }
9348
9349    @Override
9350    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9351        synchronized (this) {
9352            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9353            if (r != null) {
9354                r.setTaskDescription(td);
9355                r.task.updateTaskDescription();
9356            }
9357        }
9358    }
9359
9360    @Override
9361    public void setTaskResizeable(int taskId, int resizeableMode) {
9362        synchronized (this) {
9363            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9364                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9365            if (task == null) {
9366                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9367                return;
9368            }
9369            if (task.mResizeMode != resizeableMode) {
9370                task.mResizeMode = resizeableMode;
9371                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9372                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9373                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9374            }
9375        }
9376    }
9377
9378    @Override
9379    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9380        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9381        long ident = Binder.clearCallingIdentity();
9382        try {
9383            synchronized (this) {
9384                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9385                if (task == null) {
9386                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9387                    return;
9388                }
9389                int stackId = task.stack.mStackId;
9390                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9391                // in crop windows resize mode or if the task size is affected by the docked stack
9392                // changing size. No need to update configuration.
9393                if (bounds != null && task.inCropWindowsResizeMode()
9394                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9395                    mWindowManager.scrollTask(task.taskId, bounds);
9396                    return;
9397                }
9398
9399                // Place the task in the right stack if it isn't there already based on
9400                // the requested bounds.
9401                // The stack transition logic is:
9402                // - a null bounds on a freeform task moves that task to fullscreen
9403                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9404                //   that task to freeform
9405                // - otherwise the task is not moved
9406                if (!StackId.isTaskResizeAllowed(stackId)) {
9407                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9408                }
9409                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9410                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9411                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9412                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9413                }
9414                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9415                if (stackId != task.stack.mStackId) {
9416                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9417                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9418                    preserveWindow = false;
9419                }
9420
9421                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9422                        false /* deferResume */);
9423            }
9424        } finally {
9425            Binder.restoreCallingIdentity(ident);
9426        }
9427    }
9428
9429    @Override
9430    public Rect getTaskBounds(int taskId) {
9431        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9432        long ident = Binder.clearCallingIdentity();
9433        Rect rect = new Rect();
9434        try {
9435            synchronized (this) {
9436                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9437                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9438                if (task == null) {
9439                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9440                    return rect;
9441                }
9442                if (task.stack != null) {
9443                    // Return the bounds from window manager since it will be adjusted for various
9444                    // things like the presense of a docked stack for tasks that aren't resizeable.
9445                    mWindowManager.getTaskBounds(task.taskId, rect);
9446                } else {
9447                    // Task isn't in window manager yet since it isn't associated with a stack.
9448                    // Return the persist value from activity manager
9449                    if (task.mBounds != null) {
9450                        rect.set(task.mBounds);
9451                    } else if (task.mLastNonFullscreenBounds != null) {
9452                        rect.set(task.mLastNonFullscreenBounds);
9453                    }
9454                }
9455            }
9456        } finally {
9457            Binder.restoreCallingIdentity(ident);
9458        }
9459        return rect;
9460    }
9461
9462    @Override
9463    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9464        if (userId != UserHandle.getCallingUserId()) {
9465            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9466                    "getTaskDescriptionIcon");
9467        }
9468        final File passedIconFile = new File(filePath);
9469        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9470                passedIconFile.getName());
9471        if (!legitIconFile.getPath().equals(filePath)
9472                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9473            throw new IllegalArgumentException("Bad file path: " + filePath
9474                    + " passed for userId " + userId);
9475        }
9476        return mRecentTasks.getTaskDescriptionIcon(filePath);
9477    }
9478
9479    @Override
9480    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9481            throws RemoteException {
9482        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9483                opts.getCustomInPlaceResId() == 0) {
9484            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9485                    "with valid animation");
9486        }
9487        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9488        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9489                opts.getCustomInPlaceResId());
9490        mWindowManager.executeAppTransition();
9491    }
9492
9493    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9494            boolean removeFromRecents) {
9495        if (removeFromRecents) {
9496            mRecentTasks.remove(tr);
9497            tr.removedFromRecents();
9498        }
9499        ComponentName component = tr.getBaseIntent().getComponent();
9500        if (component == null) {
9501            Slog.w(TAG, "No component for base intent of task: " + tr);
9502            return;
9503        }
9504
9505        // Find any running services associated with this app and stop if needed.
9506        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9507
9508        if (!killProcess) {
9509            return;
9510        }
9511
9512        // Determine if the process(es) for this task should be killed.
9513        final String pkg = component.getPackageName();
9514        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9515        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9516        for (int i = 0; i < pmap.size(); i++) {
9517
9518            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9519            for (int j = 0; j < uids.size(); j++) {
9520                ProcessRecord proc = uids.valueAt(j);
9521                if (proc.userId != tr.userId) {
9522                    // Don't kill process for a different user.
9523                    continue;
9524                }
9525                if (proc == mHomeProcess) {
9526                    // Don't kill the home process along with tasks from the same package.
9527                    continue;
9528                }
9529                if (!proc.pkgList.containsKey(pkg)) {
9530                    // Don't kill process that is not associated with this task.
9531                    continue;
9532                }
9533
9534                for (int k = 0; k < proc.activities.size(); k++) {
9535                    TaskRecord otherTask = proc.activities.get(k).task;
9536                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9537                        // Don't kill process(es) that has an activity in a different task that is
9538                        // also in recents.
9539                        return;
9540                    }
9541                }
9542
9543                if (proc.foregroundServices) {
9544                    // Don't kill process(es) with foreground service.
9545                    return;
9546                }
9547
9548                // Add process to kill list.
9549                procsToKill.add(proc);
9550            }
9551        }
9552
9553        // Kill the running processes.
9554        for (int i = 0; i < procsToKill.size(); i++) {
9555            ProcessRecord pr = procsToKill.get(i);
9556            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9557                    && pr.curReceiver == null) {
9558                pr.kill("remove task", true);
9559            } else {
9560                // We delay killing processes that are not in the background or running a receiver.
9561                pr.waitingToKill = "remove task";
9562            }
9563        }
9564    }
9565
9566    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9567        // Remove all tasks with activities in the specified package from the list of recent tasks
9568        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9569            TaskRecord tr = mRecentTasks.get(i);
9570            if (tr.userId != userId) continue;
9571
9572            ComponentName cn = tr.intent.getComponent();
9573            if (cn != null && cn.getPackageName().equals(packageName)) {
9574                // If the package name matches, remove the task.
9575                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9576            }
9577        }
9578    }
9579
9580    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9581            int userId) {
9582
9583        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9584            TaskRecord tr = mRecentTasks.get(i);
9585            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9586                continue;
9587            }
9588
9589            ComponentName cn = tr.intent.getComponent();
9590            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9591                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9592            if (sameComponent) {
9593                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9594            }
9595        }
9596    }
9597
9598    /**
9599     * Removes the task with the specified task id.
9600     *
9601     * @param taskId Identifier of the task to be removed.
9602     * @param killProcess Kill any process associated with the task if possible.
9603     * @param removeFromRecents Whether to also remove the task from recents.
9604     * @return Returns true if the given task was found and removed.
9605     */
9606    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9607            boolean removeFromRecents) {
9608        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9609                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9610        if (tr != null) {
9611            tr.removeTaskActivitiesLocked();
9612            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9613            if (tr.isPersistable) {
9614                notifyTaskPersisterLocked(null, true);
9615            }
9616            return true;
9617        }
9618        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9619        return false;
9620    }
9621
9622    @Override
9623    public void removeStack(int stackId) {
9624        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9625        if (stackId == HOME_STACK_ID) {
9626            throw new IllegalArgumentException("Removing home stack is not allowed.");
9627        }
9628
9629        synchronized (this) {
9630            final long ident = Binder.clearCallingIdentity();
9631            try {
9632                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9633                if (stack == null) {
9634                    return;
9635                }
9636                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9637                for (int i = tasks.size() - 1; i >= 0; i--) {
9638                    removeTaskByIdLocked(
9639                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9640                }
9641            } finally {
9642                Binder.restoreCallingIdentity(ident);
9643            }
9644        }
9645    }
9646
9647    @Override
9648    public boolean removeTask(int taskId) {
9649        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9650        synchronized (this) {
9651            final long ident = Binder.clearCallingIdentity();
9652            try {
9653                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9654            } finally {
9655                Binder.restoreCallingIdentity(ident);
9656            }
9657        }
9658    }
9659
9660    /**
9661     * TODO: Add mController hook
9662     */
9663    @Override
9664    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9665        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9666
9667        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9668        synchronized(this) {
9669            moveTaskToFrontLocked(taskId, flags, bOptions);
9670        }
9671    }
9672
9673    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9674        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9675
9676        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9677                Binder.getCallingUid(), -1, -1, "Task to front")) {
9678            ActivityOptions.abort(options);
9679            return;
9680        }
9681        final long origId = Binder.clearCallingIdentity();
9682        try {
9683            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9684            if (task == null) {
9685                Slog.d(TAG, "Could not find task for id: "+ taskId);
9686                return;
9687            }
9688            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9689                mStackSupervisor.showLockTaskToast();
9690                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9691                return;
9692            }
9693            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9694            if (prev != null && prev.isRecentsActivity()) {
9695                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9696            }
9697            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9698                    false /* forceNonResizable */);
9699        } finally {
9700            Binder.restoreCallingIdentity(origId);
9701        }
9702        ActivityOptions.abort(options);
9703    }
9704
9705    /**
9706     * Moves an activity, and all of the other activities within the same task, to the bottom
9707     * of the history stack.  The activity's order within the task is unchanged.
9708     *
9709     * @param token A reference to the activity we wish to move
9710     * @param nonRoot If false then this only works if the activity is the root
9711     *                of a task; if true it will work for any activity in a task.
9712     * @return Returns true if the move completed, false if not.
9713     */
9714    @Override
9715    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9716        enforceNotIsolatedCaller("moveActivityTaskToBack");
9717        synchronized(this) {
9718            final long origId = Binder.clearCallingIdentity();
9719            try {
9720                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9721                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9722                if (task != null) {
9723                    if (mStackSupervisor.isLockedTask(task)) {
9724                        mStackSupervisor.showLockTaskToast();
9725                        return false;
9726                    }
9727                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9728                }
9729            } finally {
9730                Binder.restoreCallingIdentity(origId);
9731            }
9732        }
9733        return false;
9734    }
9735
9736    @Override
9737    public void moveTaskBackwards(int task) {
9738        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9739                "moveTaskBackwards()");
9740
9741        synchronized(this) {
9742            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9743                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9744                return;
9745            }
9746            final long origId = Binder.clearCallingIdentity();
9747            moveTaskBackwardsLocked(task);
9748            Binder.restoreCallingIdentity(origId);
9749        }
9750    }
9751
9752    private final void moveTaskBackwardsLocked(int task) {
9753        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9754    }
9755
9756    @Override
9757    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9758            IActivityContainerCallback callback) throws RemoteException {
9759        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9760        synchronized (this) {
9761            if (parentActivityToken == null) {
9762                throw new IllegalArgumentException("parent token must not be null");
9763            }
9764            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9765            if (r == null) {
9766                return null;
9767            }
9768            if (callback == null) {
9769                throw new IllegalArgumentException("callback must not be null");
9770            }
9771            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9772        }
9773    }
9774
9775    @Override
9776    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9777        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9778        synchronized (this) {
9779            mStackSupervisor.deleteActivityContainer(container);
9780        }
9781    }
9782
9783    @Override
9784    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9785        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9786        synchronized (this) {
9787            final int stackId = mStackSupervisor.getNextStackId();
9788            final ActivityStack stack =
9789                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9790            if (stack == null) {
9791                return null;
9792            }
9793            return stack.mActivityContainer;
9794        }
9795    }
9796
9797    @Override
9798    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9799        synchronized (this) {
9800            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9801            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9802                return stack.mActivityContainer.getDisplayId();
9803            }
9804            return Display.DEFAULT_DISPLAY;
9805        }
9806    }
9807
9808    @Override
9809    public int getActivityStackId(IBinder token) throws RemoteException {
9810        synchronized (this) {
9811            ActivityStack stack = ActivityRecord.getStackLocked(token);
9812            if (stack == null) {
9813                return INVALID_STACK_ID;
9814            }
9815            return stack.mStackId;
9816        }
9817    }
9818
9819    @Override
9820    public void exitFreeformMode(IBinder token) throws RemoteException {
9821        synchronized (this) {
9822            long ident = Binder.clearCallingIdentity();
9823            try {
9824                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9825                if (r == null) {
9826                    throw new IllegalArgumentException(
9827                            "exitFreeformMode: No activity record matching token=" + token);
9828                }
9829                final ActivityStack stack = r.getStackLocked(token);
9830                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9831                    throw new IllegalStateException(
9832                            "exitFreeformMode: You can only go fullscreen from freeform.");
9833                }
9834                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9835                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9836                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9837            } finally {
9838                Binder.restoreCallingIdentity(ident);
9839            }
9840        }
9841    }
9842
9843    @Override
9844    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9845        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9846        if (stackId == HOME_STACK_ID) {
9847            throw new IllegalArgumentException(
9848                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9849        }
9850        synchronized (this) {
9851            long ident = Binder.clearCallingIdentity();
9852            try {
9853                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9854                        + " to stackId=" + stackId + " toTop=" + toTop);
9855                if (stackId == DOCKED_STACK_ID) {
9856                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9857                            null /* initialBounds */);
9858                }
9859                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9860                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9861                if (result && stackId == DOCKED_STACK_ID) {
9862                    // If task moved to docked stack - show recents if needed.
9863                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9864                            "moveTaskToDockedStack");
9865                }
9866            } finally {
9867                Binder.restoreCallingIdentity(ident);
9868            }
9869        }
9870    }
9871
9872    @Override
9873    public void swapDockedAndFullscreenStack() throws RemoteException {
9874        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9875        synchronized (this) {
9876            long ident = Binder.clearCallingIdentity();
9877            try {
9878                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9879                        FULLSCREEN_WORKSPACE_STACK_ID);
9880                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9881                        : null;
9882                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9883                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9884                        : null;
9885                if (topTask == null || tasks == null || tasks.size() == 0) {
9886                    Slog.w(TAG,
9887                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9888                    return;
9889                }
9890
9891                // TODO: App transition
9892                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9893
9894                // Defer the resume so resume/pausing while moving stacks is dangerous.
9895                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9896                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9897                        ANIMATE, true /* deferResume */);
9898                final int size = tasks.size();
9899                for (int i = 0; i < size; i++) {
9900                    final int id = tasks.get(i).taskId;
9901                    if (id == topTask.taskId) {
9902                        continue;
9903                    }
9904                    mStackSupervisor.moveTaskToStackLocked(id,
9905                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9906                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9907                }
9908
9909                // Because we deferred the resume, to avoid conflicts with stack switches while
9910                // resuming, we need to do it after all the tasks are moved.
9911                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9912                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9913
9914                mWindowManager.executeAppTransition();
9915            } finally {
9916                Binder.restoreCallingIdentity(ident);
9917            }
9918        }
9919    }
9920
9921    /**
9922     * Moves the input task to the docked stack.
9923     *
9924     * @param taskId Id of task to move.
9925     * @param createMode The mode the docked stack should be created in if it doesn't exist
9926     *                   already. See
9927     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9928     *                   and
9929     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9930     * @param toTop If the task and stack should be moved to the top.
9931     * @param animate Whether we should play an animation for the moving the task
9932     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9933     *                      docked stack. Pass {@code null} to use default bounds.
9934     */
9935    @Override
9936    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9937            Rect initialBounds, boolean moveHomeStackFront) {
9938        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9939        synchronized (this) {
9940            long ident = Binder.clearCallingIdentity();
9941            try {
9942                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9943                        + " to createMode=" + createMode + " toTop=" + toTop);
9944                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9945                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9946                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9947                        animate, DEFER_RESUME);
9948                if (moved) {
9949                    if (moveHomeStackFront) {
9950                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9951                    }
9952                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9953                }
9954                return moved;
9955            } finally {
9956                Binder.restoreCallingIdentity(ident);
9957            }
9958        }
9959    }
9960
9961    /**
9962     * Moves the top activity in the input stackId to the pinned stack.
9963     *
9964     * @param stackId Id of stack to move the top activity to pinned stack.
9965     * @param bounds Bounds to use for pinned stack.
9966     *
9967     * @return True if the top activity of the input stack was successfully moved to the pinned
9968     *          stack.
9969     */
9970    @Override
9971    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9972        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9973        synchronized (this) {
9974            if (!mSupportsPictureInPicture) {
9975                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9976                        + "Device doesn't support picture-in-pciture mode");
9977            }
9978
9979            long ident = Binder.clearCallingIdentity();
9980            try {
9981                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9982            } finally {
9983                Binder.restoreCallingIdentity(ident);
9984            }
9985        }
9986    }
9987
9988    @Override
9989    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9990            boolean preserveWindows, boolean animate, int animationDuration) {
9991        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9992        long ident = Binder.clearCallingIdentity();
9993        try {
9994            synchronized (this) {
9995                if (animate) {
9996                    if (stackId == PINNED_STACK_ID) {
9997                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9998                    } else {
9999                        throw new IllegalArgumentException("Stack: " + stackId
10000                                + " doesn't support animated resize.");
10001                    }
10002                } else {
10003                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10004                            null /* tempTaskInsetBounds */, preserveWindows,
10005                            allowResizeInDockedMode, !DEFER_RESUME);
10006                }
10007            }
10008        } finally {
10009            Binder.restoreCallingIdentity(ident);
10010        }
10011    }
10012
10013    @Override
10014    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10015            Rect tempDockedTaskInsetBounds,
10016            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10017        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10018                "resizeDockedStack()");
10019        long ident = Binder.clearCallingIdentity();
10020        try {
10021            synchronized (this) {
10022                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10023                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10024                        PRESERVE_WINDOWS);
10025            }
10026        } finally {
10027            Binder.restoreCallingIdentity(ident);
10028        }
10029    }
10030
10031    @Override
10032    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10033        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10034                "resizePinnedStack()");
10035        final long ident = Binder.clearCallingIdentity();
10036        try {
10037            synchronized (this) {
10038                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10039            }
10040        } finally {
10041            Binder.restoreCallingIdentity(ident);
10042        }
10043    }
10044
10045    @Override
10046    public void positionTaskInStack(int taskId, int stackId, int position) {
10047        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10048        if (stackId == HOME_STACK_ID) {
10049            throw new IllegalArgumentException(
10050                    "positionTaskInStack: Attempt to change the position of task "
10051                    + taskId + " in/to home stack");
10052        }
10053        synchronized (this) {
10054            long ident = Binder.clearCallingIdentity();
10055            try {
10056                if (DEBUG_STACK) Slog.d(TAG_STACK,
10057                        "positionTaskInStack: positioning task=" + taskId
10058                        + " in stackId=" + stackId + " at position=" + position);
10059                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10060            } finally {
10061                Binder.restoreCallingIdentity(ident);
10062            }
10063        }
10064    }
10065
10066    @Override
10067    public List<StackInfo> getAllStackInfos() {
10068        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10069        long ident = Binder.clearCallingIdentity();
10070        try {
10071            synchronized (this) {
10072                return mStackSupervisor.getAllStackInfosLocked();
10073            }
10074        } finally {
10075            Binder.restoreCallingIdentity(ident);
10076        }
10077    }
10078
10079    @Override
10080    public StackInfo getStackInfo(int stackId) {
10081        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10082        long ident = Binder.clearCallingIdentity();
10083        try {
10084            synchronized (this) {
10085                return mStackSupervisor.getStackInfoLocked(stackId);
10086            }
10087        } finally {
10088            Binder.restoreCallingIdentity(ident);
10089        }
10090    }
10091
10092    @Override
10093    public boolean isInHomeStack(int taskId) {
10094        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10095        long ident = Binder.clearCallingIdentity();
10096        try {
10097            synchronized (this) {
10098                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10099                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10100                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10101            }
10102        } finally {
10103            Binder.restoreCallingIdentity(ident);
10104        }
10105    }
10106
10107    @Override
10108    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10109        synchronized(this) {
10110            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10111        }
10112    }
10113
10114    @Override
10115    public void updateDeviceOwner(String packageName) {
10116        final int callingUid = Binder.getCallingUid();
10117        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10118            throw new SecurityException("updateDeviceOwner called from non-system process");
10119        }
10120        synchronized (this) {
10121            mDeviceOwnerName = packageName;
10122        }
10123    }
10124
10125    @Override
10126    public void updateLockTaskPackages(int userId, String[] packages) {
10127        final int callingUid = Binder.getCallingUid();
10128        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10129            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10130                    "updateLockTaskPackages()");
10131        }
10132        synchronized (this) {
10133            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10134                    Arrays.toString(packages));
10135            mLockTaskPackages.put(userId, packages);
10136            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10137        }
10138    }
10139
10140
10141    void startLockTaskModeLocked(TaskRecord task) {
10142        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10143        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10144            return;
10145        }
10146
10147        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10148        // is initiated by system after the pinning request was shown and locked mode is initiated
10149        // by an authorized app directly
10150        final int callingUid = Binder.getCallingUid();
10151        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10152        long ident = Binder.clearCallingIdentity();
10153        try {
10154            if (!isSystemInitiated) {
10155                task.mLockTaskUid = callingUid;
10156                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10157                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10158                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10159                    StatusBarManagerInternal statusBarManager =
10160                            LocalServices.getService(StatusBarManagerInternal.class);
10161                    if (statusBarManager != null) {
10162                        statusBarManager.showScreenPinningRequest(task.taskId);
10163                    }
10164                    return;
10165                }
10166
10167                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10168                if (stack == null || task != stack.topTask()) {
10169                    throw new IllegalArgumentException("Invalid task, not in foreground");
10170                }
10171            }
10172            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10173                    "Locking fully");
10174            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10175                    ActivityManager.LOCK_TASK_MODE_PINNED :
10176                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10177                    "startLockTask", true);
10178        } finally {
10179            Binder.restoreCallingIdentity(ident);
10180        }
10181    }
10182
10183    @Override
10184    public void startLockTaskMode(int taskId) {
10185        synchronized (this) {
10186            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10187            if (task != null) {
10188                startLockTaskModeLocked(task);
10189            }
10190        }
10191    }
10192
10193    @Override
10194    public void startLockTaskMode(IBinder token) {
10195        synchronized (this) {
10196            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10197            if (r == null) {
10198                return;
10199            }
10200            final TaskRecord task = r.task;
10201            if (task != null) {
10202                startLockTaskModeLocked(task);
10203            }
10204        }
10205    }
10206
10207    @Override
10208    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10209        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10210        // This makes inner call to look as if it was initiated by system.
10211        long ident = Binder.clearCallingIdentity();
10212        try {
10213            synchronized (this) {
10214                startLockTaskMode(taskId);
10215            }
10216        } finally {
10217            Binder.restoreCallingIdentity(ident);
10218        }
10219    }
10220
10221    @Override
10222    public void stopLockTaskMode() {
10223        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10224        if (lockTask == null) {
10225            // Our work here is done.
10226            return;
10227        }
10228
10229        final int callingUid = Binder.getCallingUid();
10230        final int lockTaskUid = lockTask.mLockTaskUid;
10231        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10232        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10233            // Done.
10234            return;
10235        } else {
10236            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10237            // It is possible lockTaskMode was started by the system process because
10238            // android:lockTaskMode is set to a locking value in the application manifest
10239            // instead of the app calling startLockTaskMode. In this case
10240            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10241            // {@link TaskRecord.effectiveUid} instead. Also caller with
10242            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10243            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10244                    && callingUid != lockTaskUid
10245                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10246                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10247                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10248            }
10249        }
10250        long ident = Binder.clearCallingIdentity();
10251        try {
10252            Log.d(TAG, "stopLockTaskMode");
10253            // Stop lock task
10254            synchronized (this) {
10255                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10256                        "stopLockTask", true);
10257            }
10258            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10259            if (tm != null) {
10260                tm.showInCallScreen(false);
10261            }
10262        } finally {
10263            Binder.restoreCallingIdentity(ident);
10264        }
10265    }
10266
10267    /**
10268     * This API should be called by SystemUI only when user perform certain action to dismiss
10269     * lock task mode. We should only dismiss pinned lock task mode in this case.
10270     */
10271    @Override
10272    public void stopSystemLockTaskMode() throws RemoteException {
10273        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10274            stopLockTaskMode();
10275        } else {
10276            mStackSupervisor.showLockTaskToast();
10277        }
10278    }
10279
10280    @Override
10281    public boolean isInLockTaskMode() {
10282        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10283    }
10284
10285    @Override
10286    public int getLockTaskModeState() {
10287        synchronized (this) {
10288            return mStackSupervisor.getLockTaskModeState();
10289        }
10290    }
10291
10292    @Override
10293    public void showLockTaskEscapeMessage(IBinder token) {
10294        synchronized (this) {
10295            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10296            if (r == null) {
10297                return;
10298            }
10299            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10300        }
10301    }
10302
10303    // =========================================================
10304    // CONTENT PROVIDERS
10305    // =========================================================
10306
10307    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10308        List<ProviderInfo> providers = null;
10309        try {
10310            providers = AppGlobals.getPackageManager()
10311                    .queryContentProviders(app.processName, app.uid,
10312                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10313                                    | MATCH_DEBUG_TRIAGED_MISSING)
10314                    .getList();
10315        } catch (RemoteException ex) {
10316        }
10317        if (DEBUG_MU) Slog.v(TAG_MU,
10318                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10319        int userId = app.userId;
10320        if (providers != null) {
10321            int N = providers.size();
10322            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10323            for (int i=0; i<N; i++) {
10324                // TODO: keep logic in sync with installEncryptionUnawareProviders
10325                ProviderInfo cpi =
10326                    (ProviderInfo)providers.get(i);
10327                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10328                        cpi.name, cpi.flags);
10329                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10330                    // This is a singleton provider, but a user besides the
10331                    // default user is asking to initialize a process it runs
10332                    // in...  well, no, it doesn't actually run in this process,
10333                    // it runs in the process of the default user.  Get rid of it.
10334                    providers.remove(i);
10335                    N--;
10336                    i--;
10337                    continue;
10338                }
10339
10340                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10341                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10342                if (cpr == null) {
10343                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10344                    mProviderMap.putProviderByClass(comp, cpr);
10345                }
10346                if (DEBUG_MU) Slog.v(TAG_MU,
10347                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10348                app.pubProviders.put(cpi.name, cpr);
10349                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10350                    // Don't add this if it is a platform component that is marked
10351                    // to run in multiple processes, because this is actually
10352                    // part of the framework so doesn't make sense to track as a
10353                    // separate apk in the process.
10354                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10355                            mProcessStats);
10356                }
10357                notifyPackageUse(cpi.applicationInfo.packageName,
10358                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10359            }
10360        }
10361        return providers;
10362    }
10363
10364    /**
10365     * Check if {@link ProcessRecord} has a possible chance at accessing the
10366     * given {@link ProviderInfo}. Final permission checking is always done
10367     * in {@link ContentProvider}.
10368     */
10369    private final String checkContentProviderPermissionLocked(
10370            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10371        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10372        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10373        boolean checkedGrants = false;
10374        if (checkUser) {
10375            // Looking for cross-user grants before enforcing the typical cross-users permissions
10376            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10377            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10378                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10379                    return null;
10380                }
10381                checkedGrants = true;
10382            }
10383            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10384                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10385            if (userId != tmpTargetUserId) {
10386                // When we actually went to determine the final targer user ID, this ended
10387                // up different than our initial check for the authority.  This is because
10388                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10389                // SELF.  So we need to re-check the grants again.
10390                checkedGrants = false;
10391            }
10392        }
10393        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10394                cpi.applicationInfo.uid, cpi.exported)
10395                == PackageManager.PERMISSION_GRANTED) {
10396            return null;
10397        }
10398        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10399                cpi.applicationInfo.uid, cpi.exported)
10400                == PackageManager.PERMISSION_GRANTED) {
10401            return null;
10402        }
10403
10404        PathPermission[] pps = cpi.pathPermissions;
10405        if (pps != null) {
10406            int i = pps.length;
10407            while (i > 0) {
10408                i--;
10409                PathPermission pp = pps[i];
10410                String pprperm = pp.getReadPermission();
10411                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10412                        cpi.applicationInfo.uid, cpi.exported)
10413                        == PackageManager.PERMISSION_GRANTED) {
10414                    return null;
10415                }
10416                String ppwperm = pp.getWritePermission();
10417                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10418                        cpi.applicationInfo.uid, cpi.exported)
10419                        == PackageManager.PERMISSION_GRANTED) {
10420                    return null;
10421                }
10422            }
10423        }
10424        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10425            return null;
10426        }
10427
10428        String msg;
10429        if (!cpi.exported) {
10430            msg = "Permission Denial: opening provider " + cpi.name
10431                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10432                    + ", uid=" + callingUid + ") that is not exported from uid "
10433                    + cpi.applicationInfo.uid;
10434        } else {
10435            msg = "Permission Denial: opening provider " + cpi.name
10436                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10437                    + ", uid=" + callingUid + ") requires "
10438                    + cpi.readPermission + " or " + cpi.writePermission;
10439        }
10440        Slog.w(TAG, msg);
10441        return msg;
10442    }
10443
10444    /**
10445     * Returns if the ContentProvider has granted a uri to callingUid
10446     */
10447    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10448        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10449        if (perms != null) {
10450            for (int i=perms.size()-1; i>=0; i--) {
10451                GrantUri grantUri = perms.keyAt(i);
10452                if (grantUri.sourceUserId == userId || !checkUser) {
10453                    if (matchesProvider(grantUri.uri, cpi)) {
10454                        return true;
10455                    }
10456                }
10457            }
10458        }
10459        return false;
10460    }
10461
10462    /**
10463     * Returns true if the uri authority is one of the authorities specified in the provider.
10464     */
10465    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10466        String uriAuth = uri.getAuthority();
10467        String cpiAuth = cpi.authority;
10468        if (cpiAuth.indexOf(';') == -1) {
10469            return cpiAuth.equals(uriAuth);
10470        }
10471        String[] cpiAuths = cpiAuth.split(";");
10472        int length = cpiAuths.length;
10473        for (int i = 0; i < length; i++) {
10474            if (cpiAuths[i].equals(uriAuth)) return true;
10475        }
10476        return false;
10477    }
10478
10479    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10480            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10481        if (r != null) {
10482            for (int i=0; i<r.conProviders.size(); i++) {
10483                ContentProviderConnection conn = r.conProviders.get(i);
10484                if (conn.provider == cpr) {
10485                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10486                            "Adding provider requested by "
10487                            + r.processName + " from process "
10488                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10489                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10490                    if (stable) {
10491                        conn.stableCount++;
10492                        conn.numStableIncs++;
10493                    } else {
10494                        conn.unstableCount++;
10495                        conn.numUnstableIncs++;
10496                    }
10497                    return conn;
10498                }
10499            }
10500            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10501            if (stable) {
10502                conn.stableCount = 1;
10503                conn.numStableIncs = 1;
10504            } else {
10505                conn.unstableCount = 1;
10506                conn.numUnstableIncs = 1;
10507            }
10508            cpr.connections.add(conn);
10509            r.conProviders.add(conn);
10510            startAssociationLocked(r.uid, r.processName, r.curProcState,
10511                    cpr.uid, cpr.name, cpr.info.processName);
10512            return conn;
10513        }
10514        cpr.addExternalProcessHandleLocked(externalProcessToken);
10515        return null;
10516    }
10517
10518    boolean decProviderCountLocked(ContentProviderConnection conn,
10519            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10520        if (conn != null) {
10521            cpr = conn.provider;
10522            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10523                    "Removing provider requested by "
10524                    + conn.client.processName + " from process "
10525                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10526                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10527            if (stable) {
10528                conn.stableCount--;
10529            } else {
10530                conn.unstableCount--;
10531            }
10532            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10533                cpr.connections.remove(conn);
10534                conn.client.conProviders.remove(conn);
10535                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10536                    // The client is more important than last activity -- note the time this
10537                    // is happening, so we keep the old provider process around a bit as last
10538                    // activity to avoid thrashing it.
10539                    if (cpr.proc != null) {
10540                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10541                    }
10542                }
10543                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10544                return true;
10545            }
10546            return false;
10547        }
10548        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10549        return false;
10550    }
10551
10552    private void checkTime(long startTime, String where) {
10553        long now = SystemClock.uptimeMillis();
10554        if ((now-startTime) > 50) {
10555            // If we are taking more than 50ms, log about it.
10556            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10557        }
10558    }
10559
10560    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10561            PROC_SPACE_TERM,
10562            PROC_SPACE_TERM|PROC_PARENS,
10563            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10564    };
10565
10566    private final long[] mProcessStateStatsLongs = new long[1];
10567
10568    boolean isProcessAliveLocked(ProcessRecord proc) {
10569        if (proc.procStatFile == null) {
10570            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10571        }
10572        mProcessStateStatsLongs[0] = 0;
10573        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10574                mProcessStateStatsLongs, null)) {
10575            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10576            return false;
10577        }
10578        final long state = mProcessStateStatsLongs[0];
10579        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10580                + (char)state);
10581        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10582    }
10583
10584    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10585            String name, IBinder token, boolean stable, int userId) {
10586        ContentProviderRecord cpr;
10587        ContentProviderConnection conn = null;
10588        ProviderInfo cpi = null;
10589
10590        synchronized(this) {
10591            long startTime = SystemClock.uptimeMillis();
10592
10593            ProcessRecord r = null;
10594            if (caller != null) {
10595                r = getRecordForAppLocked(caller);
10596                if (r == null) {
10597                    throw new SecurityException(
10598                            "Unable to find app for caller " + caller
10599                          + " (pid=" + Binder.getCallingPid()
10600                          + ") when getting content provider " + name);
10601                }
10602            }
10603
10604            boolean checkCrossUser = true;
10605
10606            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10607
10608            // First check if this content provider has been published...
10609            cpr = mProviderMap.getProviderByName(name, userId);
10610            // If that didn't work, check if it exists for user 0 and then
10611            // verify that it's a singleton provider before using it.
10612            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10613                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10614                if (cpr != null) {
10615                    cpi = cpr.info;
10616                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10617                            cpi.name, cpi.flags)
10618                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10619                        userId = UserHandle.USER_SYSTEM;
10620                        checkCrossUser = false;
10621                    } else {
10622                        cpr = null;
10623                        cpi = null;
10624                    }
10625                }
10626            }
10627
10628            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10629            if (providerRunning) {
10630                cpi = cpr.info;
10631                String msg;
10632                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10633                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10634                        != null) {
10635                    throw new SecurityException(msg);
10636                }
10637                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10638
10639                if (r != null && cpr.canRunHere(r)) {
10640                    // This provider has been published or is in the process
10641                    // of being published...  but it is also allowed to run
10642                    // in the caller's process, so don't make a connection
10643                    // and just let the caller instantiate its own instance.
10644                    ContentProviderHolder holder = cpr.newHolder(null);
10645                    // don't give caller the provider object, it needs
10646                    // to make its own.
10647                    holder.provider = null;
10648                    return holder;
10649                }
10650
10651                final long origId = Binder.clearCallingIdentity();
10652
10653                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10654
10655                // In this case the provider instance already exists, so we can
10656                // return it right away.
10657                conn = incProviderCountLocked(r, cpr, token, stable);
10658                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10659                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10660                        // If this is a perceptible app accessing the provider,
10661                        // make sure to count it as being accessed and thus
10662                        // back up on the LRU list.  This is good because
10663                        // content providers are often expensive to start.
10664                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10665                        updateLruProcessLocked(cpr.proc, false, null);
10666                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10667                    }
10668                }
10669
10670                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10671                final int verifiedAdj = cpr.proc.verifiedAdj;
10672                boolean success = updateOomAdjLocked(cpr.proc);
10673                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10674                // if the process has been successfully adjusted.  So to reduce races with
10675                // it, we will check whether the process still exists.  Note that this doesn't
10676                // completely get rid of races with LMK killing the process, but should make
10677                // them much smaller.
10678                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10679                    success = false;
10680                }
10681                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10682                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10683                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10684                // NOTE: there is still a race here where a signal could be
10685                // pending on the process even though we managed to update its
10686                // adj level.  Not sure what to do about this, but at least
10687                // the race is now smaller.
10688                if (!success) {
10689                    // Uh oh...  it looks like the provider's process
10690                    // has been killed on us.  We need to wait for a new
10691                    // process to be started, and make sure its death
10692                    // doesn't kill our process.
10693                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10694                            + " is crashing; detaching " + r);
10695                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10696                    checkTime(startTime, "getContentProviderImpl: before appDied");
10697                    appDiedLocked(cpr.proc);
10698                    checkTime(startTime, "getContentProviderImpl: after appDied");
10699                    if (!lastRef) {
10700                        // This wasn't the last ref our process had on
10701                        // the provider...  we have now been killed, bail.
10702                        return null;
10703                    }
10704                    providerRunning = false;
10705                    conn = null;
10706                } else {
10707                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10708                }
10709
10710                Binder.restoreCallingIdentity(origId);
10711            }
10712
10713            if (!providerRunning) {
10714                try {
10715                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10716                    cpi = AppGlobals.getPackageManager().
10717                        resolveContentProvider(name,
10718                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10719                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10720                } catch (RemoteException ex) {
10721                }
10722                if (cpi == null) {
10723                    return null;
10724                }
10725                // If the provider is a singleton AND
10726                // (it's a call within the same user || the provider is a
10727                // privileged app)
10728                // Then allow connecting to the singleton provider
10729                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10730                        cpi.name, cpi.flags)
10731                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10732                if (singleton) {
10733                    userId = UserHandle.USER_SYSTEM;
10734                }
10735                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10736                checkTime(startTime, "getContentProviderImpl: got app info for user");
10737
10738                String msg;
10739                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10740                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10741                        != null) {
10742                    throw new SecurityException(msg);
10743                }
10744                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10745
10746                if (!mProcessesReady
10747                        && !cpi.processName.equals("system")) {
10748                    // If this content provider does not run in the system
10749                    // process, and the system is not yet ready to run other
10750                    // processes, then fail fast instead of hanging.
10751                    throw new IllegalArgumentException(
10752                            "Attempt to launch content provider before system ready");
10753                }
10754
10755                // Make sure that the user who owns this provider is running.  If not,
10756                // we don't want to allow it to run.
10757                if (!mUserController.isUserRunningLocked(userId, 0)) {
10758                    Slog.w(TAG, "Unable to launch app "
10759                            + cpi.applicationInfo.packageName + "/"
10760                            + cpi.applicationInfo.uid + " for provider "
10761                            + name + ": user " + userId + " is stopped");
10762                    return null;
10763                }
10764
10765                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10766                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10767                cpr = mProviderMap.getProviderByClass(comp, userId);
10768                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10769                final boolean firstClass = cpr == null;
10770                if (firstClass) {
10771                    final long ident = Binder.clearCallingIdentity();
10772
10773                    // If permissions need a review before any of the app components can run,
10774                    // we return no provider and launch a review activity if the calling app
10775                    // is in the foreground.
10776                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10777                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10778                            return null;
10779                        }
10780                    }
10781
10782                    try {
10783                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10784                        ApplicationInfo ai =
10785                            AppGlobals.getPackageManager().
10786                                getApplicationInfo(
10787                                        cpi.applicationInfo.packageName,
10788                                        STOCK_PM_FLAGS, userId);
10789                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10790                        if (ai == null) {
10791                            Slog.w(TAG, "No package info for content provider "
10792                                    + cpi.name);
10793                            return null;
10794                        }
10795                        ai = getAppInfoForUser(ai, userId);
10796                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10797                    } catch (RemoteException ex) {
10798                        // pm is in same process, this will never happen.
10799                    } finally {
10800                        Binder.restoreCallingIdentity(ident);
10801                    }
10802                }
10803
10804                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10805
10806                if (r != null && cpr.canRunHere(r)) {
10807                    // If this is a multiprocess provider, then just return its
10808                    // info and allow the caller to instantiate it.  Only do
10809                    // this if the provider is the same user as the caller's
10810                    // process, or can run as root (so can be in any process).
10811                    return cpr.newHolder(null);
10812                }
10813
10814                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10815                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10816                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10817
10818                // This is single process, and our app is now connecting to it.
10819                // See if we are already in the process of launching this
10820                // provider.
10821                final int N = mLaunchingProviders.size();
10822                int i;
10823                for (i = 0; i < N; i++) {
10824                    if (mLaunchingProviders.get(i) == cpr) {
10825                        break;
10826                    }
10827                }
10828
10829                // If the provider is not already being launched, then get it
10830                // started.
10831                if (i >= N) {
10832                    final long origId = Binder.clearCallingIdentity();
10833
10834                    try {
10835                        // Content provider is now in use, its package can't be stopped.
10836                        try {
10837                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10838                            AppGlobals.getPackageManager().setPackageStoppedState(
10839                                    cpr.appInfo.packageName, false, userId);
10840                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10841                        } catch (RemoteException e) {
10842                        } catch (IllegalArgumentException e) {
10843                            Slog.w(TAG, "Failed trying to unstop package "
10844                                    + cpr.appInfo.packageName + ": " + e);
10845                        }
10846
10847                        // Use existing process if already started
10848                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10849                        ProcessRecord proc = getProcessRecordLocked(
10850                                cpi.processName, cpr.appInfo.uid, false);
10851                        if (proc != null && proc.thread != null && !proc.killed) {
10852                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10853                                    "Installing in existing process " + proc);
10854                            if (!proc.pubProviders.containsKey(cpi.name)) {
10855                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10856                                proc.pubProviders.put(cpi.name, cpr);
10857                                try {
10858                                    proc.thread.scheduleInstallProvider(cpi);
10859                                } catch (RemoteException e) {
10860                                }
10861                            }
10862                        } else {
10863                            checkTime(startTime, "getContentProviderImpl: before start process");
10864                            proc = startProcessLocked(cpi.processName,
10865                                    cpr.appInfo, false, 0, "content provider",
10866                                    new ComponentName(cpi.applicationInfo.packageName,
10867                                            cpi.name), false, false, false);
10868                            checkTime(startTime, "getContentProviderImpl: after start process");
10869                            if (proc == null) {
10870                                Slog.w(TAG, "Unable to launch app "
10871                                        + cpi.applicationInfo.packageName + "/"
10872                                        + cpi.applicationInfo.uid + " for provider "
10873                                        + name + ": process is bad");
10874                                return null;
10875                            }
10876                        }
10877                        cpr.launchingApp = proc;
10878                        mLaunchingProviders.add(cpr);
10879                    } finally {
10880                        Binder.restoreCallingIdentity(origId);
10881                    }
10882                }
10883
10884                checkTime(startTime, "getContentProviderImpl: updating data structures");
10885
10886                // Make sure the provider is published (the same provider class
10887                // may be published under multiple names).
10888                if (firstClass) {
10889                    mProviderMap.putProviderByClass(comp, cpr);
10890                }
10891
10892                mProviderMap.putProviderByName(name, cpr);
10893                conn = incProviderCountLocked(r, cpr, token, stable);
10894                if (conn != null) {
10895                    conn.waiting = true;
10896                }
10897            }
10898            checkTime(startTime, "getContentProviderImpl: done!");
10899        }
10900
10901        // Wait for the provider to be published...
10902        synchronized (cpr) {
10903            while (cpr.provider == null) {
10904                if (cpr.launchingApp == null) {
10905                    Slog.w(TAG, "Unable to launch app "
10906                            + cpi.applicationInfo.packageName + "/"
10907                            + cpi.applicationInfo.uid + " for provider "
10908                            + name + ": launching app became null");
10909                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10910                            UserHandle.getUserId(cpi.applicationInfo.uid),
10911                            cpi.applicationInfo.packageName,
10912                            cpi.applicationInfo.uid, name);
10913                    return null;
10914                }
10915                try {
10916                    if (DEBUG_MU) Slog.v(TAG_MU,
10917                            "Waiting to start provider " + cpr
10918                            + " launchingApp=" + cpr.launchingApp);
10919                    if (conn != null) {
10920                        conn.waiting = true;
10921                    }
10922                    cpr.wait();
10923                } catch (InterruptedException ex) {
10924                } finally {
10925                    if (conn != null) {
10926                        conn.waiting = false;
10927                    }
10928                }
10929            }
10930        }
10931        return cpr != null ? cpr.newHolder(conn) : null;
10932    }
10933
10934    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10935            ProcessRecord r, final int userId) {
10936        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10937                cpi.packageName, userId)) {
10938
10939            final boolean callerForeground = r == null || r.setSchedGroup
10940                    != ProcessList.SCHED_GROUP_BACKGROUND;
10941
10942            // Show a permission review UI only for starting from a foreground app
10943            if (!callerForeground) {
10944                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10945                        + cpi.packageName + " requires a permissions review");
10946                return false;
10947            }
10948
10949            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10950            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10951                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10952            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10953
10954            if (DEBUG_PERMISSIONS_REVIEW) {
10955                Slog.i(TAG, "u" + userId + " Launching permission review "
10956                        + "for package " + cpi.packageName);
10957            }
10958
10959            final UserHandle userHandle = new UserHandle(userId);
10960            mHandler.post(new Runnable() {
10961                @Override
10962                public void run() {
10963                    mContext.startActivityAsUser(intent, userHandle);
10964                }
10965            });
10966
10967            return false;
10968        }
10969
10970        return true;
10971    }
10972
10973    PackageManagerInternal getPackageManagerInternalLocked() {
10974        if (mPackageManagerInt == null) {
10975            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10976        }
10977        return mPackageManagerInt;
10978    }
10979
10980    @Override
10981    public final ContentProviderHolder getContentProvider(
10982            IApplicationThread caller, String name, int userId, boolean stable) {
10983        enforceNotIsolatedCaller("getContentProvider");
10984        if (caller == null) {
10985            String msg = "null IApplicationThread when getting content provider "
10986                    + name;
10987            Slog.w(TAG, msg);
10988            throw new SecurityException(msg);
10989        }
10990        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10991        // with cross-user grant.
10992        return getContentProviderImpl(caller, name, null, stable, userId);
10993    }
10994
10995    public ContentProviderHolder getContentProviderExternal(
10996            String name, int userId, IBinder token) {
10997        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10998            "Do not have permission in call getContentProviderExternal()");
10999        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11000                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11001        return getContentProviderExternalUnchecked(name, token, userId);
11002    }
11003
11004    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11005            IBinder token, int userId) {
11006        return getContentProviderImpl(null, name, token, true, userId);
11007    }
11008
11009    /**
11010     * Drop a content provider from a ProcessRecord's bookkeeping
11011     */
11012    public void removeContentProvider(IBinder connection, boolean stable) {
11013        enforceNotIsolatedCaller("removeContentProvider");
11014        long ident = Binder.clearCallingIdentity();
11015        try {
11016            synchronized (this) {
11017                ContentProviderConnection conn;
11018                try {
11019                    conn = (ContentProviderConnection)connection;
11020                } catch (ClassCastException e) {
11021                    String msg ="removeContentProvider: " + connection
11022                            + " not a ContentProviderConnection";
11023                    Slog.w(TAG, msg);
11024                    throw new IllegalArgumentException(msg);
11025                }
11026                if (conn == null) {
11027                    throw new NullPointerException("connection is null");
11028                }
11029                if (decProviderCountLocked(conn, null, null, stable)) {
11030                    updateOomAdjLocked();
11031                }
11032            }
11033        } finally {
11034            Binder.restoreCallingIdentity(ident);
11035        }
11036    }
11037
11038    public void removeContentProviderExternal(String name, IBinder token) {
11039        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11040            "Do not have permission in call removeContentProviderExternal()");
11041        int userId = UserHandle.getCallingUserId();
11042        long ident = Binder.clearCallingIdentity();
11043        try {
11044            removeContentProviderExternalUnchecked(name, token, userId);
11045        } finally {
11046            Binder.restoreCallingIdentity(ident);
11047        }
11048    }
11049
11050    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11051        synchronized (this) {
11052            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11053            if(cpr == null) {
11054                //remove from mProvidersByClass
11055                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11056                return;
11057            }
11058
11059            //update content provider record entry info
11060            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11061            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11062            if (localCpr.hasExternalProcessHandles()) {
11063                if (localCpr.removeExternalProcessHandleLocked(token)) {
11064                    updateOomAdjLocked();
11065                } else {
11066                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11067                            + " with no external reference for token: "
11068                            + token + ".");
11069                }
11070            } else {
11071                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11072                        + " with no external references.");
11073            }
11074        }
11075    }
11076
11077    public final void publishContentProviders(IApplicationThread caller,
11078            List<ContentProviderHolder> providers) {
11079        if (providers == null) {
11080            return;
11081        }
11082
11083        enforceNotIsolatedCaller("publishContentProviders");
11084        synchronized (this) {
11085            final ProcessRecord r = getRecordForAppLocked(caller);
11086            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11087            if (r == null) {
11088                throw new SecurityException(
11089                        "Unable to find app for caller " + caller
11090                      + " (pid=" + Binder.getCallingPid()
11091                      + ") when publishing content providers");
11092            }
11093
11094            final long origId = Binder.clearCallingIdentity();
11095
11096            final int N = providers.size();
11097            for (int i = 0; i < N; i++) {
11098                ContentProviderHolder src = providers.get(i);
11099                if (src == null || src.info == null || src.provider == null) {
11100                    continue;
11101                }
11102                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11103                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11104                if (dst != null) {
11105                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11106                    mProviderMap.putProviderByClass(comp, dst);
11107                    String names[] = dst.info.authority.split(";");
11108                    for (int j = 0; j < names.length; j++) {
11109                        mProviderMap.putProviderByName(names[j], dst);
11110                    }
11111
11112                    int launchingCount = mLaunchingProviders.size();
11113                    int j;
11114                    boolean wasInLaunchingProviders = false;
11115                    for (j = 0; j < launchingCount; j++) {
11116                        if (mLaunchingProviders.get(j) == dst) {
11117                            mLaunchingProviders.remove(j);
11118                            wasInLaunchingProviders = true;
11119                            j--;
11120                            launchingCount--;
11121                        }
11122                    }
11123                    if (wasInLaunchingProviders) {
11124                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11125                    }
11126                    synchronized (dst) {
11127                        dst.provider = src.provider;
11128                        dst.proc = r;
11129                        dst.notifyAll();
11130                    }
11131                    updateOomAdjLocked(r);
11132                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11133                            src.info.authority);
11134                }
11135            }
11136
11137            Binder.restoreCallingIdentity(origId);
11138        }
11139    }
11140
11141    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11142        ContentProviderConnection conn;
11143        try {
11144            conn = (ContentProviderConnection)connection;
11145        } catch (ClassCastException e) {
11146            String msg ="refContentProvider: " + connection
11147                    + " not a ContentProviderConnection";
11148            Slog.w(TAG, msg);
11149            throw new IllegalArgumentException(msg);
11150        }
11151        if (conn == null) {
11152            throw new NullPointerException("connection is null");
11153        }
11154
11155        synchronized (this) {
11156            if (stable > 0) {
11157                conn.numStableIncs += stable;
11158            }
11159            stable = conn.stableCount + stable;
11160            if (stable < 0) {
11161                throw new IllegalStateException("stableCount < 0: " + stable);
11162            }
11163
11164            if (unstable > 0) {
11165                conn.numUnstableIncs += unstable;
11166            }
11167            unstable = conn.unstableCount + unstable;
11168            if (unstable < 0) {
11169                throw new IllegalStateException("unstableCount < 0: " + unstable);
11170            }
11171
11172            if ((stable+unstable) <= 0) {
11173                throw new IllegalStateException("ref counts can't go to zero here: stable="
11174                        + stable + " unstable=" + unstable);
11175            }
11176            conn.stableCount = stable;
11177            conn.unstableCount = unstable;
11178            return !conn.dead;
11179        }
11180    }
11181
11182    public void unstableProviderDied(IBinder connection) {
11183        ContentProviderConnection conn;
11184        try {
11185            conn = (ContentProviderConnection)connection;
11186        } catch (ClassCastException e) {
11187            String msg ="refContentProvider: " + connection
11188                    + " not a ContentProviderConnection";
11189            Slog.w(TAG, msg);
11190            throw new IllegalArgumentException(msg);
11191        }
11192        if (conn == null) {
11193            throw new NullPointerException("connection is null");
11194        }
11195
11196        // Safely retrieve the content provider associated with the connection.
11197        IContentProvider provider;
11198        synchronized (this) {
11199            provider = conn.provider.provider;
11200        }
11201
11202        if (provider == null) {
11203            // Um, yeah, we're way ahead of you.
11204            return;
11205        }
11206
11207        // Make sure the caller is being honest with us.
11208        if (provider.asBinder().pingBinder()) {
11209            // Er, no, still looks good to us.
11210            synchronized (this) {
11211                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11212                        + " says " + conn + " died, but we don't agree");
11213                return;
11214            }
11215        }
11216
11217        // Well look at that!  It's dead!
11218        synchronized (this) {
11219            if (conn.provider.provider != provider) {
11220                // But something changed...  good enough.
11221                return;
11222            }
11223
11224            ProcessRecord proc = conn.provider.proc;
11225            if (proc == null || proc.thread == null) {
11226                // Seems like the process is already cleaned up.
11227                return;
11228            }
11229
11230            // As far as we're concerned, this is just like receiving a
11231            // death notification...  just a bit prematurely.
11232            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11233                    + ") early provider death");
11234            final long ident = Binder.clearCallingIdentity();
11235            try {
11236                appDiedLocked(proc);
11237            } finally {
11238                Binder.restoreCallingIdentity(ident);
11239            }
11240        }
11241    }
11242
11243    @Override
11244    public void appNotRespondingViaProvider(IBinder connection) {
11245        enforceCallingPermission(
11246                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11247
11248        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11249        if (conn == null) {
11250            Slog.w(TAG, "ContentProviderConnection is null");
11251            return;
11252        }
11253
11254        final ProcessRecord host = conn.provider.proc;
11255        if (host == null) {
11256            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11257            return;
11258        }
11259
11260        mHandler.post(new Runnable() {
11261            @Override
11262            public void run() {
11263                mAppErrors.appNotResponding(host, null, null, false,
11264                        "ContentProvider not responding");
11265            }
11266        });
11267    }
11268
11269    public final void installSystemProviders() {
11270        List<ProviderInfo> providers;
11271        synchronized (this) {
11272            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11273            providers = generateApplicationProvidersLocked(app);
11274            if (providers != null) {
11275                for (int i=providers.size()-1; i>=0; i--) {
11276                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11277                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11278                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11279                                + ": not system .apk");
11280                        providers.remove(i);
11281                    }
11282                }
11283            }
11284        }
11285        if (providers != null) {
11286            mSystemThread.installSystemProviders(providers);
11287        }
11288
11289        mCoreSettingsObserver = new CoreSettingsObserver(this);
11290        mFontScaleSettingObserver = new FontScaleSettingObserver();
11291
11292        //mUsageStatsService.monitorPackages();
11293    }
11294
11295    private void startPersistentApps(int matchFlags) {
11296        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11297
11298        synchronized (this) {
11299            try {
11300                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11301                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11302                for (ApplicationInfo app : apps) {
11303                    if (!"android".equals(app.packageName)) {
11304                        addAppLocked(app, false, null /* ABI override */);
11305                    }
11306                }
11307            } catch (RemoteException ex) {
11308            }
11309        }
11310    }
11311
11312    /**
11313     * When a user is unlocked, we need to install encryption-unaware providers
11314     * belonging to any running apps.
11315     */
11316    private void installEncryptionUnawareProviders(int userId) {
11317        // We're only interested in providers that are encryption unaware, and
11318        // we don't care about uninstalled apps, since there's no way they're
11319        // running at this point.
11320        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11321
11322        synchronized (this) {
11323            final int NP = mProcessNames.getMap().size();
11324            for (int ip = 0; ip < NP; ip++) {
11325                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11326                final int NA = apps.size();
11327                for (int ia = 0; ia < NA; ia++) {
11328                    final ProcessRecord app = apps.valueAt(ia);
11329                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11330
11331                    final int NG = app.pkgList.size();
11332                    for (int ig = 0; ig < NG; ig++) {
11333                        try {
11334                            final String pkgName = app.pkgList.keyAt(ig);
11335                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11336                                    .getPackageInfo(pkgName, matchFlags, userId);
11337                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11338                                for (ProviderInfo pi : pkgInfo.providers) {
11339                                    // TODO: keep in sync with generateApplicationProvidersLocked
11340                                    final boolean processMatch = Objects.equals(pi.processName,
11341                                            app.processName) || pi.multiprocess;
11342                                    final boolean userMatch = isSingleton(pi.processName,
11343                                            pi.applicationInfo, pi.name, pi.flags)
11344                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11345                                    if (processMatch && userMatch) {
11346                                        Log.v(TAG, "Installing " + pi);
11347                                        app.thread.scheduleInstallProvider(pi);
11348                                    } else {
11349                                        Log.v(TAG, "Skipping " + pi);
11350                                    }
11351                                }
11352                            }
11353                        } catch (RemoteException ignored) {
11354                        }
11355                    }
11356                }
11357            }
11358        }
11359    }
11360
11361    /**
11362     * Allows apps to retrieve the MIME type of a URI.
11363     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11364     * users, then it does not need permission to access the ContentProvider.
11365     * Either, it needs cross-user uri grants.
11366     *
11367     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11368     *
11369     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11370     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11371     */
11372    public String getProviderMimeType(Uri uri, int userId) {
11373        enforceNotIsolatedCaller("getProviderMimeType");
11374        final String name = uri.getAuthority();
11375        int callingUid = Binder.getCallingUid();
11376        int callingPid = Binder.getCallingPid();
11377        long ident = 0;
11378        boolean clearedIdentity = false;
11379        synchronized (this) {
11380            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11381        }
11382        if (canClearIdentity(callingPid, callingUid, userId)) {
11383            clearedIdentity = true;
11384            ident = Binder.clearCallingIdentity();
11385        }
11386        ContentProviderHolder holder = null;
11387        try {
11388            holder = getContentProviderExternalUnchecked(name, null, userId);
11389            if (holder != null) {
11390                return holder.provider.getType(uri);
11391            }
11392        } catch (RemoteException e) {
11393            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11394            return null;
11395        } catch (Exception e) {
11396            Log.w(TAG, "Exception while determining type of " + uri, e);
11397            return null;
11398        } finally {
11399            // We need to clear the identity to call removeContentProviderExternalUnchecked
11400            if (!clearedIdentity) {
11401                ident = Binder.clearCallingIdentity();
11402            }
11403            try {
11404                if (holder != null) {
11405                    removeContentProviderExternalUnchecked(name, null, userId);
11406                }
11407            } finally {
11408                Binder.restoreCallingIdentity(ident);
11409            }
11410        }
11411
11412        return null;
11413    }
11414
11415    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11416        if (UserHandle.getUserId(callingUid) == userId) {
11417            return true;
11418        }
11419        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11420                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11421                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11422                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11423                return true;
11424        }
11425        return false;
11426    }
11427
11428    // =========================================================
11429    // GLOBAL MANAGEMENT
11430    // =========================================================
11431
11432    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11433            boolean isolated, int isolatedUid) {
11434        String proc = customProcess != null ? customProcess : info.processName;
11435        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11436        final int userId = UserHandle.getUserId(info.uid);
11437        int uid = info.uid;
11438        if (isolated) {
11439            if (isolatedUid == 0) {
11440                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11441                while (true) {
11442                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11443                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11444                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11445                    }
11446                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11447                    mNextIsolatedProcessUid++;
11448                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11449                        // No process for this uid, use it.
11450                        break;
11451                    }
11452                    stepsLeft--;
11453                    if (stepsLeft <= 0) {
11454                        return null;
11455                    }
11456                }
11457            } else {
11458                // Special case for startIsolatedProcess (internal only), where
11459                // the uid of the isolated process is specified by the caller.
11460                uid = isolatedUid;
11461            }
11462
11463            // Register the isolated UID with this application so BatteryStats knows to
11464            // attribute resource usage to the application.
11465            //
11466            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11467            // about the process state of the isolated UID *before* it is registered with the
11468            // owning application.
11469            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11470        }
11471        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11472        if (!mBooted && !mBooting
11473                && userId == UserHandle.USER_SYSTEM
11474                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11475            r.persistent = true;
11476        }
11477        addProcessNameLocked(r);
11478        return r;
11479    }
11480
11481    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11482            String abiOverride) {
11483        ProcessRecord app;
11484        if (!isolated) {
11485            app = getProcessRecordLocked(info.processName, info.uid, true);
11486        } else {
11487            app = null;
11488        }
11489
11490        if (app == null) {
11491            app = newProcessRecordLocked(info, null, isolated, 0);
11492            updateLruProcessLocked(app, false, null);
11493            updateOomAdjLocked();
11494        }
11495
11496        // This package really, really can not be stopped.
11497        try {
11498            AppGlobals.getPackageManager().setPackageStoppedState(
11499                    info.packageName, false, UserHandle.getUserId(app.uid));
11500        } catch (RemoteException e) {
11501        } catch (IllegalArgumentException e) {
11502            Slog.w(TAG, "Failed trying to unstop package "
11503                    + info.packageName + ": " + e);
11504        }
11505
11506        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11507            app.persistent = true;
11508            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11509        }
11510        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11511            mPersistentStartingProcesses.add(app);
11512            startProcessLocked(app, "added application", app.processName, abiOverride,
11513                    null /* entryPoint */, null /* entryPointArgs */);
11514        }
11515
11516        return app;
11517    }
11518
11519    public void unhandledBack() {
11520        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11521                "unhandledBack()");
11522
11523        synchronized(this) {
11524            final long origId = Binder.clearCallingIdentity();
11525            try {
11526                getFocusedStack().unhandledBackLocked();
11527            } finally {
11528                Binder.restoreCallingIdentity(origId);
11529            }
11530        }
11531    }
11532
11533    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11534        enforceNotIsolatedCaller("openContentUri");
11535        final int userId = UserHandle.getCallingUserId();
11536        String name = uri.getAuthority();
11537        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11538        ParcelFileDescriptor pfd = null;
11539        if (cph != null) {
11540            // We record the binder invoker's uid in thread-local storage before
11541            // going to the content provider to open the file.  Later, in the code
11542            // that handles all permissions checks, we look for this uid and use
11543            // that rather than the Activity Manager's own uid.  The effect is that
11544            // we do the check against the caller's permissions even though it looks
11545            // to the content provider like the Activity Manager itself is making
11546            // the request.
11547            Binder token = new Binder();
11548            sCallerIdentity.set(new Identity(
11549                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11550            try {
11551                pfd = cph.provider.openFile(null, uri, "r", null, token);
11552            } catch (FileNotFoundException e) {
11553                // do nothing; pfd will be returned null
11554            } finally {
11555                // Ensure that whatever happens, we clean up the identity state
11556                sCallerIdentity.remove();
11557                // Ensure we're done with the provider.
11558                removeContentProviderExternalUnchecked(name, null, userId);
11559            }
11560        } else {
11561            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11562        }
11563        return pfd;
11564    }
11565
11566    // Actually is sleeping or shutting down or whatever else in the future
11567    // is an inactive state.
11568    boolean isSleepingOrShuttingDownLocked() {
11569        return isSleepingLocked() || mShuttingDown;
11570    }
11571
11572    boolean isShuttingDownLocked() {
11573        return mShuttingDown;
11574    }
11575
11576    boolean isSleepingLocked() {
11577        return mSleeping;
11578    }
11579
11580    void onWakefulnessChanged(int wakefulness) {
11581        synchronized(this) {
11582            mWakefulness = wakefulness;
11583            updateSleepIfNeededLocked();
11584        }
11585    }
11586
11587    void finishRunningVoiceLocked() {
11588        if (mRunningVoice != null) {
11589            mRunningVoice = null;
11590            mVoiceWakeLock.release();
11591            updateSleepIfNeededLocked();
11592        }
11593    }
11594
11595    void startTimeTrackingFocusedActivityLocked() {
11596        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11597            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11598        }
11599    }
11600
11601    void updateSleepIfNeededLocked() {
11602        if (mSleeping && !shouldSleepLocked()) {
11603            mSleeping = false;
11604            startTimeTrackingFocusedActivityLocked();
11605            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11606            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11607            updateOomAdjLocked();
11608        } else if (!mSleeping && shouldSleepLocked()) {
11609            mSleeping = true;
11610            if (mCurAppTimeTracker != null) {
11611                mCurAppTimeTracker.stop();
11612            }
11613            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11614            mStackSupervisor.goingToSleepLocked();
11615            updateOomAdjLocked();
11616
11617            // Initialize the wake times of all processes.
11618            checkExcessivePowerUsageLocked(false);
11619            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11620            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11621            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11622        }
11623    }
11624
11625    private boolean shouldSleepLocked() {
11626        // Resume applications while running a voice interactor.
11627        if (mRunningVoice != null) {
11628            return false;
11629        }
11630
11631        // TODO: Transform the lock screen state into a sleep token instead.
11632        switch (mWakefulness) {
11633            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11634            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11635            case PowerManagerInternal.WAKEFULNESS_DOZING:
11636                // Pause applications whenever the lock screen is shown or any sleep
11637                // tokens have been acquired.
11638                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11639            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11640            default:
11641                // If we're asleep then pause applications unconditionally.
11642                return true;
11643        }
11644    }
11645
11646    /** Pokes the task persister. */
11647    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11648        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11649    }
11650
11651    /** Notifies all listeners when the task stack has changed. */
11652    void notifyTaskStackChangedLocked() {
11653        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11654        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11655        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11656        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11657    }
11658
11659    /** Notifies all listeners when an Activity is pinned. */
11660    void notifyActivityPinnedLocked() {
11661        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11662        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11663    }
11664
11665    /**
11666     * Notifies all listeners when an attempt was made to start an an activity that is already
11667     * running in the pinned stack and the activity was not actually started, but the task is
11668     * either brought to the front or a new Intent is delivered to it.
11669     */
11670    void notifyPinnedActivityRestartAttemptLocked() {
11671        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11672        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11673    }
11674
11675    /** Notifies all listeners when the pinned stack animation ends. */
11676    @Override
11677    public void notifyPinnedStackAnimationEnded() {
11678        synchronized (this) {
11679            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11680            mHandler.obtainMessage(
11681                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11682        }
11683    }
11684
11685    @Override
11686    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11687        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11688    }
11689
11690    @Override
11691    public boolean shutdown(int timeout) {
11692        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11693                != PackageManager.PERMISSION_GRANTED) {
11694            throw new SecurityException("Requires permission "
11695                    + android.Manifest.permission.SHUTDOWN);
11696        }
11697
11698        boolean timedout = false;
11699
11700        synchronized(this) {
11701            mShuttingDown = true;
11702            updateEventDispatchingLocked();
11703            timedout = mStackSupervisor.shutdownLocked(timeout);
11704        }
11705
11706        mAppOpsService.shutdown();
11707        if (mUsageStatsService != null) {
11708            mUsageStatsService.prepareShutdown();
11709        }
11710        mBatteryStatsService.shutdown();
11711        synchronized (this) {
11712            mProcessStats.shutdownLocked();
11713            notifyTaskPersisterLocked(null, true);
11714        }
11715
11716        return timedout;
11717    }
11718
11719    public final void activitySlept(IBinder token) {
11720        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11721
11722        final long origId = Binder.clearCallingIdentity();
11723
11724        synchronized (this) {
11725            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11726            if (r != null) {
11727                mStackSupervisor.activitySleptLocked(r);
11728            }
11729        }
11730
11731        Binder.restoreCallingIdentity(origId);
11732    }
11733
11734    private String lockScreenShownToString() {
11735        switch (mLockScreenShown) {
11736            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11737            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11738            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11739            default: return "Unknown=" + mLockScreenShown;
11740        }
11741    }
11742
11743    void logLockScreen(String msg) {
11744        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11745                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11746                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11747                + " mSleeping=" + mSleeping);
11748    }
11749
11750    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11751        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11752        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11753        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11754            boolean wasRunningVoice = mRunningVoice != null;
11755            mRunningVoice = session;
11756            if (!wasRunningVoice) {
11757                mVoiceWakeLock.acquire();
11758                updateSleepIfNeededLocked();
11759            }
11760        }
11761    }
11762
11763    private void updateEventDispatchingLocked() {
11764        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11765    }
11766
11767    public void setLockScreenShown(boolean showing, boolean occluded) {
11768        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11769                != PackageManager.PERMISSION_GRANTED) {
11770            throw new SecurityException("Requires permission "
11771                    + android.Manifest.permission.DEVICE_POWER);
11772        }
11773
11774        synchronized(this) {
11775            long ident = Binder.clearCallingIdentity();
11776            try {
11777                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11778                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11779                if (showing && occluded) {
11780                    // The lock screen is currently showing, but is occluded by a window that can
11781                    // show on top of the lock screen. In this can we want to dismiss the docked
11782                    // stack since it will be complicated/risky to try to put the activity on top
11783                    // of the lock screen in the right fullscreen configuration.
11784                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11785                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11786                }
11787
11788                updateSleepIfNeededLocked();
11789            } finally {
11790                Binder.restoreCallingIdentity(ident);
11791            }
11792        }
11793    }
11794
11795    @Override
11796    public void notifyLockedProfile(@UserIdInt int userId) {
11797        try {
11798            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11799                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11800            }
11801        } catch (RemoteException ex) {
11802            throw new SecurityException("Fail to check is caller a privileged app", ex);
11803        }
11804
11805        synchronized (this) {
11806            if (mStackSupervisor.isUserLockedProfile(userId)) {
11807                final long ident = Binder.clearCallingIdentity();
11808                try {
11809                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11810                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11811                        // If there is no device lock, we will show the profile's credential page.
11812                        mActivityStarter.showConfirmDeviceCredential(userId);
11813                    } else {
11814                        // Showing launcher to avoid user entering credential twice.
11815                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11816                    }
11817                } finally {
11818                    Binder.restoreCallingIdentity(ident);
11819                }
11820            }
11821        }
11822    }
11823
11824    @Override
11825    public void startConfirmDeviceCredentialIntent(Intent intent) {
11826        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11827        synchronized (this) {
11828            final long ident = Binder.clearCallingIdentity();
11829            try {
11830                mActivityStarter.startConfirmCredentialIntent(intent);
11831            } finally {
11832                Binder.restoreCallingIdentity(ident);
11833            }
11834        }
11835    }
11836
11837    @Override
11838    public void stopAppSwitches() {
11839        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11840                != PackageManager.PERMISSION_GRANTED) {
11841            throw new SecurityException("viewquires permission "
11842                    + android.Manifest.permission.STOP_APP_SWITCHES);
11843        }
11844
11845        synchronized(this) {
11846            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11847                    + APP_SWITCH_DELAY_TIME;
11848            mDidAppSwitch = false;
11849            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11850            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11851            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11852        }
11853    }
11854
11855    public void resumeAppSwitches() {
11856        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11857                != PackageManager.PERMISSION_GRANTED) {
11858            throw new SecurityException("Requires permission "
11859                    + android.Manifest.permission.STOP_APP_SWITCHES);
11860        }
11861
11862        synchronized(this) {
11863            // Note that we don't execute any pending app switches... we will
11864            // let those wait until either the timeout, or the next start
11865            // activity request.
11866            mAppSwitchesAllowedTime = 0;
11867        }
11868    }
11869
11870    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11871            int callingPid, int callingUid, String name) {
11872        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11873            return true;
11874        }
11875
11876        int perm = checkComponentPermission(
11877                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11878                sourceUid, -1, true);
11879        if (perm == PackageManager.PERMISSION_GRANTED) {
11880            return true;
11881        }
11882
11883        // If the actual IPC caller is different from the logical source, then
11884        // also see if they are allowed to control app switches.
11885        if (callingUid != -1 && callingUid != sourceUid) {
11886            perm = checkComponentPermission(
11887                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11888                    callingUid, -1, true);
11889            if (perm == PackageManager.PERMISSION_GRANTED) {
11890                return true;
11891            }
11892        }
11893
11894        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11895        return false;
11896    }
11897
11898    public void setDebugApp(String packageName, boolean waitForDebugger,
11899            boolean persistent) {
11900        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11901                "setDebugApp()");
11902
11903        long ident = Binder.clearCallingIdentity();
11904        try {
11905            // Note that this is not really thread safe if there are multiple
11906            // callers into it at the same time, but that's not a situation we
11907            // care about.
11908            if (persistent) {
11909                final ContentResolver resolver = mContext.getContentResolver();
11910                Settings.Global.putString(
11911                    resolver, Settings.Global.DEBUG_APP,
11912                    packageName);
11913                Settings.Global.putInt(
11914                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11915                    waitForDebugger ? 1 : 0);
11916            }
11917
11918            synchronized (this) {
11919                if (!persistent) {
11920                    mOrigDebugApp = mDebugApp;
11921                    mOrigWaitForDebugger = mWaitForDebugger;
11922                }
11923                mDebugApp = packageName;
11924                mWaitForDebugger = waitForDebugger;
11925                mDebugTransient = !persistent;
11926                if (packageName != null) {
11927                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11928                            false, UserHandle.USER_ALL, "set debug app");
11929                }
11930            }
11931        } finally {
11932            Binder.restoreCallingIdentity(ident);
11933        }
11934    }
11935
11936    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11937        synchronized (this) {
11938            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11939            if (!isDebuggable) {
11940                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11941                    throw new SecurityException("Process not debuggable: " + app.packageName);
11942                }
11943            }
11944
11945            mTrackAllocationApp = processName;
11946        }
11947    }
11948
11949    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11950        synchronized (this) {
11951            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11952            if (!isDebuggable) {
11953                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11954                    throw new SecurityException("Process not debuggable: " + app.packageName);
11955                }
11956            }
11957            mProfileApp = processName;
11958            mProfileFile = profilerInfo.profileFile;
11959            if (mProfileFd != null) {
11960                try {
11961                    mProfileFd.close();
11962                } catch (IOException e) {
11963                }
11964                mProfileFd = null;
11965            }
11966            mProfileFd = profilerInfo.profileFd;
11967            mSamplingInterval = profilerInfo.samplingInterval;
11968            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11969            mProfileType = 0;
11970        }
11971    }
11972
11973    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11974        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11975        if (!isDebuggable) {
11976            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11977                throw new SecurityException("Process not debuggable: " + app.packageName);
11978            }
11979        }
11980        mNativeDebuggingApp = processName;
11981    }
11982
11983    @Override
11984    public void setAlwaysFinish(boolean enabled) {
11985        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11986                "setAlwaysFinish()");
11987
11988        long ident = Binder.clearCallingIdentity();
11989        try {
11990            Settings.Global.putInt(
11991                    mContext.getContentResolver(),
11992                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11993
11994            synchronized (this) {
11995                mAlwaysFinishActivities = enabled;
11996            }
11997        } finally {
11998            Binder.restoreCallingIdentity(ident);
11999        }
12000    }
12001
12002    @Override
12003    public void setLenientBackgroundCheck(boolean enabled) {
12004        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12005                "setLenientBackgroundCheck()");
12006
12007        long ident = Binder.clearCallingIdentity();
12008        try {
12009            Settings.Global.putInt(
12010                    mContext.getContentResolver(),
12011                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12012
12013            synchronized (this) {
12014                mLenientBackgroundCheck = enabled;
12015            }
12016        } finally {
12017            Binder.restoreCallingIdentity(ident);
12018        }
12019    }
12020
12021    @Override
12022    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12023        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12024                "setActivityController()");
12025        synchronized (this) {
12026            mController = controller;
12027            mControllerIsAMonkey = imAMonkey;
12028            Watchdog.getInstance().setActivityController(controller);
12029        }
12030    }
12031
12032    @Override
12033    public void setUserIsMonkey(boolean userIsMonkey) {
12034        synchronized (this) {
12035            synchronized (mPidsSelfLocked) {
12036                final int callingPid = Binder.getCallingPid();
12037                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12038                if (precessRecord == null) {
12039                    throw new SecurityException("Unknown process: " + callingPid);
12040                }
12041                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12042                    throw new SecurityException("Only an instrumentation process "
12043                            + "with a UiAutomation can call setUserIsMonkey");
12044                }
12045            }
12046            mUserIsMonkey = userIsMonkey;
12047        }
12048    }
12049
12050    @Override
12051    public boolean isUserAMonkey() {
12052        synchronized (this) {
12053            // If there is a controller also implies the user is a monkey.
12054            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12055        }
12056    }
12057
12058    public void requestBugReport(int bugreportType) {
12059        String service = null;
12060        switch (bugreportType) {
12061            case ActivityManager.BUGREPORT_OPTION_FULL:
12062                service = "bugreport";
12063                break;
12064            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12065                service = "bugreportplus";
12066                break;
12067            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12068                service = "bugreportremote";
12069                break;
12070            case ActivityManager.BUGREPORT_OPTION_WEAR:
12071                service = "bugreportwear";
12072                break;
12073        }
12074        if (service == null) {
12075            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12076                    + bugreportType);
12077        }
12078        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12079        SystemProperties.set("ctl.start", service);
12080    }
12081
12082    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12083        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12084    }
12085
12086    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12087        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12088            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12089        }
12090        return KEY_DISPATCHING_TIMEOUT;
12091    }
12092
12093    @Override
12094    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12095        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12096                != PackageManager.PERMISSION_GRANTED) {
12097            throw new SecurityException("Requires permission "
12098                    + android.Manifest.permission.FILTER_EVENTS);
12099        }
12100        ProcessRecord proc;
12101        long timeout;
12102        synchronized (this) {
12103            synchronized (mPidsSelfLocked) {
12104                proc = mPidsSelfLocked.get(pid);
12105            }
12106            timeout = getInputDispatchingTimeoutLocked(proc);
12107        }
12108
12109        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12110            return -1;
12111        }
12112
12113        return timeout;
12114    }
12115
12116    /**
12117     * Handle input dispatching timeouts.
12118     * Returns whether input dispatching should be aborted or not.
12119     */
12120    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12121            final ActivityRecord activity, final ActivityRecord parent,
12122            final boolean aboveSystem, String reason) {
12123        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12124                != PackageManager.PERMISSION_GRANTED) {
12125            throw new SecurityException("Requires permission "
12126                    + android.Manifest.permission.FILTER_EVENTS);
12127        }
12128
12129        final String annotation;
12130        if (reason == null) {
12131            annotation = "Input dispatching timed out";
12132        } else {
12133            annotation = "Input dispatching timed out (" + reason + ")";
12134        }
12135
12136        if (proc != null) {
12137            synchronized (this) {
12138                if (proc.debugging) {
12139                    return false;
12140                }
12141
12142                if (mDidDexOpt) {
12143                    // Give more time since we were dexopting.
12144                    mDidDexOpt = false;
12145                    return false;
12146                }
12147
12148                if (proc.instrumentationClass != null) {
12149                    Bundle info = new Bundle();
12150                    info.putString("shortMsg", "keyDispatchingTimedOut");
12151                    info.putString("longMsg", annotation);
12152                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12153                    return true;
12154                }
12155            }
12156            mHandler.post(new Runnable() {
12157                @Override
12158                public void run() {
12159                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12160                }
12161            });
12162        }
12163
12164        return true;
12165    }
12166
12167    @Override
12168    public Bundle getAssistContextExtras(int requestType) {
12169        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12170                null, null, true /* focused */, true /* newSessionId */,
12171                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12172        if (pae == null) {
12173            return null;
12174        }
12175        synchronized (pae) {
12176            while (!pae.haveResult) {
12177                try {
12178                    pae.wait();
12179                } catch (InterruptedException e) {
12180                }
12181            }
12182        }
12183        synchronized (this) {
12184            buildAssistBundleLocked(pae, pae.result);
12185            mPendingAssistExtras.remove(pae);
12186            mUiHandler.removeCallbacks(pae);
12187        }
12188        return pae.extras;
12189    }
12190
12191    @Override
12192    public boolean isAssistDataAllowedOnCurrentActivity() {
12193        int userId;
12194        synchronized (this) {
12195            userId = mUserController.getCurrentUserIdLocked();
12196            ActivityRecord activity = getFocusedStack().topActivity();
12197            if (activity == null) {
12198                return false;
12199            }
12200            userId = activity.userId;
12201        }
12202        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12203                Context.DEVICE_POLICY_SERVICE);
12204        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12205    }
12206
12207    @Override
12208    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12209        long ident = Binder.clearCallingIdentity();
12210        try {
12211            synchronized (this) {
12212                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12213                ActivityRecord top = getFocusedStack().topActivity();
12214                if (top != caller) {
12215                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12216                            + " is not current top " + top);
12217                    return false;
12218                }
12219                if (!top.nowVisible) {
12220                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12221                            + " is not visible");
12222                    return false;
12223                }
12224            }
12225            AssistUtils utils = new AssistUtils(mContext);
12226            return utils.showSessionForActiveService(args,
12227                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12228        } finally {
12229            Binder.restoreCallingIdentity(ident);
12230        }
12231    }
12232
12233    @Override
12234    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12235            Bundle receiverExtras,
12236            IBinder activityToken, boolean focused, boolean newSessionId) {
12237        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12238                activityToken, focused, newSessionId,
12239                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12240                != null;
12241    }
12242
12243    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12244            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12245            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12246        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12247                "enqueueAssistContext()");
12248        synchronized (this) {
12249            ActivityRecord activity = getFocusedStack().topActivity();
12250            if (activity == null) {
12251                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12252                return null;
12253            }
12254            if (activity.app == null || activity.app.thread == null) {
12255                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12256                return null;
12257            }
12258            if (focused) {
12259                if (activityToken != null) {
12260                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12261                    if (activity != caller) {
12262                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12263                                + " is not current top " + activity);
12264                        return null;
12265                    }
12266                }
12267            } else {
12268                activity = ActivityRecord.forTokenLocked(activityToken);
12269                if (activity == null) {
12270                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12271                            + " couldn't be found");
12272                    return null;
12273                }
12274            }
12275
12276            PendingAssistExtras pae;
12277            Bundle extras = new Bundle();
12278            if (args != null) {
12279                extras.putAll(args);
12280            }
12281            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12282            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12283            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12284                    userHandle);
12285            // Increment the sessionId if necessary
12286            if (newSessionId) {
12287                mViSessionId++;
12288            }
12289            try {
12290                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12291                        requestType, mViSessionId);
12292                mPendingAssistExtras.add(pae);
12293                mUiHandler.postDelayed(pae, timeout);
12294            } catch (RemoteException e) {
12295                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12296                return null;
12297            }
12298            return pae;
12299        }
12300    }
12301
12302    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12303        IResultReceiver receiver;
12304        synchronized (this) {
12305            mPendingAssistExtras.remove(pae);
12306            receiver = pae.receiver;
12307        }
12308        if (receiver != null) {
12309            // Caller wants result sent back to them.
12310            Bundle sendBundle = new Bundle();
12311            // At least return the receiver extras
12312            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12313                    pae.receiverExtras);
12314            try {
12315                pae.receiver.send(0, sendBundle);
12316            } catch (RemoteException e) {
12317            }
12318        }
12319    }
12320
12321    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12322        if (result != null) {
12323            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12324        }
12325        if (pae.hint != null) {
12326            pae.extras.putBoolean(pae.hint, true);
12327        }
12328    }
12329
12330    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12331            AssistContent content, Uri referrer) {
12332        PendingAssistExtras pae = (PendingAssistExtras)token;
12333        synchronized (pae) {
12334            pae.result = extras;
12335            pae.structure = structure;
12336            pae.content = content;
12337            if (referrer != null) {
12338                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12339            }
12340            pae.haveResult = true;
12341            pae.notifyAll();
12342            if (pae.intent == null && pae.receiver == null) {
12343                // Caller is just waiting for the result.
12344                return;
12345            }
12346        }
12347
12348        // We are now ready to launch the assist activity.
12349        IResultReceiver sendReceiver = null;
12350        Bundle sendBundle = null;
12351        synchronized (this) {
12352            buildAssistBundleLocked(pae, extras);
12353            boolean exists = mPendingAssistExtras.remove(pae);
12354            mUiHandler.removeCallbacks(pae);
12355            if (!exists) {
12356                // Timed out.
12357                return;
12358            }
12359            if ((sendReceiver=pae.receiver) != null) {
12360                // Caller wants result sent back to them.
12361                sendBundle = new Bundle();
12362                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12363                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12364                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12365                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12366                        pae.receiverExtras);
12367            }
12368        }
12369        if (sendReceiver != null) {
12370            try {
12371                sendReceiver.send(0, sendBundle);
12372            } catch (RemoteException e) {
12373            }
12374            return;
12375        }
12376
12377        long ident = Binder.clearCallingIdentity();
12378        try {
12379            pae.intent.replaceExtras(pae.extras);
12380            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12381                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12382                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12383            closeSystemDialogs("assist");
12384            try {
12385                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12386            } catch (ActivityNotFoundException e) {
12387                Slog.w(TAG, "No activity to handle assist action.", e);
12388            }
12389        } finally {
12390            Binder.restoreCallingIdentity(ident);
12391        }
12392    }
12393
12394    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12395            Bundle args) {
12396        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12397                true /* focused */, true /* newSessionId */,
12398                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12399    }
12400
12401    public void registerProcessObserver(IProcessObserver observer) {
12402        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12403                "registerProcessObserver()");
12404        synchronized (this) {
12405            mProcessObservers.register(observer);
12406        }
12407    }
12408
12409    @Override
12410    public void unregisterProcessObserver(IProcessObserver observer) {
12411        synchronized (this) {
12412            mProcessObservers.unregister(observer);
12413        }
12414    }
12415
12416    @Override
12417    public void registerUidObserver(IUidObserver observer, int which) {
12418        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12419                "registerUidObserver()");
12420        synchronized (this) {
12421            mUidObservers.register(observer, which);
12422        }
12423    }
12424
12425    @Override
12426    public void unregisterUidObserver(IUidObserver observer) {
12427        synchronized (this) {
12428            mUidObservers.unregister(observer);
12429        }
12430    }
12431
12432    @Override
12433    public boolean convertFromTranslucent(IBinder token) {
12434        final long origId = Binder.clearCallingIdentity();
12435        try {
12436            synchronized (this) {
12437                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12438                if (r == null) {
12439                    return false;
12440                }
12441                final boolean translucentChanged = r.changeWindowTranslucency(true);
12442                if (translucentChanged) {
12443                    r.task.stack.releaseBackgroundResources(r);
12444                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12445                }
12446                mWindowManager.setAppFullscreen(token, true);
12447                return translucentChanged;
12448            }
12449        } finally {
12450            Binder.restoreCallingIdentity(origId);
12451        }
12452    }
12453
12454    @Override
12455    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12456        final long origId = Binder.clearCallingIdentity();
12457        try {
12458            synchronized (this) {
12459                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12460                if (r == null) {
12461                    return false;
12462                }
12463                int index = r.task.mActivities.lastIndexOf(r);
12464                if (index > 0) {
12465                    ActivityRecord under = r.task.mActivities.get(index - 1);
12466                    under.returningOptions = options;
12467                }
12468                final boolean translucentChanged = r.changeWindowTranslucency(false);
12469                if (translucentChanged) {
12470                    r.task.stack.convertActivityToTranslucent(r);
12471                }
12472                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12473                mWindowManager.setAppFullscreen(token, false);
12474                return translucentChanged;
12475            }
12476        } finally {
12477            Binder.restoreCallingIdentity(origId);
12478        }
12479    }
12480
12481    @Override
12482    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12483        final long origId = Binder.clearCallingIdentity();
12484        try {
12485            synchronized (this) {
12486                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12487                if (r != null) {
12488                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12489                }
12490            }
12491            return false;
12492        } finally {
12493            Binder.restoreCallingIdentity(origId);
12494        }
12495    }
12496
12497    @Override
12498    public boolean isBackgroundVisibleBehind(IBinder token) {
12499        final long origId = Binder.clearCallingIdentity();
12500        try {
12501            synchronized (this) {
12502                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12503                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12504                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12505                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12506                return visible;
12507            }
12508        } finally {
12509            Binder.restoreCallingIdentity(origId);
12510        }
12511    }
12512
12513    @Override
12514    public ActivityOptions getActivityOptions(IBinder token) {
12515        final long origId = Binder.clearCallingIdentity();
12516        try {
12517            synchronized (this) {
12518                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12519                if (r != null) {
12520                    final ActivityOptions activityOptions = r.pendingOptions;
12521                    r.pendingOptions = null;
12522                    return activityOptions;
12523                }
12524                return null;
12525            }
12526        } finally {
12527            Binder.restoreCallingIdentity(origId);
12528        }
12529    }
12530
12531    @Override
12532    public void setImmersive(IBinder token, boolean immersive) {
12533        synchronized(this) {
12534            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12535            if (r == null) {
12536                throw new IllegalArgumentException();
12537            }
12538            r.immersive = immersive;
12539
12540            // update associated state if we're frontmost
12541            if (r == mFocusedActivity) {
12542                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12543                applyUpdateLockStateLocked(r);
12544            }
12545        }
12546    }
12547
12548    @Override
12549    public boolean isImmersive(IBinder token) {
12550        synchronized (this) {
12551            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12552            if (r == null) {
12553                throw new IllegalArgumentException();
12554            }
12555            return r.immersive;
12556        }
12557    }
12558
12559    public void setVrThread(int tid) {
12560        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12561            throw new UnsupportedOperationException("VR mode not supported on this device!");
12562        }
12563
12564        synchronized (this) {
12565            ProcessRecord proc;
12566            synchronized (mPidsSelfLocked) {
12567                final int pid = Binder.getCallingPid();
12568                proc = mPidsSelfLocked.get(pid);
12569                if (proc != null && mInVrMode && tid >= 0) {
12570                    // ensure the tid belongs to the process
12571                    if (!Process.isThreadInProcess(pid, tid)) {
12572                        throw new IllegalArgumentException("VR thread does not belong to process");
12573                    }
12574                    // reset existing VR thread to CFS
12575                    if (proc.vrThreadTid != 0) {
12576                        Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12577                    }
12578                    // add check to guarantee that tid belongs to pid?
12579                    proc.vrThreadTid = tid;
12580                    // promote to FIFO now if the tid is non-zero
12581                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && proc.vrThreadTid > 0) {
12582                        Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12583                    }
12584                } else {
12585                    //Slog.e("VR_FIFO", "Didn't set thread from setVrThread?");
12586                }
12587            }
12588        }
12589    }
12590
12591    @Override
12592    public void setRenderThread(int tid) {
12593        synchronized (this) {
12594            ProcessRecord proc;
12595            synchronized (mPidsSelfLocked) {
12596                int pid = Binder.getCallingPid();
12597                proc = mPidsSelfLocked.get(pid);
12598                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12599                    // ensure the tid belongs to the process
12600                    if (!Process.isThreadInProcess(pid, tid)) {
12601                        throw new IllegalArgumentException(
12602                            "Render thread does not belong to process");
12603                    }
12604                    proc.renderThreadTid = tid;
12605                    if (DEBUG_OOM_ADJ) {
12606                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12607                    }
12608                    // promote to FIFO now
12609                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12610                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12611                        if (mUseFifoUiScheduling) {
12612                            Process.setThreadScheduler(proc.renderThreadTid,
12613                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12614                        } else {
12615                            Process.setThreadPriority(proc.renderThreadTid, -10);
12616                        }
12617                    }
12618                } else {
12619                    if (DEBUG_OOM_ADJ) {
12620                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12621                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12622                               mUseFifoUiScheduling);
12623                    }
12624                }
12625            }
12626        }
12627    }
12628
12629    @Override
12630    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12631        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12632            throw new UnsupportedOperationException("VR mode not supported on this device!");
12633        }
12634
12635        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12636
12637        ActivityRecord r;
12638        synchronized (this) {
12639            r = ActivityRecord.isInStackLocked(token);
12640        }
12641
12642        if (r == null) {
12643            throw new IllegalArgumentException();
12644        }
12645
12646        int err;
12647        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12648                VrManagerInternal.NO_ERROR) {
12649            return err;
12650        }
12651
12652        synchronized(this) {
12653            r.requestedVrComponent = (enabled) ? packageName : null;
12654
12655            // Update associated state if this activity is currently focused
12656            if (r == mFocusedActivity) {
12657                applyUpdateVrModeLocked(r);
12658            }
12659            return 0;
12660        }
12661    }
12662
12663    @Override
12664    public boolean isVrModePackageEnabled(ComponentName packageName) {
12665        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12666            throw new UnsupportedOperationException("VR mode not supported on this device!");
12667        }
12668
12669        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12670
12671        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12672                VrManagerInternal.NO_ERROR;
12673    }
12674
12675    public boolean isTopActivityImmersive() {
12676        enforceNotIsolatedCaller("startActivity");
12677        synchronized (this) {
12678            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12679            return (r != null) ? r.immersive : false;
12680        }
12681    }
12682
12683    @Override
12684    public boolean isTopOfTask(IBinder token) {
12685        synchronized (this) {
12686            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12687            if (r == null) {
12688                throw new IllegalArgumentException();
12689            }
12690            return r.task.getTopActivity() == r;
12691        }
12692    }
12693
12694    @Override
12695    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12696        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12697            String msg = "Permission Denial: setHasTopUi() from pid="
12698                    + Binder.getCallingPid()
12699                    + ", uid=" + Binder.getCallingUid()
12700                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12701            Slog.w(TAG, msg);
12702            throw new SecurityException(msg);
12703        }
12704        final int pid = Binder.getCallingPid();
12705        final long origId = Binder.clearCallingIdentity();
12706        try {
12707            synchronized (this) {
12708                boolean changed = false;
12709                ProcessRecord pr;
12710                synchronized (mPidsSelfLocked) {
12711                    pr = mPidsSelfLocked.get(pid);
12712                    if (pr == null) {
12713                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12714                        return;
12715                    }
12716                    if (pr.hasTopUi != hasTopUi) {
12717                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12718                        pr.hasTopUi = hasTopUi;
12719                        changed = true;
12720                    }
12721                }
12722                if (changed) {
12723                    updateOomAdjLocked(pr);
12724                }
12725            }
12726        } finally {
12727            Binder.restoreCallingIdentity(origId);
12728        }
12729    }
12730
12731    public final void enterSafeMode() {
12732        synchronized(this) {
12733            // It only makes sense to do this before the system is ready
12734            // and started launching other packages.
12735            if (!mSystemReady) {
12736                try {
12737                    AppGlobals.getPackageManager().enterSafeMode();
12738                } catch (RemoteException e) {
12739                }
12740            }
12741
12742            mSafeMode = true;
12743        }
12744    }
12745
12746    public final void showSafeModeOverlay() {
12747        View v = LayoutInflater.from(mContext).inflate(
12748                com.android.internal.R.layout.safe_mode, null);
12749        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12750        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12751        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12752        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12753        lp.gravity = Gravity.BOTTOM | Gravity.START;
12754        lp.format = v.getBackground().getOpacity();
12755        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12756                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12757        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12758        ((WindowManager)mContext.getSystemService(
12759                Context.WINDOW_SERVICE)).addView(v, lp);
12760    }
12761
12762    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12763        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12764            return;
12765        }
12766        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12767        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12768        synchronized (stats) {
12769            if (mBatteryStatsService.isOnBattery()) {
12770                mBatteryStatsService.enforceCallingPermission();
12771                int MY_UID = Binder.getCallingUid();
12772                final int uid;
12773                if (sender == null) {
12774                    uid = sourceUid;
12775                } else {
12776                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12777                }
12778                BatteryStatsImpl.Uid.Pkg pkg =
12779                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12780                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12781                pkg.noteWakeupAlarmLocked(tag);
12782            }
12783        }
12784    }
12785
12786    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12787        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12788            return;
12789        }
12790        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12791        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12792        synchronized (stats) {
12793            mBatteryStatsService.enforceCallingPermission();
12794            int MY_UID = Binder.getCallingUid();
12795            final int uid;
12796            if (sender == null) {
12797                uid = sourceUid;
12798            } else {
12799                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12800            }
12801            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12802        }
12803    }
12804
12805    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12806        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12807            return;
12808        }
12809        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12810        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12811        synchronized (stats) {
12812            mBatteryStatsService.enforceCallingPermission();
12813            int MY_UID = Binder.getCallingUid();
12814            final int uid;
12815            if (sender == null) {
12816                uid = sourceUid;
12817            } else {
12818                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12819            }
12820            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12821        }
12822    }
12823
12824    public boolean killPids(int[] pids, String pReason, boolean secure) {
12825        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12826            throw new SecurityException("killPids only available to the system");
12827        }
12828        String reason = (pReason == null) ? "Unknown" : pReason;
12829        // XXX Note: don't acquire main activity lock here, because the window
12830        // manager calls in with its locks held.
12831
12832        boolean killed = false;
12833        synchronized (mPidsSelfLocked) {
12834            int worstType = 0;
12835            for (int i=0; i<pids.length; i++) {
12836                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12837                if (proc != null) {
12838                    int type = proc.setAdj;
12839                    if (type > worstType) {
12840                        worstType = type;
12841                    }
12842                }
12843            }
12844
12845            // If the worst oom_adj is somewhere in the cached proc LRU range,
12846            // then constrain it so we will kill all cached procs.
12847            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12848                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12849                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12850            }
12851
12852            // If this is not a secure call, don't let it kill processes that
12853            // are important.
12854            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12855                worstType = ProcessList.SERVICE_ADJ;
12856            }
12857
12858            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12859            for (int i=0; i<pids.length; i++) {
12860                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12861                if (proc == null) {
12862                    continue;
12863                }
12864                int adj = proc.setAdj;
12865                if (adj >= worstType && !proc.killedByAm) {
12866                    proc.kill(reason, true);
12867                    killed = true;
12868                }
12869            }
12870        }
12871        return killed;
12872    }
12873
12874    @Override
12875    public void killUid(int appId, int userId, String reason) {
12876        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12877        synchronized (this) {
12878            final long identity = Binder.clearCallingIdentity();
12879            try {
12880                killPackageProcessesLocked(null, appId, userId,
12881                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12882                        reason != null ? reason : "kill uid");
12883            } finally {
12884                Binder.restoreCallingIdentity(identity);
12885            }
12886        }
12887    }
12888
12889    @Override
12890    public boolean killProcessesBelowForeground(String reason) {
12891        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12892            throw new SecurityException("killProcessesBelowForeground() only available to system");
12893        }
12894
12895        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12896    }
12897
12898    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12899        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12900            throw new SecurityException("killProcessesBelowAdj() only available to system");
12901        }
12902
12903        boolean killed = false;
12904        synchronized (mPidsSelfLocked) {
12905            final int size = mPidsSelfLocked.size();
12906            for (int i = 0; i < size; i++) {
12907                final int pid = mPidsSelfLocked.keyAt(i);
12908                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12909                if (proc == null) continue;
12910
12911                final int adj = proc.setAdj;
12912                if (adj > belowAdj && !proc.killedByAm) {
12913                    proc.kill(reason, true);
12914                    killed = true;
12915                }
12916            }
12917        }
12918        return killed;
12919    }
12920
12921    @Override
12922    public void hang(final IBinder who, boolean allowRestart) {
12923        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12924                != PackageManager.PERMISSION_GRANTED) {
12925            throw new SecurityException("Requires permission "
12926                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12927        }
12928
12929        final IBinder.DeathRecipient death = new DeathRecipient() {
12930            @Override
12931            public void binderDied() {
12932                synchronized (this) {
12933                    notifyAll();
12934                }
12935            }
12936        };
12937
12938        try {
12939            who.linkToDeath(death, 0);
12940        } catch (RemoteException e) {
12941            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12942            return;
12943        }
12944
12945        synchronized (this) {
12946            Watchdog.getInstance().setAllowRestart(allowRestart);
12947            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12948            synchronized (death) {
12949                while (who.isBinderAlive()) {
12950                    try {
12951                        death.wait();
12952                    } catch (InterruptedException e) {
12953                    }
12954                }
12955            }
12956            Watchdog.getInstance().setAllowRestart(true);
12957        }
12958    }
12959
12960    @Override
12961    public void restart() {
12962        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12963                != PackageManager.PERMISSION_GRANTED) {
12964            throw new SecurityException("Requires permission "
12965                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12966        }
12967
12968        Log.i(TAG, "Sending shutdown broadcast...");
12969
12970        BroadcastReceiver br = new BroadcastReceiver() {
12971            @Override public void onReceive(Context context, Intent intent) {
12972                // Now the broadcast is done, finish up the low-level shutdown.
12973                Log.i(TAG, "Shutting down activity manager...");
12974                shutdown(10000);
12975                Log.i(TAG, "Shutdown complete, restarting!");
12976                Process.killProcess(Process.myPid());
12977                System.exit(10);
12978            }
12979        };
12980
12981        // First send the high-level shut down broadcast.
12982        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12983        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12984        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12985        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12986        mContext.sendOrderedBroadcastAsUser(intent,
12987                UserHandle.ALL, null, br, mHandler, 0, null, null);
12988        */
12989        br.onReceive(mContext, intent);
12990    }
12991
12992    private long getLowRamTimeSinceIdle(long now) {
12993        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12994    }
12995
12996    @Override
12997    public void performIdleMaintenance() {
12998        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12999                != PackageManager.PERMISSION_GRANTED) {
13000            throw new SecurityException("Requires permission "
13001                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13002        }
13003
13004        synchronized (this) {
13005            final long now = SystemClock.uptimeMillis();
13006            final long timeSinceLastIdle = now - mLastIdleTime;
13007            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13008            mLastIdleTime = now;
13009            mLowRamTimeSinceLastIdle = 0;
13010            if (mLowRamStartTime != 0) {
13011                mLowRamStartTime = now;
13012            }
13013
13014            StringBuilder sb = new StringBuilder(128);
13015            sb.append("Idle maintenance over ");
13016            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13017            sb.append(" low RAM for ");
13018            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13019            Slog.i(TAG, sb.toString());
13020
13021            // If at least 1/3 of our time since the last idle period has been spent
13022            // with RAM low, then we want to kill processes.
13023            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13024
13025            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13026                ProcessRecord proc = mLruProcesses.get(i);
13027                if (proc.notCachedSinceIdle) {
13028                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13029                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13030                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13031                        if (doKilling && proc.initialIdlePss != 0
13032                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13033                            sb = new StringBuilder(128);
13034                            sb.append("Kill");
13035                            sb.append(proc.processName);
13036                            sb.append(" in idle maint: pss=");
13037                            sb.append(proc.lastPss);
13038                            sb.append(", swapPss=");
13039                            sb.append(proc.lastSwapPss);
13040                            sb.append(", initialPss=");
13041                            sb.append(proc.initialIdlePss);
13042                            sb.append(", period=");
13043                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13044                            sb.append(", lowRamPeriod=");
13045                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13046                            Slog.wtfQuiet(TAG, sb.toString());
13047                            proc.kill("idle maint (pss " + proc.lastPss
13048                                    + " from " + proc.initialIdlePss + ")", true);
13049                        }
13050                    }
13051                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13052                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13053                    proc.notCachedSinceIdle = true;
13054                    proc.initialIdlePss = 0;
13055                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13056                            mTestPssMode, isSleepingLocked(), now);
13057                }
13058            }
13059
13060            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13061            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13062        }
13063    }
13064
13065    @Override
13066    public void sendIdleJobTrigger() {
13067        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13068                != PackageManager.PERMISSION_GRANTED) {
13069            throw new SecurityException("Requires permission "
13070                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13071        }
13072
13073        final long ident = Binder.clearCallingIdentity();
13074        try {
13075            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13076                    .setPackage("android")
13077                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13078            broadcastIntent(null, intent, null, null, 0, null, null, null,
13079                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13080        } finally {
13081            Binder.restoreCallingIdentity(ident);
13082        }
13083    }
13084
13085    private void retrieveSettings() {
13086        final ContentResolver resolver = mContext.getContentResolver();
13087        final boolean freeformWindowManagement =
13088                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13089                        || Settings.Global.getInt(
13090                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13091        final boolean supportsPictureInPicture =
13092                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13093
13094        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13095        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13096        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13097        final boolean alwaysFinishActivities =
13098                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13099        final boolean lenientBackgroundCheck =
13100                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13101        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13102        final boolean forceResizable = Settings.Global.getInt(
13103                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13104        final boolean supportsLeanbackOnly =
13105                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13106
13107        // Transfer any global setting for forcing RTL layout, into a System Property
13108        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13109
13110        final Configuration configuration = new Configuration();
13111        Settings.System.getConfiguration(resolver, configuration);
13112        if (forceRtl) {
13113            // This will take care of setting the correct layout direction flags
13114            configuration.setLayoutDirection(configuration.locale);
13115        }
13116
13117        synchronized (this) {
13118            mDebugApp = mOrigDebugApp = debugApp;
13119            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13120            mAlwaysFinishActivities = alwaysFinishActivities;
13121            mLenientBackgroundCheck = lenientBackgroundCheck;
13122            mSupportsLeanbackOnly = supportsLeanbackOnly;
13123            mForceResizableActivities = forceResizable;
13124            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13125            if (supportsMultiWindow || forceResizable) {
13126                mSupportsMultiWindow = true;
13127                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13128                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13129            } else {
13130                mSupportsMultiWindow = false;
13131                mSupportsFreeformWindowManagement = false;
13132                mSupportsPictureInPicture = false;
13133            }
13134            // This happens before any activities are started, so we can
13135            // change mConfiguration in-place.
13136            updateConfigurationLocked(configuration, null, true);
13137            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13138                    "Initial config: " + mConfiguration);
13139
13140            // Load resources only after the current configuration has been set.
13141            final Resources res = mContext.getResources();
13142            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13143            mThumbnailWidth = res.getDimensionPixelSize(
13144                    com.android.internal.R.dimen.thumbnail_width);
13145            mThumbnailHeight = res.getDimensionPixelSize(
13146                    com.android.internal.R.dimen.thumbnail_height);
13147            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13148                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13149            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13150                    com.android.internal.R.string.config_appsNotReportingCrashes));
13151            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13152                mFullscreenThumbnailScale = (float) res
13153                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13154                    (float) mConfiguration.screenWidthDp;
13155            } else {
13156                mFullscreenThumbnailScale = res.getFraction(
13157                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13158            }
13159        }
13160    }
13161
13162    public boolean testIsSystemReady() {
13163        // no need to synchronize(this) just to read & return the value
13164        return mSystemReady;
13165    }
13166
13167    public void systemReady(final Runnable goingCallback) {
13168        synchronized(this) {
13169            if (mSystemReady) {
13170                // If we're done calling all the receivers, run the next "boot phase" passed in
13171                // by the SystemServer
13172                if (goingCallback != null) {
13173                    goingCallback.run();
13174                }
13175                return;
13176            }
13177
13178            mLocalDeviceIdleController
13179                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13180
13181            // Make sure we have the current profile info, since it is needed for security checks.
13182            mUserController.onSystemReady();
13183            mRecentTasks.onSystemReadyLocked();
13184            mAppOpsService.systemReady();
13185            mSystemReady = true;
13186        }
13187
13188        ArrayList<ProcessRecord> procsToKill = null;
13189        synchronized(mPidsSelfLocked) {
13190            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13191                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13192                if (!isAllowedWhileBooting(proc.info)){
13193                    if (procsToKill == null) {
13194                        procsToKill = new ArrayList<ProcessRecord>();
13195                    }
13196                    procsToKill.add(proc);
13197                }
13198            }
13199        }
13200
13201        synchronized(this) {
13202            if (procsToKill != null) {
13203                for (int i=procsToKill.size()-1; i>=0; i--) {
13204                    ProcessRecord proc = procsToKill.get(i);
13205                    Slog.i(TAG, "Removing system update proc: " + proc);
13206                    removeProcessLocked(proc, true, false, "system update done");
13207                }
13208            }
13209
13210            // Now that we have cleaned up any update processes, we
13211            // are ready to start launching real processes and know that
13212            // we won't trample on them any more.
13213            mProcessesReady = true;
13214        }
13215
13216        Slog.i(TAG, "System now ready");
13217        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13218            SystemClock.uptimeMillis());
13219
13220        synchronized(this) {
13221            // Make sure we have no pre-ready processes sitting around.
13222
13223            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13224                ResolveInfo ri = mContext.getPackageManager()
13225                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13226                                STOCK_PM_FLAGS);
13227                CharSequence errorMsg = null;
13228                if (ri != null) {
13229                    ActivityInfo ai = ri.activityInfo;
13230                    ApplicationInfo app = ai.applicationInfo;
13231                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13232                        mTopAction = Intent.ACTION_FACTORY_TEST;
13233                        mTopData = null;
13234                        mTopComponent = new ComponentName(app.packageName,
13235                                ai.name);
13236                    } else {
13237                        errorMsg = mContext.getResources().getText(
13238                                com.android.internal.R.string.factorytest_not_system);
13239                    }
13240                } else {
13241                    errorMsg = mContext.getResources().getText(
13242                            com.android.internal.R.string.factorytest_no_action);
13243                }
13244                if (errorMsg != null) {
13245                    mTopAction = null;
13246                    mTopData = null;
13247                    mTopComponent = null;
13248                    Message msg = Message.obtain();
13249                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13250                    msg.getData().putCharSequence("msg", errorMsg);
13251                    mUiHandler.sendMessage(msg);
13252                }
13253            }
13254        }
13255
13256        retrieveSettings();
13257        final int currentUserId;
13258        synchronized (this) {
13259            currentUserId = mUserController.getCurrentUserIdLocked();
13260            readGrantedUriPermissionsLocked();
13261        }
13262
13263        if (goingCallback != null) goingCallback.run();
13264
13265        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13266                Integer.toString(currentUserId), currentUserId);
13267        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13268                Integer.toString(currentUserId), currentUserId);
13269        mSystemServiceManager.startUser(currentUserId);
13270
13271        synchronized (this) {
13272            // Only start up encryption-aware persistent apps; once user is
13273            // unlocked we'll come back around and start unaware apps
13274            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13275
13276            // Start up initial activity.
13277            mBooting = true;
13278            // Enable home activity for system user, so that the system can always boot
13279            if (UserManager.isSplitSystemUser()) {
13280                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13281                try {
13282                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13283                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13284                            UserHandle.USER_SYSTEM);
13285                } catch (RemoteException e) {
13286                    throw e.rethrowAsRuntimeException();
13287                }
13288            }
13289            startHomeActivityLocked(currentUserId, "systemReady");
13290
13291            try {
13292                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13293                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13294                            + " data partition or your device will be unstable.");
13295                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13296                }
13297            } catch (RemoteException e) {
13298            }
13299
13300            if (!Build.isBuildConsistent()) {
13301                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13302                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13303            }
13304
13305            long ident = Binder.clearCallingIdentity();
13306            try {
13307                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13308                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13309                        | Intent.FLAG_RECEIVER_FOREGROUND);
13310                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13311                broadcastIntentLocked(null, null, intent,
13312                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13313                        null, false, false, MY_PID, Process.SYSTEM_UID,
13314                        currentUserId);
13315                intent = new Intent(Intent.ACTION_USER_STARTING);
13316                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13317                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13318                broadcastIntentLocked(null, null, intent,
13319                        null, new IIntentReceiver.Stub() {
13320                            @Override
13321                            public void performReceive(Intent intent, int resultCode, String data,
13322                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13323                                    throws RemoteException {
13324                            }
13325                        }, 0, null, null,
13326                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13327                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13328            } catch (Throwable t) {
13329                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13330            } finally {
13331                Binder.restoreCallingIdentity(ident);
13332            }
13333            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13334            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13335        }
13336    }
13337
13338    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13339        synchronized (this) {
13340            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13341        }
13342    }
13343
13344    void skipCurrentReceiverLocked(ProcessRecord app) {
13345        for (BroadcastQueue queue : mBroadcastQueues) {
13346            queue.skipCurrentReceiverLocked(app);
13347        }
13348    }
13349
13350    /**
13351     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13352     * The application process will exit immediately after this call returns.
13353     * @param app object of the crashing app, null for the system server
13354     * @param crashInfo describing the exception
13355     */
13356    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13357        ProcessRecord r = findAppProcess(app, "Crash");
13358        final String processName = app == null ? "system_server"
13359                : (r == null ? "unknown" : r.processName);
13360
13361        handleApplicationCrashInner("crash", r, processName, crashInfo);
13362    }
13363
13364    /* Native crash reporting uses this inner version because it needs to be somewhat
13365     * decoupled from the AM-managed cleanup lifecycle
13366     */
13367    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13368            ApplicationErrorReport.CrashInfo crashInfo) {
13369        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13370                UserHandle.getUserId(Binder.getCallingUid()), processName,
13371                r == null ? -1 : r.info.flags,
13372                crashInfo.exceptionClassName,
13373                crashInfo.exceptionMessage,
13374                crashInfo.throwFileName,
13375                crashInfo.throwLineNumber);
13376
13377        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13378
13379        mAppErrors.crashApplication(r, crashInfo);
13380    }
13381
13382    public void handleApplicationStrictModeViolation(
13383            IBinder app,
13384            int violationMask,
13385            StrictMode.ViolationInfo info) {
13386        ProcessRecord r = findAppProcess(app, "StrictMode");
13387        if (r == null) {
13388            return;
13389        }
13390
13391        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13392            Integer stackFingerprint = info.hashCode();
13393            boolean logIt = true;
13394            synchronized (mAlreadyLoggedViolatedStacks) {
13395                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13396                    logIt = false;
13397                    // TODO: sub-sample into EventLog for these, with
13398                    // the info.durationMillis?  Then we'd get
13399                    // the relative pain numbers, without logging all
13400                    // the stack traces repeatedly.  We'd want to do
13401                    // likewise in the client code, which also does
13402                    // dup suppression, before the Binder call.
13403                } else {
13404                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13405                        mAlreadyLoggedViolatedStacks.clear();
13406                    }
13407                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13408                }
13409            }
13410            if (logIt) {
13411                logStrictModeViolationToDropBox(r, info);
13412            }
13413        }
13414
13415        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13416            AppErrorResult result = new AppErrorResult();
13417            synchronized (this) {
13418                final long origId = Binder.clearCallingIdentity();
13419
13420                Message msg = Message.obtain();
13421                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13422                HashMap<String, Object> data = new HashMap<String, Object>();
13423                data.put("result", result);
13424                data.put("app", r);
13425                data.put("violationMask", violationMask);
13426                data.put("info", info);
13427                msg.obj = data;
13428                mUiHandler.sendMessage(msg);
13429
13430                Binder.restoreCallingIdentity(origId);
13431            }
13432            int res = result.get();
13433            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13434        }
13435    }
13436
13437    // Depending on the policy in effect, there could be a bunch of
13438    // these in quick succession so we try to batch these together to
13439    // minimize disk writes, number of dropbox entries, and maximize
13440    // compression, by having more fewer, larger records.
13441    private void logStrictModeViolationToDropBox(
13442            ProcessRecord process,
13443            StrictMode.ViolationInfo info) {
13444        if (info == null) {
13445            return;
13446        }
13447        final boolean isSystemApp = process == null ||
13448                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13449                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13450        final String processName = process == null ? "unknown" : process.processName;
13451        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13452        final DropBoxManager dbox = (DropBoxManager)
13453                mContext.getSystemService(Context.DROPBOX_SERVICE);
13454
13455        // Exit early if the dropbox isn't configured to accept this report type.
13456        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13457
13458        boolean bufferWasEmpty;
13459        boolean needsFlush;
13460        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13461        synchronized (sb) {
13462            bufferWasEmpty = sb.length() == 0;
13463            appendDropBoxProcessHeaders(process, processName, sb);
13464            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13465            sb.append("System-App: ").append(isSystemApp).append("\n");
13466            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13467            if (info.violationNumThisLoop != 0) {
13468                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13469            }
13470            if (info.numAnimationsRunning != 0) {
13471                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13472            }
13473            if (info.broadcastIntentAction != null) {
13474                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13475            }
13476            if (info.durationMillis != -1) {
13477                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13478            }
13479            if (info.numInstances != -1) {
13480                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13481            }
13482            if (info.tags != null) {
13483                for (String tag : info.tags) {
13484                    sb.append("Span-Tag: ").append(tag).append("\n");
13485                }
13486            }
13487            sb.append("\n");
13488            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13489                sb.append(info.crashInfo.stackTrace);
13490                sb.append("\n");
13491            }
13492            if (info.message != null) {
13493                sb.append(info.message);
13494                sb.append("\n");
13495            }
13496
13497            // Only buffer up to ~64k.  Various logging bits truncate
13498            // things at 128k.
13499            needsFlush = (sb.length() > 64 * 1024);
13500        }
13501
13502        // Flush immediately if the buffer's grown too large, or this
13503        // is a non-system app.  Non-system apps are isolated with a
13504        // different tag & policy and not batched.
13505        //
13506        // Batching is useful during internal testing with
13507        // StrictMode settings turned up high.  Without batching,
13508        // thousands of separate files could be created on boot.
13509        if (!isSystemApp || needsFlush) {
13510            new Thread("Error dump: " + dropboxTag) {
13511                @Override
13512                public void run() {
13513                    String report;
13514                    synchronized (sb) {
13515                        report = sb.toString();
13516                        sb.delete(0, sb.length());
13517                        sb.trimToSize();
13518                    }
13519                    if (report.length() != 0) {
13520                        dbox.addText(dropboxTag, report);
13521                    }
13522                }
13523            }.start();
13524            return;
13525        }
13526
13527        // System app batching:
13528        if (!bufferWasEmpty) {
13529            // An existing dropbox-writing thread is outstanding, so
13530            // we don't need to start it up.  The existing thread will
13531            // catch the buffer appends we just did.
13532            return;
13533        }
13534
13535        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13536        // (After this point, we shouldn't access AMS internal data structures.)
13537        new Thread("Error dump: " + dropboxTag) {
13538            @Override
13539            public void run() {
13540                // 5 second sleep to let stacks arrive and be batched together
13541                try {
13542                    Thread.sleep(5000);  // 5 seconds
13543                } catch (InterruptedException e) {}
13544
13545                String errorReport;
13546                synchronized (mStrictModeBuffer) {
13547                    errorReport = mStrictModeBuffer.toString();
13548                    if (errorReport.length() == 0) {
13549                        return;
13550                    }
13551                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13552                    mStrictModeBuffer.trimToSize();
13553                }
13554                dbox.addText(dropboxTag, errorReport);
13555            }
13556        }.start();
13557    }
13558
13559    /**
13560     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13561     * @param app object of the crashing app, null for the system server
13562     * @param tag reported by the caller
13563     * @param system whether this wtf is coming from the system
13564     * @param crashInfo describing the context of the error
13565     * @return true if the process should exit immediately (WTF is fatal)
13566     */
13567    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13568            final ApplicationErrorReport.CrashInfo crashInfo) {
13569        final int callingUid = Binder.getCallingUid();
13570        final int callingPid = Binder.getCallingPid();
13571
13572        if (system) {
13573            // If this is coming from the system, we could very well have low-level
13574            // system locks held, so we want to do this all asynchronously.  And we
13575            // never want this to become fatal, so there is that too.
13576            mHandler.post(new Runnable() {
13577                @Override public void run() {
13578                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13579                }
13580            });
13581            return false;
13582        }
13583
13584        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13585                crashInfo);
13586
13587        if (r != null && r.pid != Process.myPid() &&
13588                Settings.Global.getInt(mContext.getContentResolver(),
13589                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13590            mAppErrors.crashApplication(r, crashInfo);
13591            return true;
13592        } else {
13593            return false;
13594        }
13595    }
13596
13597    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13598            final ApplicationErrorReport.CrashInfo crashInfo) {
13599        final ProcessRecord r = findAppProcess(app, "WTF");
13600        final String processName = app == null ? "system_server"
13601                : (r == null ? "unknown" : r.processName);
13602
13603        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13604                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13605
13606        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13607
13608        return r;
13609    }
13610
13611    /**
13612     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13613     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13614     */
13615    private ProcessRecord findAppProcess(IBinder app, String reason) {
13616        if (app == null) {
13617            return null;
13618        }
13619
13620        synchronized (this) {
13621            final int NP = mProcessNames.getMap().size();
13622            for (int ip=0; ip<NP; ip++) {
13623                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13624                final int NA = apps.size();
13625                for (int ia=0; ia<NA; ia++) {
13626                    ProcessRecord p = apps.valueAt(ia);
13627                    if (p.thread != null && p.thread.asBinder() == app) {
13628                        return p;
13629                    }
13630                }
13631            }
13632
13633            Slog.w(TAG, "Can't find mystery application for " + reason
13634                    + " from pid=" + Binder.getCallingPid()
13635                    + " uid=" + Binder.getCallingUid() + ": " + app);
13636            return null;
13637        }
13638    }
13639
13640    /**
13641     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13642     * to append various headers to the dropbox log text.
13643     */
13644    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13645            StringBuilder sb) {
13646        // Watchdog thread ends up invoking this function (with
13647        // a null ProcessRecord) to add the stack file to dropbox.
13648        // Do not acquire a lock on this (am) in such cases, as it
13649        // could cause a potential deadlock, if and when watchdog
13650        // is invoked due to unavailability of lock on am and it
13651        // would prevent watchdog from killing system_server.
13652        if (process == null) {
13653            sb.append("Process: ").append(processName).append("\n");
13654            return;
13655        }
13656        // Note: ProcessRecord 'process' is guarded by the service
13657        // instance.  (notably process.pkgList, which could otherwise change
13658        // concurrently during execution of this method)
13659        synchronized (this) {
13660            sb.append("Process: ").append(processName).append("\n");
13661            int flags = process.info.flags;
13662            IPackageManager pm = AppGlobals.getPackageManager();
13663            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13664            for (int ip=0; ip<process.pkgList.size(); ip++) {
13665                String pkg = process.pkgList.keyAt(ip);
13666                sb.append("Package: ").append(pkg);
13667                try {
13668                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13669                    if (pi != null) {
13670                        sb.append(" v").append(pi.versionCode);
13671                        if (pi.versionName != null) {
13672                            sb.append(" (").append(pi.versionName).append(")");
13673                        }
13674                    }
13675                } catch (RemoteException e) {
13676                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13677                }
13678                sb.append("\n");
13679            }
13680        }
13681    }
13682
13683    private static String processClass(ProcessRecord process) {
13684        if (process == null || process.pid == MY_PID) {
13685            return "system_server";
13686        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13687            return "system_app";
13688        } else {
13689            return "data_app";
13690        }
13691    }
13692
13693    private volatile long mWtfClusterStart;
13694    private volatile int mWtfClusterCount;
13695
13696    /**
13697     * Write a description of an error (crash, WTF, ANR) to the drop box.
13698     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13699     * @param process which caused the error, null means the system server
13700     * @param activity which triggered the error, null if unknown
13701     * @param parent activity related to the error, null if unknown
13702     * @param subject line related to the error, null if absent
13703     * @param report in long form describing the error, null if absent
13704     * @param dataFile text file to include in the report, null if none
13705     * @param crashInfo giving an application stack trace, null if absent
13706     */
13707    public void addErrorToDropBox(String eventType,
13708            ProcessRecord process, String processName, ActivityRecord activity,
13709            ActivityRecord parent, String subject,
13710            final String report, final File dataFile,
13711            final ApplicationErrorReport.CrashInfo crashInfo) {
13712        // NOTE -- this must never acquire the ActivityManagerService lock,
13713        // otherwise the watchdog may be prevented from resetting the system.
13714
13715        final String dropboxTag = processClass(process) + "_" + eventType;
13716        final DropBoxManager dbox = (DropBoxManager)
13717                mContext.getSystemService(Context.DROPBOX_SERVICE);
13718
13719        // Exit early if the dropbox isn't configured to accept this report type.
13720        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13721
13722        // Rate-limit how often we're willing to do the heavy lifting below to
13723        // collect and record logs; currently 5 logs per 10 second period.
13724        final long now = SystemClock.elapsedRealtime();
13725        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13726            mWtfClusterStart = now;
13727            mWtfClusterCount = 1;
13728        } else {
13729            if (mWtfClusterCount++ >= 5) return;
13730        }
13731
13732        final StringBuilder sb = new StringBuilder(1024);
13733        appendDropBoxProcessHeaders(process, processName, sb);
13734        if (process != null) {
13735            sb.append("Foreground: ")
13736                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13737                    .append("\n");
13738        }
13739        if (activity != null) {
13740            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13741        }
13742        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13743            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13744        }
13745        if (parent != null && parent != activity) {
13746            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13747        }
13748        if (subject != null) {
13749            sb.append("Subject: ").append(subject).append("\n");
13750        }
13751        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13752        if (Debug.isDebuggerConnected()) {
13753            sb.append("Debugger: Connected\n");
13754        }
13755        sb.append("\n");
13756
13757        // Do the rest in a worker thread to avoid blocking the caller on I/O
13758        // (After this point, we shouldn't access AMS internal data structures.)
13759        Thread worker = new Thread("Error dump: " + dropboxTag) {
13760            @Override
13761            public void run() {
13762                if (report != null) {
13763                    sb.append(report);
13764                }
13765
13766                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13767                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13768                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13769                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13770
13771                if (dataFile != null && maxDataFileSize > 0) {
13772                    try {
13773                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13774                                    "\n\n[[TRUNCATED]]"));
13775                    } catch (IOException e) {
13776                        Slog.e(TAG, "Error reading " + dataFile, e);
13777                    }
13778                }
13779                if (crashInfo != null && crashInfo.stackTrace != null) {
13780                    sb.append(crashInfo.stackTrace);
13781                }
13782
13783                if (lines > 0) {
13784                    sb.append("\n");
13785
13786                    // Merge several logcat streams, and take the last N lines
13787                    InputStreamReader input = null;
13788                    try {
13789                        java.lang.Process logcat = new ProcessBuilder(
13790                                "/system/bin/timeout", "-k", "15s", "10s",
13791                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13792                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13793                                        .redirectErrorStream(true).start();
13794
13795                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13796                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13797                        input = new InputStreamReader(logcat.getInputStream());
13798
13799                        int num;
13800                        char[] buf = new char[8192];
13801                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13802                    } catch (IOException e) {
13803                        Slog.e(TAG, "Error running logcat", e);
13804                    } finally {
13805                        if (input != null) try { input.close(); } catch (IOException e) {}
13806                    }
13807                }
13808
13809                dbox.addText(dropboxTag, sb.toString());
13810            }
13811        };
13812
13813        if (process == null) {
13814            // If process is null, we are being called from some internal code
13815            // and may be about to die -- run this synchronously.
13816            worker.run();
13817        } else {
13818            worker.start();
13819        }
13820    }
13821
13822    @Override
13823    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13824        enforceNotIsolatedCaller("getProcessesInErrorState");
13825        // assume our apps are happy - lazy create the list
13826        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13827
13828        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13829                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13830        int userId = UserHandle.getUserId(Binder.getCallingUid());
13831
13832        synchronized (this) {
13833
13834            // iterate across all processes
13835            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13836                ProcessRecord app = mLruProcesses.get(i);
13837                if (!allUsers && app.userId != userId) {
13838                    continue;
13839                }
13840                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13841                    // This one's in trouble, so we'll generate a report for it
13842                    // crashes are higher priority (in case there's a crash *and* an anr)
13843                    ActivityManager.ProcessErrorStateInfo report = null;
13844                    if (app.crashing) {
13845                        report = app.crashingReport;
13846                    } else if (app.notResponding) {
13847                        report = app.notRespondingReport;
13848                    }
13849
13850                    if (report != null) {
13851                        if (errList == null) {
13852                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13853                        }
13854                        errList.add(report);
13855                    } else {
13856                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13857                                " crashing = " + app.crashing +
13858                                " notResponding = " + app.notResponding);
13859                    }
13860                }
13861            }
13862        }
13863
13864        return errList;
13865    }
13866
13867    static int procStateToImportance(int procState, int memAdj,
13868            ActivityManager.RunningAppProcessInfo currApp) {
13869        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13870        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13871            currApp.lru = memAdj;
13872        } else {
13873            currApp.lru = 0;
13874        }
13875        return imp;
13876    }
13877
13878    private void fillInProcMemInfo(ProcessRecord app,
13879            ActivityManager.RunningAppProcessInfo outInfo) {
13880        outInfo.pid = app.pid;
13881        outInfo.uid = app.info.uid;
13882        if (mHeavyWeightProcess == app) {
13883            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13884        }
13885        if (app.persistent) {
13886            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13887        }
13888        if (app.activities.size() > 0) {
13889            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13890        }
13891        outInfo.lastTrimLevel = app.trimMemoryLevel;
13892        int adj = app.curAdj;
13893        int procState = app.curProcState;
13894        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13895        outInfo.importanceReasonCode = app.adjTypeCode;
13896        outInfo.processState = app.curProcState;
13897    }
13898
13899    @Override
13900    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13901        enforceNotIsolatedCaller("getRunningAppProcesses");
13902
13903        final int callingUid = Binder.getCallingUid();
13904
13905        // Lazy instantiation of list
13906        List<ActivityManager.RunningAppProcessInfo> runList = null;
13907        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13908                callingUid) == PackageManager.PERMISSION_GRANTED;
13909        final int userId = UserHandle.getUserId(callingUid);
13910        final boolean allUids = isGetTasksAllowed(
13911                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13912
13913        synchronized (this) {
13914            // Iterate across all processes
13915            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13916                ProcessRecord app = mLruProcesses.get(i);
13917                if ((!allUsers && app.userId != userId)
13918                        || (!allUids && app.uid != callingUid)) {
13919                    continue;
13920                }
13921                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13922                    // Generate process state info for running application
13923                    ActivityManager.RunningAppProcessInfo currApp =
13924                        new ActivityManager.RunningAppProcessInfo(app.processName,
13925                                app.pid, app.getPackageList());
13926                    fillInProcMemInfo(app, currApp);
13927                    if (app.adjSource instanceof ProcessRecord) {
13928                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13929                        currApp.importanceReasonImportance =
13930                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13931                                        app.adjSourceProcState);
13932                    } else if (app.adjSource instanceof ActivityRecord) {
13933                        ActivityRecord r = (ActivityRecord)app.adjSource;
13934                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13935                    }
13936                    if (app.adjTarget instanceof ComponentName) {
13937                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13938                    }
13939                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13940                    //        + " lru=" + currApp.lru);
13941                    if (runList == null) {
13942                        runList = new ArrayList<>();
13943                    }
13944                    runList.add(currApp);
13945                }
13946            }
13947        }
13948        return runList;
13949    }
13950
13951    @Override
13952    public List<ApplicationInfo> getRunningExternalApplications() {
13953        enforceNotIsolatedCaller("getRunningExternalApplications");
13954        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13955        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13956        if (runningApps != null && runningApps.size() > 0) {
13957            Set<String> extList = new HashSet<String>();
13958            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13959                if (app.pkgList != null) {
13960                    for (String pkg : app.pkgList) {
13961                        extList.add(pkg);
13962                    }
13963                }
13964            }
13965            IPackageManager pm = AppGlobals.getPackageManager();
13966            for (String pkg : extList) {
13967                try {
13968                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13969                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13970                        retList.add(info);
13971                    }
13972                } catch (RemoteException e) {
13973                }
13974            }
13975        }
13976        return retList;
13977    }
13978
13979    @Override
13980    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13981        enforceNotIsolatedCaller("getMyMemoryState");
13982        synchronized (this) {
13983            ProcessRecord proc;
13984            synchronized (mPidsSelfLocked) {
13985                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13986            }
13987            fillInProcMemInfo(proc, outInfo);
13988        }
13989    }
13990
13991    @Override
13992    public int getMemoryTrimLevel() {
13993        enforceNotIsolatedCaller("getMyMemoryState");
13994        synchronized (this) {
13995            return mLastMemoryLevel;
13996        }
13997    }
13998
13999    @Override
14000    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14001            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14002        (new ActivityManagerShellCommand(this, false)).exec(
14003                this, in, out, err, args, resultReceiver);
14004    }
14005
14006    @Override
14007    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14008        if (checkCallingPermission(android.Manifest.permission.DUMP)
14009                != PackageManager.PERMISSION_GRANTED) {
14010            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14011                    + Binder.getCallingPid()
14012                    + ", uid=" + Binder.getCallingUid()
14013                    + " without permission "
14014                    + android.Manifest.permission.DUMP);
14015            return;
14016        }
14017
14018        boolean dumpAll = false;
14019        boolean dumpClient = false;
14020        boolean dumpCheckin = false;
14021        boolean dumpCheckinFormat = false;
14022        String dumpPackage = null;
14023
14024        int opti = 0;
14025        while (opti < args.length) {
14026            String opt = args[opti];
14027            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14028                break;
14029            }
14030            opti++;
14031            if ("-a".equals(opt)) {
14032                dumpAll = true;
14033            } else if ("-c".equals(opt)) {
14034                dumpClient = true;
14035            } else if ("-p".equals(opt)) {
14036                if (opti < args.length) {
14037                    dumpPackage = args[opti];
14038                    opti++;
14039                } else {
14040                    pw.println("Error: -p option requires package argument");
14041                    return;
14042                }
14043                dumpClient = true;
14044            } else if ("--checkin".equals(opt)) {
14045                dumpCheckin = dumpCheckinFormat = true;
14046            } else if ("-C".equals(opt)) {
14047                dumpCheckinFormat = true;
14048            } else if ("-h".equals(opt)) {
14049                ActivityManagerShellCommand.dumpHelp(pw, true);
14050                return;
14051            } else {
14052                pw.println("Unknown argument: " + opt + "; use -h for help");
14053            }
14054        }
14055
14056        long origId = Binder.clearCallingIdentity();
14057        boolean more = false;
14058        // Is the caller requesting to dump a particular piece of data?
14059        if (opti < args.length) {
14060            String cmd = args[opti];
14061            opti++;
14062            if ("activities".equals(cmd) || "a".equals(cmd)) {
14063                synchronized (this) {
14064                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14065                }
14066            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14067                synchronized (this) {
14068                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14069                }
14070            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14071                String[] newArgs;
14072                String name;
14073                if (opti >= args.length) {
14074                    name = null;
14075                    newArgs = EMPTY_STRING_ARRAY;
14076                } else {
14077                    dumpPackage = args[opti];
14078                    opti++;
14079                    newArgs = new String[args.length - opti];
14080                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14081                            args.length - opti);
14082                }
14083                synchronized (this) {
14084                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14085                }
14086            } else if ("broadcast-stats".equals(cmd)) {
14087                String[] newArgs;
14088                String name;
14089                if (opti >= args.length) {
14090                    name = null;
14091                    newArgs = EMPTY_STRING_ARRAY;
14092                } else {
14093                    dumpPackage = args[opti];
14094                    opti++;
14095                    newArgs = new String[args.length - opti];
14096                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14097                            args.length - opti);
14098                }
14099                synchronized (this) {
14100                    if (dumpCheckinFormat) {
14101                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14102                                dumpPackage);
14103                    } else {
14104                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14105                    }
14106                }
14107            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14108                String[] newArgs;
14109                String name;
14110                if (opti >= args.length) {
14111                    name = null;
14112                    newArgs = EMPTY_STRING_ARRAY;
14113                } else {
14114                    dumpPackage = args[opti];
14115                    opti++;
14116                    newArgs = new String[args.length - opti];
14117                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14118                            args.length - opti);
14119                }
14120                synchronized (this) {
14121                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14122                }
14123            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14124                String[] newArgs;
14125                String name;
14126                if (opti >= args.length) {
14127                    name = null;
14128                    newArgs = EMPTY_STRING_ARRAY;
14129                } else {
14130                    dumpPackage = args[opti];
14131                    opti++;
14132                    newArgs = new String[args.length - opti];
14133                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14134                            args.length - opti);
14135                }
14136                synchronized (this) {
14137                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14138                }
14139            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14140                synchronized (this) {
14141                    dumpOomLocked(fd, pw, args, opti, true);
14142                }
14143            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14144                synchronized (this) {
14145                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14146                }
14147            } else if ("provider".equals(cmd)) {
14148                String[] newArgs;
14149                String name;
14150                if (opti >= args.length) {
14151                    name = null;
14152                    newArgs = EMPTY_STRING_ARRAY;
14153                } else {
14154                    name = args[opti];
14155                    opti++;
14156                    newArgs = new String[args.length - opti];
14157                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14158                }
14159                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14160                    pw.println("No providers match: " + name);
14161                    pw.println("Use -h for help.");
14162                }
14163            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14164                synchronized (this) {
14165                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14166                }
14167            } else if ("service".equals(cmd)) {
14168                String[] newArgs;
14169                String name;
14170                if (opti >= args.length) {
14171                    name = null;
14172                    newArgs = EMPTY_STRING_ARRAY;
14173                } else {
14174                    name = args[opti];
14175                    opti++;
14176                    newArgs = new String[args.length - opti];
14177                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14178                            args.length - opti);
14179                }
14180                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14181                    pw.println("No services match: " + name);
14182                    pw.println("Use -h for help.");
14183                }
14184            } else if ("package".equals(cmd)) {
14185                String[] newArgs;
14186                if (opti >= args.length) {
14187                    pw.println("package: no package name specified");
14188                    pw.println("Use -h for help.");
14189                } else {
14190                    dumpPackage = args[opti];
14191                    opti++;
14192                    newArgs = new String[args.length - opti];
14193                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14194                            args.length - opti);
14195                    args = newArgs;
14196                    opti = 0;
14197                    more = true;
14198                }
14199            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14200                synchronized (this) {
14201                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14202                }
14203            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14204                if (dumpClient) {
14205                    ActiveServices.ServiceDumper dumper;
14206                    synchronized (this) {
14207                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14208                                dumpPackage);
14209                    }
14210                    dumper.dumpWithClient();
14211                } else {
14212                    synchronized (this) {
14213                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14214                                dumpPackage).dumpLocked();
14215                    }
14216                }
14217            } else if ("locks".equals(cmd)) {
14218                LockGuard.dump(fd, pw, args);
14219            } else {
14220                // Dumping a single activity?
14221                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14222                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14223                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14224                    if (res < 0) {
14225                        pw.println("Bad activity command, or no activities match: " + cmd);
14226                        pw.println("Use -h for help.");
14227                    }
14228                }
14229            }
14230            if (!more) {
14231                Binder.restoreCallingIdentity(origId);
14232                return;
14233            }
14234        }
14235
14236        // No piece of data specified, dump everything.
14237        if (dumpCheckinFormat) {
14238            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14239        } else if (dumpClient) {
14240            ActiveServices.ServiceDumper sdumper;
14241            synchronized (this) {
14242                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14243                pw.println();
14244                if (dumpAll) {
14245                    pw.println("-------------------------------------------------------------------------------");
14246                }
14247                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14248                pw.println();
14249                if (dumpAll) {
14250                    pw.println("-------------------------------------------------------------------------------");
14251                }
14252                if (dumpAll || dumpPackage != null) {
14253                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14254                    pw.println();
14255                    if (dumpAll) {
14256                        pw.println("-------------------------------------------------------------------------------");
14257                    }
14258                }
14259                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14260                pw.println();
14261                if (dumpAll) {
14262                    pw.println("-------------------------------------------------------------------------------");
14263                }
14264                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14265                pw.println();
14266                if (dumpAll) {
14267                    pw.println("-------------------------------------------------------------------------------");
14268                }
14269                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14270                        dumpPackage);
14271            }
14272            sdumper.dumpWithClient();
14273            pw.println();
14274            synchronized (this) {
14275                if (dumpAll) {
14276                    pw.println("-------------------------------------------------------------------------------");
14277                }
14278                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14279                pw.println();
14280                if (dumpAll) {
14281                    pw.println("-------------------------------------------------------------------------------");
14282                }
14283                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14284                if (mAssociations.size() > 0) {
14285                    pw.println();
14286                    if (dumpAll) {
14287                        pw.println("-------------------------------------------------------------------------------");
14288                    }
14289                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14290                }
14291                pw.println();
14292                if (dumpAll) {
14293                    pw.println("-------------------------------------------------------------------------------");
14294                }
14295                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14296            }
14297
14298        } else {
14299            synchronized (this) {
14300                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14301                pw.println();
14302                if (dumpAll) {
14303                    pw.println("-------------------------------------------------------------------------------");
14304                }
14305                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14306                pw.println();
14307                if (dumpAll) {
14308                    pw.println("-------------------------------------------------------------------------------");
14309                }
14310                if (dumpAll || dumpPackage != null) {
14311                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14312                    pw.println();
14313                    if (dumpAll) {
14314                        pw.println("-------------------------------------------------------------------------------");
14315                    }
14316                }
14317                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14318                pw.println();
14319                if (dumpAll) {
14320                    pw.println("-------------------------------------------------------------------------------");
14321                }
14322                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14323                pw.println();
14324                if (dumpAll) {
14325                    pw.println("-------------------------------------------------------------------------------");
14326                }
14327                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14328                        .dumpLocked();
14329                pw.println();
14330                if (dumpAll) {
14331                    pw.println("-------------------------------------------------------------------------------");
14332                }
14333                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14334                pw.println();
14335                if (dumpAll) {
14336                    pw.println("-------------------------------------------------------------------------------");
14337                }
14338                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14339                if (mAssociations.size() > 0) {
14340                    pw.println();
14341                    if (dumpAll) {
14342                        pw.println("-------------------------------------------------------------------------------");
14343                    }
14344                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14345                }
14346                pw.println();
14347                if (dumpAll) {
14348                    pw.println("-------------------------------------------------------------------------------");
14349                }
14350                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14351            }
14352        }
14353        Binder.restoreCallingIdentity(origId);
14354    }
14355
14356    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14357            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14358        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14359
14360        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14361                dumpPackage);
14362        boolean needSep = printedAnything;
14363
14364        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14365                dumpPackage, needSep, "  mFocusedActivity: ");
14366        if (printed) {
14367            printedAnything = true;
14368            needSep = false;
14369        }
14370
14371        if (dumpPackage == null) {
14372            if (needSep) {
14373                pw.println();
14374            }
14375            needSep = true;
14376            printedAnything = true;
14377            mStackSupervisor.dump(pw, "  ");
14378        }
14379
14380        if (!printedAnything) {
14381            pw.println("  (nothing)");
14382        }
14383    }
14384
14385    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14386            int opti, boolean dumpAll, String dumpPackage) {
14387        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14388
14389        boolean printedAnything = false;
14390
14391        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14392            boolean printedHeader = false;
14393
14394            final int N = mRecentTasks.size();
14395            for (int i=0; i<N; i++) {
14396                TaskRecord tr = mRecentTasks.get(i);
14397                if (dumpPackage != null) {
14398                    if (tr.realActivity == null ||
14399                            !dumpPackage.equals(tr.realActivity)) {
14400                        continue;
14401                    }
14402                }
14403                if (!printedHeader) {
14404                    pw.println("  Recent tasks:");
14405                    printedHeader = true;
14406                    printedAnything = true;
14407                }
14408                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14409                        pw.println(tr);
14410                if (dumpAll) {
14411                    mRecentTasks.get(i).dump(pw, "    ");
14412                }
14413            }
14414        }
14415
14416        if (!printedAnything) {
14417            pw.println("  (nothing)");
14418        }
14419    }
14420
14421    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14422            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14423        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14424
14425        int dumpUid = 0;
14426        if (dumpPackage != null) {
14427            IPackageManager pm = AppGlobals.getPackageManager();
14428            try {
14429                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14430            } catch (RemoteException e) {
14431            }
14432        }
14433
14434        boolean printedAnything = false;
14435
14436        final long now = SystemClock.uptimeMillis();
14437
14438        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14439            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14440                    = mAssociations.valueAt(i1);
14441            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14442                SparseArray<ArrayMap<String, Association>> sourceUids
14443                        = targetComponents.valueAt(i2);
14444                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14445                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14446                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14447                        Association ass = sourceProcesses.valueAt(i4);
14448                        if (dumpPackage != null) {
14449                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14450                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14451                                continue;
14452                            }
14453                        }
14454                        printedAnything = true;
14455                        pw.print("  ");
14456                        pw.print(ass.mTargetProcess);
14457                        pw.print("/");
14458                        UserHandle.formatUid(pw, ass.mTargetUid);
14459                        pw.print(" <- ");
14460                        pw.print(ass.mSourceProcess);
14461                        pw.print("/");
14462                        UserHandle.formatUid(pw, ass.mSourceUid);
14463                        pw.println();
14464                        pw.print("    via ");
14465                        pw.print(ass.mTargetComponent.flattenToShortString());
14466                        pw.println();
14467                        pw.print("    ");
14468                        long dur = ass.mTime;
14469                        if (ass.mNesting > 0) {
14470                            dur += now - ass.mStartTime;
14471                        }
14472                        TimeUtils.formatDuration(dur, pw);
14473                        pw.print(" (");
14474                        pw.print(ass.mCount);
14475                        pw.print(" times)");
14476                        pw.print("  ");
14477                        for (int i=0; i<ass.mStateTimes.length; i++) {
14478                            long amt = ass.mStateTimes[i];
14479                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14480                                amt += now - ass.mLastStateUptime;
14481                            }
14482                            if (amt != 0) {
14483                                pw.print(" ");
14484                                pw.print(ProcessList.makeProcStateString(
14485                                            i + ActivityManager.MIN_PROCESS_STATE));
14486                                pw.print("=");
14487                                TimeUtils.formatDuration(amt, pw);
14488                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14489                                    pw.print("*");
14490                                }
14491                            }
14492                        }
14493                        pw.println();
14494                        if (ass.mNesting > 0) {
14495                            pw.print("    Currently active: ");
14496                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14497                            pw.println();
14498                        }
14499                    }
14500                }
14501            }
14502
14503        }
14504
14505        if (!printedAnything) {
14506            pw.println("  (nothing)");
14507        }
14508    }
14509
14510    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14511            String header, boolean needSep) {
14512        boolean printed = false;
14513        int whichAppId = -1;
14514        if (dumpPackage != null) {
14515            try {
14516                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14517                        dumpPackage, 0);
14518                whichAppId = UserHandle.getAppId(info.uid);
14519            } catch (NameNotFoundException e) {
14520                e.printStackTrace();
14521            }
14522        }
14523        for (int i=0; i<uids.size(); i++) {
14524            UidRecord uidRec = uids.valueAt(i);
14525            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14526                continue;
14527            }
14528            if (!printed) {
14529                printed = true;
14530                if (needSep) {
14531                    pw.println();
14532                }
14533                pw.print("  ");
14534                pw.println(header);
14535                needSep = true;
14536            }
14537            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14538            pw.print(": "); pw.println(uidRec);
14539        }
14540        return printed;
14541    }
14542
14543    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14544            int opti, boolean dumpAll, String dumpPackage) {
14545        boolean needSep = false;
14546        boolean printedAnything = false;
14547        int numPers = 0;
14548
14549        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14550
14551        if (dumpAll) {
14552            final int NP = mProcessNames.getMap().size();
14553            for (int ip=0; ip<NP; ip++) {
14554                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14555                final int NA = procs.size();
14556                for (int ia=0; ia<NA; ia++) {
14557                    ProcessRecord r = procs.valueAt(ia);
14558                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14559                        continue;
14560                    }
14561                    if (!needSep) {
14562                        pw.println("  All known processes:");
14563                        needSep = true;
14564                        printedAnything = true;
14565                    }
14566                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14567                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14568                        pw.print(" "); pw.println(r);
14569                    r.dump(pw, "    ");
14570                    if (r.persistent) {
14571                        numPers++;
14572                    }
14573                }
14574            }
14575        }
14576
14577        if (mIsolatedProcesses.size() > 0) {
14578            boolean printed = false;
14579            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14580                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14581                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14582                    continue;
14583                }
14584                if (!printed) {
14585                    if (needSep) {
14586                        pw.println();
14587                    }
14588                    pw.println("  Isolated process list (sorted by uid):");
14589                    printedAnything = true;
14590                    printed = true;
14591                    needSep = true;
14592                }
14593                pw.println(String.format("%sIsolated #%2d: %s",
14594                        "    ", i, r.toString()));
14595            }
14596        }
14597
14598        if (mActiveUids.size() > 0) {
14599            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14600                printedAnything = needSep = true;
14601            }
14602        }
14603        if (mValidateUids.size() > 0) {
14604            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14605                printedAnything = needSep = true;
14606            }
14607        }
14608
14609        if (mLruProcesses.size() > 0) {
14610            if (needSep) {
14611                pw.println();
14612            }
14613            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14614                    pw.print(" total, non-act at ");
14615                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14616                    pw.print(", non-svc at ");
14617                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14618                    pw.println("):");
14619            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14620            needSep = true;
14621            printedAnything = true;
14622        }
14623
14624        if (dumpAll || dumpPackage != null) {
14625            synchronized (mPidsSelfLocked) {
14626                boolean printed = false;
14627                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14628                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14629                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14630                        continue;
14631                    }
14632                    if (!printed) {
14633                        if (needSep) pw.println();
14634                        needSep = true;
14635                        pw.println("  PID mappings:");
14636                        printed = true;
14637                        printedAnything = true;
14638                    }
14639                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14640                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14641                }
14642            }
14643        }
14644
14645        if (mForegroundProcesses.size() > 0) {
14646            synchronized (mPidsSelfLocked) {
14647                boolean printed = false;
14648                for (int i=0; i<mForegroundProcesses.size(); i++) {
14649                    ProcessRecord r = mPidsSelfLocked.get(
14650                            mForegroundProcesses.valueAt(i).pid);
14651                    if (dumpPackage != null && (r == null
14652                            || !r.pkgList.containsKey(dumpPackage))) {
14653                        continue;
14654                    }
14655                    if (!printed) {
14656                        if (needSep) pw.println();
14657                        needSep = true;
14658                        pw.println("  Foreground Processes:");
14659                        printed = true;
14660                        printedAnything = true;
14661                    }
14662                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14663                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14664                }
14665            }
14666        }
14667
14668        if (mPersistentStartingProcesses.size() > 0) {
14669            if (needSep) pw.println();
14670            needSep = true;
14671            printedAnything = true;
14672            pw.println("  Persisent processes that are starting:");
14673            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14674                    "Starting Norm", "Restarting PERS", dumpPackage);
14675        }
14676
14677        if (mRemovedProcesses.size() > 0) {
14678            if (needSep) pw.println();
14679            needSep = true;
14680            printedAnything = true;
14681            pw.println("  Processes that are being removed:");
14682            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14683                    "Removed Norm", "Removed PERS", dumpPackage);
14684        }
14685
14686        if (mProcessesOnHold.size() > 0) {
14687            if (needSep) pw.println();
14688            needSep = true;
14689            printedAnything = true;
14690            pw.println("  Processes that are on old until the system is ready:");
14691            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14692                    "OnHold Norm", "OnHold PERS", dumpPackage);
14693        }
14694
14695        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14696
14697        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14698        if (needSep) {
14699            printedAnything = true;
14700        }
14701
14702        if (dumpPackage == null) {
14703            pw.println();
14704            needSep = false;
14705            mUserController.dump(pw, dumpAll);
14706        }
14707        if (mHomeProcess != null && (dumpPackage == null
14708                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14709            if (needSep) {
14710                pw.println();
14711                needSep = false;
14712            }
14713            pw.println("  mHomeProcess: " + mHomeProcess);
14714        }
14715        if (mPreviousProcess != null && (dumpPackage == null
14716                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14717            if (needSep) {
14718                pw.println();
14719                needSep = false;
14720            }
14721            pw.println("  mPreviousProcess: " + mPreviousProcess);
14722        }
14723        if (dumpAll) {
14724            StringBuilder sb = new StringBuilder(128);
14725            sb.append("  mPreviousProcessVisibleTime: ");
14726            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14727            pw.println(sb);
14728        }
14729        if (mHeavyWeightProcess != null && (dumpPackage == null
14730                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14731            if (needSep) {
14732                pw.println();
14733                needSep = false;
14734            }
14735            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14736        }
14737        if (dumpPackage == null) {
14738            pw.println("  mConfiguration: " + mConfiguration);
14739        }
14740        if (dumpAll) {
14741            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14742            if (mCompatModePackages.getPackages().size() > 0) {
14743                boolean printed = false;
14744                for (Map.Entry<String, Integer> entry
14745                        : mCompatModePackages.getPackages().entrySet()) {
14746                    String pkg = entry.getKey();
14747                    int mode = entry.getValue();
14748                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14749                        continue;
14750                    }
14751                    if (!printed) {
14752                        pw.println("  mScreenCompatPackages:");
14753                        printed = true;
14754                    }
14755                    pw.print("    "); pw.print(pkg); pw.print(": ");
14756                            pw.print(mode); pw.println();
14757                }
14758            }
14759        }
14760        if (dumpPackage == null) {
14761            pw.println("  mWakefulness="
14762                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14763            pw.println("  mSleepTokens=" + mSleepTokens);
14764            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14765                    + lockScreenShownToString());
14766            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14767            if (mRunningVoice != null) {
14768                pw.println("  mRunningVoice=" + mRunningVoice);
14769                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14770            }
14771        }
14772        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14773                || mOrigWaitForDebugger) {
14774            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14775                    || dumpPackage.equals(mOrigDebugApp)) {
14776                if (needSep) {
14777                    pw.println();
14778                    needSep = false;
14779                }
14780                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14781                        + " mDebugTransient=" + mDebugTransient
14782                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14783            }
14784        }
14785        if (mCurAppTimeTracker != null) {
14786            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14787        }
14788        if (mMemWatchProcesses.getMap().size() > 0) {
14789            pw.println("  Mem watch processes:");
14790            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14791                    = mMemWatchProcesses.getMap();
14792            for (int i=0; i<procs.size(); i++) {
14793                final String proc = procs.keyAt(i);
14794                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14795                for (int j=0; j<uids.size(); j++) {
14796                    if (needSep) {
14797                        pw.println();
14798                        needSep = false;
14799                    }
14800                    StringBuilder sb = new StringBuilder();
14801                    sb.append("    ").append(proc).append('/');
14802                    UserHandle.formatUid(sb, uids.keyAt(j));
14803                    Pair<Long, String> val = uids.valueAt(j);
14804                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14805                    if (val.second != null) {
14806                        sb.append(", report to ").append(val.second);
14807                    }
14808                    pw.println(sb.toString());
14809                }
14810            }
14811            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14812            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14813            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14814                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14815        }
14816        if (mTrackAllocationApp != null) {
14817            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14818                if (needSep) {
14819                    pw.println();
14820                    needSep = false;
14821                }
14822                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14823            }
14824        }
14825        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14826                || mProfileFd != null) {
14827            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14828                if (needSep) {
14829                    pw.println();
14830                    needSep = false;
14831                }
14832                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14833                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14834                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14835                        + mAutoStopProfiler);
14836                pw.println("  mProfileType=" + mProfileType);
14837            }
14838        }
14839        if (mNativeDebuggingApp != null) {
14840            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14841                if (needSep) {
14842                    pw.println();
14843                    needSep = false;
14844                }
14845                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14846            }
14847        }
14848        if (dumpPackage == null) {
14849            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14850                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14851                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14852            }
14853            if (mController != null) {
14854                pw.println("  mController=" + mController
14855                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14856            }
14857            if (dumpAll) {
14858                pw.println("  Total persistent processes: " + numPers);
14859                pw.println("  mProcessesReady=" + mProcessesReady
14860                        + " mSystemReady=" + mSystemReady
14861                        + " mBooted=" + mBooted
14862                        + " mFactoryTest=" + mFactoryTest);
14863                pw.println("  mBooting=" + mBooting
14864                        + " mCallFinishBooting=" + mCallFinishBooting
14865                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14866                pw.print("  mLastPowerCheckRealtime=");
14867                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14868                        pw.println("");
14869                pw.print("  mLastPowerCheckUptime=");
14870                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14871                        pw.println("");
14872                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14873                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14874                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14875                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14876                        + " (" + mLruProcesses.size() + " total)"
14877                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14878                        + " mNumServiceProcs=" + mNumServiceProcs
14879                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14880                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14881                        + " mLastMemoryLevel=" + mLastMemoryLevel
14882                        + " mLastNumProcesses=" + mLastNumProcesses);
14883                long now = SystemClock.uptimeMillis();
14884                pw.print("  mLastIdleTime=");
14885                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14886                        pw.print(" mLowRamSinceLastIdle=");
14887                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14888                        pw.println();
14889            }
14890        }
14891
14892        if (!printedAnything) {
14893            pw.println("  (nothing)");
14894        }
14895    }
14896
14897    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14898            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14899        if (mProcessesToGc.size() > 0) {
14900            boolean printed = false;
14901            long now = SystemClock.uptimeMillis();
14902            for (int i=0; i<mProcessesToGc.size(); i++) {
14903                ProcessRecord proc = mProcessesToGc.get(i);
14904                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14905                    continue;
14906                }
14907                if (!printed) {
14908                    if (needSep) pw.println();
14909                    needSep = true;
14910                    pw.println("  Processes that are waiting to GC:");
14911                    printed = true;
14912                }
14913                pw.print("    Process "); pw.println(proc);
14914                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14915                        pw.print(", last gced=");
14916                        pw.print(now-proc.lastRequestedGc);
14917                        pw.print(" ms ago, last lowMem=");
14918                        pw.print(now-proc.lastLowMemory);
14919                        pw.println(" ms ago");
14920
14921            }
14922        }
14923        return needSep;
14924    }
14925
14926    void printOomLevel(PrintWriter pw, String name, int adj) {
14927        pw.print("    ");
14928        if (adj >= 0) {
14929            pw.print(' ');
14930            if (adj < 10) pw.print(' ');
14931        } else {
14932            if (adj > -10) pw.print(' ');
14933        }
14934        pw.print(adj);
14935        pw.print(": ");
14936        pw.print(name);
14937        pw.print(" (");
14938        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14939        pw.println(")");
14940    }
14941
14942    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14943            int opti, boolean dumpAll) {
14944        boolean needSep = false;
14945
14946        if (mLruProcesses.size() > 0) {
14947            if (needSep) pw.println();
14948            needSep = true;
14949            pw.println("  OOM levels:");
14950            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14951            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14952            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14953            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14954            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14955            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14956            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14957            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14958            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14959            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14960            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14961            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14962            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14963            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14964
14965            if (needSep) pw.println();
14966            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14967                    pw.print(" total, non-act at ");
14968                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14969                    pw.print(", non-svc at ");
14970                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14971                    pw.println("):");
14972            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14973            needSep = true;
14974        }
14975
14976        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14977
14978        pw.println();
14979        pw.println("  mHomeProcess: " + mHomeProcess);
14980        pw.println("  mPreviousProcess: " + mPreviousProcess);
14981        if (mHeavyWeightProcess != null) {
14982            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14983        }
14984
14985        return true;
14986    }
14987
14988    /**
14989     * There are three ways to call this:
14990     *  - no provider specified: dump all the providers
14991     *  - a flattened component name that matched an existing provider was specified as the
14992     *    first arg: dump that one provider
14993     *  - the first arg isn't the flattened component name of an existing provider:
14994     *    dump all providers whose component contains the first arg as a substring
14995     */
14996    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14997            int opti, boolean dumpAll) {
14998        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14999    }
15000
15001    static class ItemMatcher {
15002        ArrayList<ComponentName> components;
15003        ArrayList<String> strings;
15004        ArrayList<Integer> objects;
15005        boolean all;
15006
15007        ItemMatcher() {
15008            all = true;
15009        }
15010
15011        void build(String name) {
15012            ComponentName componentName = ComponentName.unflattenFromString(name);
15013            if (componentName != null) {
15014                if (components == null) {
15015                    components = new ArrayList<ComponentName>();
15016                }
15017                components.add(componentName);
15018                all = false;
15019            } else {
15020                int objectId = 0;
15021                // Not a '/' separated full component name; maybe an object ID?
15022                try {
15023                    objectId = Integer.parseInt(name, 16);
15024                    if (objects == null) {
15025                        objects = new ArrayList<Integer>();
15026                    }
15027                    objects.add(objectId);
15028                    all = false;
15029                } catch (RuntimeException e) {
15030                    // Not an integer; just do string match.
15031                    if (strings == null) {
15032                        strings = new ArrayList<String>();
15033                    }
15034                    strings.add(name);
15035                    all = false;
15036                }
15037            }
15038        }
15039
15040        int build(String[] args, int opti) {
15041            for (; opti<args.length; opti++) {
15042                String name = args[opti];
15043                if ("--".equals(name)) {
15044                    return opti+1;
15045                }
15046                build(name);
15047            }
15048            return opti;
15049        }
15050
15051        boolean match(Object object, ComponentName comp) {
15052            if (all) {
15053                return true;
15054            }
15055            if (components != null) {
15056                for (int i=0; i<components.size(); i++) {
15057                    if (components.get(i).equals(comp)) {
15058                        return true;
15059                    }
15060                }
15061            }
15062            if (objects != null) {
15063                for (int i=0; i<objects.size(); i++) {
15064                    if (System.identityHashCode(object) == objects.get(i)) {
15065                        return true;
15066                    }
15067                }
15068            }
15069            if (strings != null) {
15070                String flat = comp.flattenToString();
15071                for (int i=0; i<strings.size(); i++) {
15072                    if (flat.contains(strings.get(i))) {
15073                        return true;
15074                    }
15075                }
15076            }
15077            return false;
15078        }
15079    }
15080
15081    /**
15082     * There are three things that cmd can be:
15083     *  - a flattened component name that matches an existing activity
15084     *  - the cmd arg isn't the flattened component name of an existing activity:
15085     *    dump all activity whose component contains the cmd as a substring
15086     *  - A hex number of the ActivityRecord object instance.
15087     */
15088    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15089            int opti, boolean dumpAll) {
15090        ArrayList<ActivityRecord> activities;
15091
15092        synchronized (this) {
15093            activities = mStackSupervisor.getDumpActivitiesLocked(name);
15094        }
15095
15096        if (activities.size() <= 0) {
15097            return false;
15098        }
15099
15100        String[] newArgs = new String[args.length - opti];
15101        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15102
15103        TaskRecord lastTask = null;
15104        boolean needSep = false;
15105        for (int i=activities.size()-1; i>=0; i--) {
15106            ActivityRecord r = activities.get(i);
15107            if (needSep) {
15108                pw.println();
15109            }
15110            needSep = true;
15111            synchronized (this) {
15112                if (lastTask != r.task) {
15113                    lastTask = r.task;
15114                    pw.print("TASK "); pw.print(lastTask.affinity);
15115                            pw.print(" id="); pw.println(lastTask.taskId);
15116                    if (dumpAll) {
15117                        lastTask.dump(pw, "  ");
15118                    }
15119                }
15120            }
15121            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15122        }
15123        return true;
15124    }
15125
15126    /**
15127     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15128     * there is a thread associated with the activity.
15129     */
15130    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15131            final ActivityRecord r, String[] args, boolean dumpAll) {
15132        String innerPrefix = prefix + "  ";
15133        synchronized (this) {
15134            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15135                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15136                    pw.print(" pid=");
15137                    if (r.app != null) pw.println(r.app.pid);
15138                    else pw.println("(not running)");
15139            if (dumpAll) {
15140                r.dump(pw, innerPrefix);
15141            }
15142        }
15143        if (r.app != null && r.app.thread != null) {
15144            // flush anything that is already in the PrintWriter since the thread is going
15145            // to write to the file descriptor directly
15146            pw.flush();
15147            try {
15148                TransferPipe tp = new TransferPipe();
15149                try {
15150                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15151                            r.appToken, innerPrefix, args);
15152                    tp.go(fd);
15153                } finally {
15154                    tp.kill();
15155                }
15156            } catch (IOException e) {
15157                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15158            } catch (RemoteException e) {
15159                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15160            }
15161        }
15162    }
15163
15164    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15165            int opti, boolean dumpAll, String dumpPackage) {
15166        boolean needSep = false;
15167        boolean onlyHistory = false;
15168        boolean printedAnything = false;
15169
15170        if ("history".equals(dumpPackage)) {
15171            if (opti < args.length && "-s".equals(args[opti])) {
15172                dumpAll = false;
15173            }
15174            onlyHistory = true;
15175            dumpPackage = null;
15176        }
15177
15178        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15179        if (!onlyHistory && dumpAll) {
15180            if (mRegisteredReceivers.size() > 0) {
15181                boolean printed = false;
15182                Iterator it = mRegisteredReceivers.values().iterator();
15183                while (it.hasNext()) {
15184                    ReceiverList r = (ReceiverList)it.next();
15185                    if (dumpPackage != null && (r.app == null ||
15186                            !dumpPackage.equals(r.app.info.packageName))) {
15187                        continue;
15188                    }
15189                    if (!printed) {
15190                        pw.println("  Registered Receivers:");
15191                        needSep = true;
15192                        printed = true;
15193                        printedAnything = true;
15194                    }
15195                    pw.print("  * "); pw.println(r);
15196                    r.dump(pw, "    ");
15197                }
15198            }
15199
15200            if (mReceiverResolver.dump(pw, needSep ?
15201                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15202                    "    ", dumpPackage, false, false)) {
15203                needSep = true;
15204                printedAnything = true;
15205            }
15206        }
15207
15208        for (BroadcastQueue q : mBroadcastQueues) {
15209            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15210            printedAnything |= needSep;
15211        }
15212
15213        needSep = true;
15214
15215        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15216            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15217                if (needSep) {
15218                    pw.println();
15219                }
15220                needSep = true;
15221                printedAnything = true;
15222                pw.print("  Sticky broadcasts for user ");
15223                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15224                StringBuilder sb = new StringBuilder(128);
15225                for (Map.Entry<String, ArrayList<Intent>> ent
15226                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15227                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15228                    if (dumpAll) {
15229                        pw.println(":");
15230                        ArrayList<Intent> intents = ent.getValue();
15231                        final int N = intents.size();
15232                        for (int i=0; i<N; i++) {
15233                            sb.setLength(0);
15234                            sb.append("    Intent: ");
15235                            intents.get(i).toShortString(sb, false, true, false, false);
15236                            pw.println(sb.toString());
15237                            Bundle bundle = intents.get(i).getExtras();
15238                            if (bundle != null) {
15239                                pw.print("      ");
15240                                pw.println(bundle.toString());
15241                            }
15242                        }
15243                    } else {
15244                        pw.println("");
15245                    }
15246                }
15247            }
15248        }
15249
15250        if (!onlyHistory && dumpAll) {
15251            pw.println();
15252            for (BroadcastQueue queue : mBroadcastQueues) {
15253                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15254                        + queue.mBroadcastsScheduled);
15255            }
15256            pw.println("  mHandler:");
15257            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15258            needSep = true;
15259            printedAnything = true;
15260        }
15261
15262        if (!printedAnything) {
15263            pw.println("  (nothing)");
15264        }
15265    }
15266
15267    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15268            int opti, boolean dumpAll, String dumpPackage) {
15269        if (mCurBroadcastStats == null) {
15270            return;
15271        }
15272
15273        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15274        final long now = SystemClock.elapsedRealtime();
15275        if (mLastBroadcastStats != null) {
15276            pw.print("  Last stats (from ");
15277            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15278            pw.print(" to ");
15279            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15280            pw.print(", ");
15281            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15282                    - mLastBroadcastStats.mStartUptime, pw);
15283            pw.println(" uptime):");
15284            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15285                pw.println("    (nothing)");
15286            }
15287            pw.println();
15288        }
15289        pw.print("  Current stats (from ");
15290        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15291        pw.print(" to now, ");
15292        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15293                - mCurBroadcastStats.mStartUptime, pw);
15294        pw.println(" uptime):");
15295        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15296            pw.println("    (nothing)");
15297        }
15298    }
15299
15300    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15301            int opti, boolean fullCheckin, String dumpPackage) {
15302        if (mCurBroadcastStats == null) {
15303            return;
15304        }
15305
15306        if (mLastBroadcastStats != null) {
15307            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15308            if (fullCheckin) {
15309                mLastBroadcastStats = null;
15310                return;
15311            }
15312        }
15313        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15314        if (fullCheckin) {
15315            mCurBroadcastStats = null;
15316        }
15317    }
15318
15319    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15320            int opti, boolean dumpAll, String dumpPackage) {
15321        boolean needSep;
15322        boolean printedAnything = false;
15323
15324        ItemMatcher matcher = new ItemMatcher();
15325        matcher.build(args, opti);
15326
15327        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15328
15329        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15330        printedAnything |= needSep;
15331
15332        if (mLaunchingProviders.size() > 0) {
15333            boolean printed = false;
15334            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15335                ContentProviderRecord r = mLaunchingProviders.get(i);
15336                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15337                    continue;
15338                }
15339                if (!printed) {
15340                    if (needSep) pw.println();
15341                    needSep = true;
15342                    pw.println("  Launching content providers:");
15343                    printed = true;
15344                    printedAnything = true;
15345                }
15346                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15347                        pw.println(r);
15348            }
15349        }
15350
15351        if (!printedAnything) {
15352            pw.println("  (nothing)");
15353        }
15354    }
15355
15356    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15357            int opti, boolean dumpAll, String dumpPackage) {
15358        boolean needSep = false;
15359        boolean printedAnything = false;
15360
15361        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15362
15363        if (mGrantedUriPermissions.size() > 0) {
15364            boolean printed = false;
15365            int dumpUid = -2;
15366            if (dumpPackage != null) {
15367                try {
15368                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15369                            MATCH_UNINSTALLED_PACKAGES, 0);
15370                } catch (NameNotFoundException e) {
15371                    dumpUid = -1;
15372                }
15373            }
15374            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15375                int uid = mGrantedUriPermissions.keyAt(i);
15376                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15377                    continue;
15378                }
15379                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15380                if (!printed) {
15381                    if (needSep) pw.println();
15382                    needSep = true;
15383                    pw.println("  Granted Uri Permissions:");
15384                    printed = true;
15385                    printedAnything = true;
15386                }
15387                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15388                for (UriPermission perm : perms.values()) {
15389                    pw.print("    "); pw.println(perm);
15390                    if (dumpAll) {
15391                        perm.dump(pw, "      ");
15392                    }
15393                }
15394            }
15395        }
15396
15397        if (!printedAnything) {
15398            pw.println("  (nothing)");
15399        }
15400    }
15401
15402    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15403            int opti, boolean dumpAll, String dumpPackage) {
15404        boolean printed = false;
15405
15406        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15407
15408        if (mIntentSenderRecords.size() > 0) {
15409            Iterator<WeakReference<PendingIntentRecord>> it
15410                    = mIntentSenderRecords.values().iterator();
15411            while (it.hasNext()) {
15412                WeakReference<PendingIntentRecord> ref = it.next();
15413                PendingIntentRecord rec = ref != null ? ref.get(): null;
15414                if (dumpPackage != null && (rec == null
15415                        || !dumpPackage.equals(rec.key.packageName))) {
15416                    continue;
15417                }
15418                printed = true;
15419                if (rec != null) {
15420                    pw.print("  * "); pw.println(rec);
15421                    if (dumpAll) {
15422                        rec.dump(pw, "    ");
15423                    }
15424                } else {
15425                    pw.print("  * "); pw.println(ref);
15426                }
15427            }
15428        }
15429
15430        if (!printed) {
15431            pw.println("  (nothing)");
15432        }
15433    }
15434
15435    private static final int dumpProcessList(PrintWriter pw,
15436            ActivityManagerService service, List list,
15437            String prefix, String normalLabel, String persistentLabel,
15438            String dumpPackage) {
15439        int numPers = 0;
15440        final int N = list.size()-1;
15441        for (int i=N; i>=0; i--) {
15442            ProcessRecord r = (ProcessRecord)list.get(i);
15443            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15444                continue;
15445            }
15446            pw.println(String.format("%s%s #%2d: %s",
15447                    prefix, (r.persistent ? persistentLabel : normalLabel),
15448                    i, r.toString()));
15449            if (r.persistent) {
15450                numPers++;
15451            }
15452        }
15453        return numPers;
15454    }
15455
15456    private static final boolean dumpProcessOomList(PrintWriter pw,
15457            ActivityManagerService service, List<ProcessRecord> origList,
15458            String prefix, String normalLabel, String persistentLabel,
15459            boolean inclDetails, String dumpPackage) {
15460
15461        ArrayList<Pair<ProcessRecord, Integer>> list
15462                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15463        for (int i=0; i<origList.size(); i++) {
15464            ProcessRecord r = origList.get(i);
15465            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15466                continue;
15467            }
15468            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15469        }
15470
15471        if (list.size() <= 0) {
15472            return false;
15473        }
15474
15475        Comparator<Pair<ProcessRecord, Integer>> comparator
15476                = new Comparator<Pair<ProcessRecord, Integer>>() {
15477            @Override
15478            public int compare(Pair<ProcessRecord, Integer> object1,
15479                    Pair<ProcessRecord, Integer> object2) {
15480                if (object1.first.setAdj != object2.first.setAdj) {
15481                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15482                }
15483                if (object1.first.setProcState != object2.first.setProcState) {
15484                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15485                }
15486                if (object1.second.intValue() != object2.second.intValue()) {
15487                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15488                }
15489                return 0;
15490            }
15491        };
15492
15493        Collections.sort(list, comparator);
15494
15495        final long curRealtime = SystemClock.elapsedRealtime();
15496        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15497        final long curUptime = SystemClock.uptimeMillis();
15498        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15499
15500        for (int i=list.size()-1; i>=0; i--) {
15501            ProcessRecord r = list.get(i).first;
15502            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15503            char schedGroup;
15504            switch (r.setSchedGroup) {
15505                case ProcessList.SCHED_GROUP_BACKGROUND:
15506                    schedGroup = 'B';
15507                    break;
15508                case ProcessList.SCHED_GROUP_DEFAULT:
15509                    schedGroup = 'F';
15510                    break;
15511                case ProcessList.SCHED_GROUP_TOP_APP:
15512                    schedGroup = 'T';
15513                    break;
15514                default:
15515                    schedGroup = '?';
15516                    break;
15517            }
15518            char foreground;
15519            if (r.foregroundActivities) {
15520                foreground = 'A';
15521            } else if (r.foregroundServices) {
15522                foreground = 'S';
15523            } else {
15524                foreground = ' ';
15525            }
15526            String procState = ProcessList.makeProcStateString(r.curProcState);
15527            pw.print(prefix);
15528            pw.print(r.persistent ? persistentLabel : normalLabel);
15529            pw.print(" #");
15530            int num = (origList.size()-1)-list.get(i).second;
15531            if (num < 10) pw.print(' ');
15532            pw.print(num);
15533            pw.print(": ");
15534            pw.print(oomAdj);
15535            pw.print(' ');
15536            pw.print(schedGroup);
15537            pw.print('/');
15538            pw.print(foreground);
15539            pw.print('/');
15540            pw.print(procState);
15541            pw.print(" trm:");
15542            if (r.trimMemoryLevel < 10) pw.print(' ');
15543            pw.print(r.trimMemoryLevel);
15544            pw.print(' ');
15545            pw.print(r.toShortString());
15546            pw.print(" (");
15547            pw.print(r.adjType);
15548            pw.println(')');
15549            if (r.adjSource != null || r.adjTarget != null) {
15550                pw.print(prefix);
15551                pw.print("    ");
15552                if (r.adjTarget instanceof ComponentName) {
15553                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15554                } else if (r.adjTarget != null) {
15555                    pw.print(r.adjTarget.toString());
15556                } else {
15557                    pw.print("{null}");
15558                }
15559                pw.print("<=");
15560                if (r.adjSource instanceof ProcessRecord) {
15561                    pw.print("Proc{");
15562                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15563                    pw.println("}");
15564                } else if (r.adjSource != null) {
15565                    pw.println(r.adjSource.toString());
15566                } else {
15567                    pw.println("{null}");
15568                }
15569            }
15570            if (inclDetails) {
15571                pw.print(prefix);
15572                pw.print("    ");
15573                pw.print("oom: max="); pw.print(r.maxAdj);
15574                pw.print(" curRaw="); pw.print(r.curRawAdj);
15575                pw.print(" setRaw="); pw.print(r.setRawAdj);
15576                pw.print(" cur="); pw.print(r.curAdj);
15577                pw.print(" set="); pw.println(r.setAdj);
15578                pw.print(prefix);
15579                pw.print("    ");
15580                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15581                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15582                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15583                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15584                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15585                pw.println();
15586                pw.print(prefix);
15587                pw.print("    ");
15588                pw.print("cached="); pw.print(r.cached);
15589                pw.print(" empty="); pw.print(r.empty);
15590                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15591
15592                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15593                    if (r.lastWakeTime != 0) {
15594                        long wtime;
15595                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15596                        synchronized (stats) {
15597                            wtime = stats.getProcessWakeTime(r.info.uid,
15598                                    r.pid, curRealtime);
15599                        }
15600                        long timeUsed = wtime - r.lastWakeTime;
15601                        pw.print(prefix);
15602                        pw.print("    ");
15603                        pw.print("keep awake over ");
15604                        TimeUtils.formatDuration(realtimeSince, pw);
15605                        pw.print(" used ");
15606                        TimeUtils.formatDuration(timeUsed, pw);
15607                        pw.print(" (");
15608                        pw.print((timeUsed*100)/realtimeSince);
15609                        pw.println("%)");
15610                    }
15611                    if (r.lastCpuTime != 0) {
15612                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15613                        pw.print(prefix);
15614                        pw.print("    ");
15615                        pw.print("run cpu over ");
15616                        TimeUtils.formatDuration(uptimeSince, pw);
15617                        pw.print(" used ");
15618                        TimeUtils.formatDuration(timeUsed, pw);
15619                        pw.print(" (");
15620                        pw.print((timeUsed*100)/uptimeSince);
15621                        pw.println("%)");
15622                    }
15623                }
15624            }
15625        }
15626        return true;
15627    }
15628
15629    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15630            String[] args) {
15631        ArrayList<ProcessRecord> procs;
15632        synchronized (this) {
15633            if (args != null && args.length > start
15634                    && args[start].charAt(0) != '-') {
15635                procs = new ArrayList<ProcessRecord>();
15636                int pid = -1;
15637                try {
15638                    pid = Integer.parseInt(args[start]);
15639                } catch (NumberFormatException e) {
15640                }
15641                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15642                    ProcessRecord proc = mLruProcesses.get(i);
15643                    if (proc.pid == pid) {
15644                        procs.add(proc);
15645                    } else if (allPkgs && proc.pkgList != null
15646                            && proc.pkgList.containsKey(args[start])) {
15647                        procs.add(proc);
15648                    } else if (proc.processName.equals(args[start])) {
15649                        procs.add(proc);
15650                    }
15651                }
15652                if (procs.size() <= 0) {
15653                    return null;
15654                }
15655            } else {
15656                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15657            }
15658        }
15659        return procs;
15660    }
15661
15662    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15663            PrintWriter pw, String[] args) {
15664        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15665        if (procs == null) {
15666            pw.println("No process found for: " + args[0]);
15667            return;
15668        }
15669
15670        long uptime = SystemClock.uptimeMillis();
15671        long realtime = SystemClock.elapsedRealtime();
15672        pw.println("Applications Graphics Acceleration Info:");
15673        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15674
15675        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15676            ProcessRecord r = procs.get(i);
15677            if (r.thread != null) {
15678                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15679                pw.flush();
15680                try {
15681                    TransferPipe tp = new TransferPipe();
15682                    try {
15683                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15684                        tp.go(fd);
15685                    } finally {
15686                        tp.kill();
15687                    }
15688                } catch (IOException e) {
15689                    pw.println("Failure while dumping the app: " + r);
15690                    pw.flush();
15691                } catch (RemoteException e) {
15692                    pw.println("Got a RemoteException while dumping the app " + r);
15693                    pw.flush();
15694                }
15695            }
15696        }
15697    }
15698
15699    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15700        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15701        if (procs == null) {
15702            pw.println("No process found for: " + args[0]);
15703            return;
15704        }
15705
15706        pw.println("Applications Database Info:");
15707
15708        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15709            ProcessRecord r = procs.get(i);
15710            if (r.thread != null) {
15711                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15712                pw.flush();
15713                try {
15714                    TransferPipe tp = new TransferPipe();
15715                    try {
15716                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15717                        tp.go(fd);
15718                    } finally {
15719                        tp.kill();
15720                    }
15721                } catch (IOException e) {
15722                    pw.println("Failure while dumping the app: " + r);
15723                    pw.flush();
15724                } catch (RemoteException e) {
15725                    pw.println("Got a RemoteException while dumping the app " + r);
15726                    pw.flush();
15727                }
15728            }
15729        }
15730    }
15731
15732    final static class MemItem {
15733        final boolean isProc;
15734        final String label;
15735        final String shortLabel;
15736        final long pss;
15737        final long swapPss;
15738        final int id;
15739        final boolean hasActivities;
15740        ArrayList<MemItem> subitems;
15741
15742        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15743                boolean _hasActivities) {
15744            isProc = true;
15745            label = _label;
15746            shortLabel = _shortLabel;
15747            pss = _pss;
15748            swapPss = _swapPss;
15749            id = _id;
15750            hasActivities = _hasActivities;
15751        }
15752
15753        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15754            isProc = false;
15755            label = _label;
15756            shortLabel = _shortLabel;
15757            pss = _pss;
15758            swapPss = _swapPss;
15759            id = _id;
15760            hasActivities = false;
15761        }
15762    }
15763
15764    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15765            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15766        if (sort && !isCompact) {
15767            Collections.sort(items, new Comparator<MemItem>() {
15768                @Override
15769                public int compare(MemItem lhs, MemItem rhs) {
15770                    if (lhs.pss < rhs.pss) {
15771                        return 1;
15772                    } else if (lhs.pss > rhs.pss) {
15773                        return -1;
15774                    }
15775                    return 0;
15776                }
15777            });
15778        }
15779
15780        for (int i=0; i<items.size(); i++) {
15781            MemItem mi = items.get(i);
15782            if (!isCompact) {
15783                if (dumpSwapPss) {
15784                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15785                            mi.label, stringifyKBSize(mi.swapPss));
15786                } else {
15787                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15788                }
15789            } else if (mi.isProc) {
15790                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15791                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15792                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15793                pw.println(mi.hasActivities ? ",a" : ",e");
15794            } else {
15795                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15796                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15797            }
15798            if (mi.subitems != null) {
15799                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15800                        true, isCompact, dumpSwapPss);
15801            }
15802        }
15803    }
15804
15805    // These are in KB.
15806    static final long[] DUMP_MEM_BUCKETS = new long[] {
15807        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15808        120*1024, 160*1024, 200*1024,
15809        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15810        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15811    };
15812
15813    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15814            boolean stackLike) {
15815        int start = label.lastIndexOf('.');
15816        if (start >= 0) start++;
15817        else start = 0;
15818        int end = label.length();
15819        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15820            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15821                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15822                out.append(bucket);
15823                out.append(stackLike ? "MB." : "MB ");
15824                out.append(label, start, end);
15825                return;
15826            }
15827        }
15828        out.append(memKB/1024);
15829        out.append(stackLike ? "MB." : "MB ");
15830        out.append(label, start, end);
15831    }
15832
15833    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15834            ProcessList.NATIVE_ADJ,
15835            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15836            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15837            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15838            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15839            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15840            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15841    };
15842    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15843            "Native",
15844            "System", "Persistent", "Persistent Service", "Foreground",
15845            "Visible", "Perceptible",
15846            "Heavy Weight", "Backup",
15847            "A Services", "Home",
15848            "Previous", "B Services", "Cached"
15849    };
15850    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15851            "native",
15852            "sys", "pers", "persvc", "fore",
15853            "vis", "percept",
15854            "heavy", "backup",
15855            "servicea", "home",
15856            "prev", "serviceb", "cached"
15857    };
15858
15859    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15860            long realtime, boolean isCheckinRequest, boolean isCompact) {
15861        if (isCompact) {
15862            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15863        }
15864        if (isCheckinRequest || isCompact) {
15865            // short checkin version
15866            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15867        } else {
15868            pw.println("Applications Memory Usage (in Kilobytes):");
15869            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15870        }
15871    }
15872
15873    private static final int KSM_SHARED = 0;
15874    private static final int KSM_SHARING = 1;
15875    private static final int KSM_UNSHARED = 2;
15876    private static final int KSM_VOLATILE = 3;
15877
15878    private final long[] getKsmInfo() {
15879        long[] longOut = new long[4];
15880        final int[] SINGLE_LONG_FORMAT = new int[] {
15881            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15882        };
15883        long[] longTmp = new long[1];
15884        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15885                SINGLE_LONG_FORMAT, null, longTmp, null);
15886        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15887        longTmp[0] = 0;
15888        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15889                SINGLE_LONG_FORMAT, null, longTmp, null);
15890        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15891        longTmp[0] = 0;
15892        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15893                SINGLE_LONG_FORMAT, null, longTmp, null);
15894        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15895        longTmp[0] = 0;
15896        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15897                SINGLE_LONG_FORMAT, null, longTmp, null);
15898        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15899        return longOut;
15900    }
15901
15902    private static String stringifySize(long size, int order) {
15903        Locale locale = Locale.US;
15904        switch (order) {
15905            case 1:
15906                return String.format(locale, "%,13d", size);
15907            case 1024:
15908                return String.format(locale, "%,9dK", size / 1024);
15909            case 1024 * 1024:
15910                return String.format(locale, "%,5dM", size / 1024 / 1024);
15911            case 1024 * 1024 * 1024:
15912                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15913            default:
15914                throw new IllegalArgumentException("Invalid size order");
15915        }
15916    }
15917
15918    private static String stringifyKBSize(long size) {
15919        return stringifySize(size * 1024, 1024);
15920    }
15921
15922    // Update this version number in case you change the 'compact' format
15923    private static final int MEMINFO_COMPACT_VERSION = 1;
15924
15925    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15926            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15927        boolean dumpDetails = false;
15928        boolean dumpFullDetails = false;
15929        boolean dumpDalvik = false;
15930        boolean dumpSummaryOnly = false;
15931        boolean dumpUnreachable = false;
15932        boolean oomOnly = false;
15933        boolean isCompact = false;
15934        boolean localOnly = false;
15935        boolean packages = false;
15936        boolean isCheckinRequest = false;
15937        boolean dumpSwapPss = false;
15938
15939        int opti = 0;
15940        while (opti < args.length) {
15941            String opt = args[opti];
15942            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15943                break;
15944            }
15945            opti++;
15946            if ("-a".equals(opt)) {
15947                dumpDetails = true;
15948                dumpFullDetails = true;
15949                dumpDalvik = true;
15950                dumpSwapPss = true;
15951            } else if ("-d".equals(opt)) {
15952                dumpDalvik = true;
15953            } else if ("-c".equals(opt)) {
15954                isCompact = true;
15955            } else if ("-s".equals(opt)) {
15956                dumpDetails = true;
15957                dumpSummaryOnly = true;
15958            } else if ("-S".equals(opt)) {
15959                dumpSwapPss = true;
15960            } else if ("--unreachable".equals(opt)) {
15961                dumpUnreachable = true;
15962            } else if ("--oom".equals(opt)) {
15963                oomOnly = true;
15964            } else if ("--local".equals(opt)) {
15965                localOnly = true;
15966            } else if ("--package".equals(opt)) {
15967                packages = true;
15968            } else if ("--checkin".equals(opt)) {
15969                isCheckinRequest = true;
15970
15971            } else if ("-h".equals(opt)) {
15972                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15973                pw.println("  -a: include all available information for each process.");
15974                pw.println("  -d: include dalvik details.");
15975                pw.println("  -c: dump in a compact machine-parseable representation.");
15976                pw.println("  -s: dump only summary of application memory usage.");
15977                pw.println("  -S: dump also SwapPss.");
15978                pw.println("  --oom: only show processes organized by oom adj.");
15979                pw.println("  --local: only collect details locally, don't call process.");
15980                pw.println("  --package: interpret process arg as package, dumping all");
15981                pw.println("             processes that have loaded that package.");
15982                pw.println("  --checkin: dump data for a checkin");
15983                pw.println("If [process] is specified it can be the name or ");
15984                pw.println("pid of a specific process to dump.");
15985                return;
15986            } else {
15987                pw.println("Unknown argument: " + opt + "; use -h for help");
15988            }
15989        }
15990
15991        long uptime = SystemClock.uptimeMillis();
15992        long realtime = SystemClock.elapsedRealtime();
15993        final long[] tmpLong = new long[1];
15994
15995        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15996        if (procs == null) {
15997            // No Java processes.  Maybe they want to print a native process.
15998            if (args != null && args.length > opti
15999                    && args[opti].charAt(0) != '-') {
16000                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16001                        = new ArrayList<ProcessCpuTracker.Stats>();
16002                updateCpuStatsNow();
16003                int findPid = -1;
16004                try {
16005                    findPid = Integer.parseInt(args[opti]);
16006                } catch (NumberFormatException e) {
16007                }
16008                synchronized (mProcessCpuTracker) {
16009                    final int N = mProcessCpuTracker.countStats();
16010                    for (int i=0; i<N; i++) {
16011                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16012                        if (st.pid == findPid || (st.baseName != null
16013                                && st.baseName.equals(args[opti]))) {
16014                            nativeProcs.add(st);
16015                        }
16016                    }
16017                }
16018                if (nativeProcs.size() > 0) {
16019                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16020                            isCompact);
16021                    Debug.MemoryInfo mi = null;
16022                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16023                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16024                        final int pid = r.pid;
16025                        if (!isCheckinRequest && dumpDetails) {
16026                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16027                        }
16028                        if (mi == null) {
16029                            mi = new Debug.MemoryInfo();
16030                        }
16031                        if (dumpDetails || (!brief && !oomOnly)) {
16032                            Debug.getMemoryInfo(pid, mi);
16033                        } else {
16034                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16035                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16036                        }
16037                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16038                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16039                        if (isCheckinRequest) {
16040                            pw.println();
16041                        }
16042                    }
16043                    return;
16044                }
16045            }
16046            pw.println("No process found for: " + args[opti]);
16047            return;
16048        }
16049
16050        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16051            dumpDetails = true;
16052        }
16053
16054        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16055
16056        String[] innerArgs = new String[args.length-opti];
16057        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16058
16059        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16060        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16061        long nativePss = 0;
16062        long nativeSwapPss = 0;
16063        long dalvikPss = 0;
16064        long dalvikSwapPss = 0;
16065        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16066                EmptyArray.LONG;
16067        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16068                EmptyArray.LONG;
16069        long otherPss = 0;
16070        long otherSwapPss = 0;
16071        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16072        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16073
16074        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16075        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16076        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16077                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16078
16079        long totalPss = 0;
16080        long totalSwapPss = 0;
16081        long cachedPss = 0;
16082        long cachedSwapPss = 0;
16083        boolean hasSwapPss = false;
16084
16085        Debug.MemoryInfo mi = null;
16086        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16087            final ProcessRecord r = procs.get(i);
16088            final IApplicationThread thread;
16089            final int pid;
16090            final int oomAdj;
16091            final boolean hasActivities;
16092            synchronized (this) {
16093                thread = r.thread;
16094                pid = r.pid;
16095                oomAdj = r.getSetAdjWithServices();
16096                hasActivities = r.activities.size() > 0;
16097            }
16098            if (thread != null) {
16099                if (!isCheckinRequest && dumpDetails) {
16100                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16101                }
16102                if (mi == null) {
16103                    mi = new Debug.MemoryInfo();
16104                }
16105                if (dumpDetails || (!brief && !oomOnly)) {
16106                    Debug.getMemoryInfo(pid, mi);
16107                    hasSwapPss = mi.hasSwappedOutPss;
16108                } else {
16109                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16110                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16111                }
16112                if (dumpDetails) {
16113                    if (localOnly) {
16114                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16115                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16116                        if (isCheckinRequest) {
16117                            pw.println();
16118                        }
16119                    } else {
16120                        try {
16121                            pw.flush();
16122                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16123                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16124                        } catch (RemoteException e) {
16125                            if (!isCheckinRequest) {
16126                                pw.println("Got RemoteException!");
16127                                pw.flush();
16128                            }
16129                        }
16130                    }
16131                }
16132
16133                final long myTotalPss = mi.getTotalPss();
16134                final long myTotalUss = mi.getTotalUss();
16135                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16136
16137                synchronized (this) {
16138                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16139                        // Record this for posterity if the process has been stable.
16140                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16141                    }
16142                }
16143
16144                if (!isCheckinRequest && mi != null) {
16145                    totalPss += myTotalPss;
16146                    totalSwapPss += myTotalSwapPss;
16147                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16148                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16149                            myTotalSwapPss, pid, hasActivities);
16150                    procMems.add(pssItem);
16151                    procMemsMap.put(pid, pssItem);
16152
16153                    nativePss += mi.nativePss;
16154                    nativeSwapPss += mi.nativeSwappedOutPss;
16155                    dalvikPss += mi.dalvikPss;
16156                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16157                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16158                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16159                        dalvikSubitemSwapPss[j] +=
16160                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16161                    }
16162                    otherPss += mi.otherPss;
16163                    otherSwapPss += mi.otherSwappedOutPss;
16164                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16165                        long mem = mi.getOtherPss(j);
16166                        miscPss[j] += mem;
16167                        otherPss -= mem;
16168                        mem = mi.getOtherSwappedOutPss(j);
16169                        miscSwapPss[j] += mem;
16170                        otherSwapPss -= mem;
16171                    }
16172
16173                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16174                        cachedPss += myTotalPss;
16175                        cachedSwapPss += myTotalSwapPss;
16176                    }
16177
16178                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16179                        if (oomIndex == (oomPss.length - 1)
16180                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16181                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16182                            oomPss[oomIndex] += myTotalPss;
16183                            oomSwapPss[oomIndex] += myTotalSwapPss;
16184                            if (oomProcs[oomIndex] == null) {
16185                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16186                            }
16187                            oomProcs[oomIndex].add(pssItem);
16188                            break;
16189                        }
16190                    }
16191                }
16192            }
16193        }
16194
16195        long nativeProcTotalPss = 0;
16196
16197        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16198            // If we are showing aggregations, also look for native processes to
16199            // include so that our aggregations are more accurate.
16200            updateCpuStatsNow();
16201            mi = null;
16202            synchronized (mProcessCpuTracker) {
16203                final int N = mProcessCpuTracker.countStats();
16204                for (int i=0; i<N; i++) {
16205                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16206                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16207                        if (mi == null) {
16208                            mi = new Debug.MemoryInfo();
16209                        }
16210                        if (!brief && !oomOnly) {
16211                            Debug.getMemoryInfo(st.pid, mi);
16212                        } else {
16213                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16214                            mi.nativePrivateDirty = (int)tmpLong[0];
16215                        }
16216
16217                        final long myTotalPss = mi.getTotalPss();
16218                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16219                        totalPss += myTotalPss;
16220                        nativeProcTotalPss += myTotalPss;
16221
16222                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16223                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16224                        procMems.add(pssItem);
16225
16226                        nativePss += mi.nativePss;
16227                        nativeSwapPss += mi.nativeSwappedOutPss;
16228                        dalvikPss += mi.dalvikPss;
16229                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16230                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16231                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16232                            dalvikSubitemSwapPss[j] +=
16233                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16234                        }
16235                        otherPss += mi.otherPss;
16236                        otherSwapPss += mi.otherSwappedOutPss;
16237                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16238                            long mem = mi.getOtherPss(j);
16239                            miscPss[j] += mem;
16240                            otherPss -= mem;
16241                            mem = mi.getOtherSwappedOutPss(j);
16242                            miscSwapPss[j] += mem;
16243                            otherSwapPss -= mem;
16244                        }
16245                        oomPss[0] += myTotalPss;
16246                        oomSwapPss[0] += myTotalSwapPss;
16247                        if (oomProcs[0] == null) {
16248                            oomProcs[0] = new ArrayList<MemItem>();
16249                        }
16250                        oomProcs[0].add(pssItem);
16251                    }
16252                }
16253            }
16254
16255            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16256
16257            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16258            final MemItem dalvikItem =
16259                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16260            if (dalvikSubitemPss.length > 0) {
16261                dalvikItem.subitems = new ArrayList<MemItem>();
16262                for (int j=0; j<dalvikSubitemPss.length; j++) {
16263                    final String name = Debug.MemoryInfo.getOtherLabel(
16264                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16265                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16266                                    dalvikSubitemSwapPss[j], j));
16267                }
16268            }
16269            catMems.add(dalvikItem);
16270            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16271            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16272                String label = Debug.MemoryInfo.getOtherLabel(j);
16273                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16274            }
16275
16276            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16277            for (int j=0; j<oomPss.length; j++) {
16278                if (oomPss[j] != 0) {
16279                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16280                            : DUMP_MEM_OOM_LABEL[j];
16281                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16282                            DUMP_MEM_OOM_ADJ[j]);
16283                    item.subitems = oomProcs[j];
16284                    oomMems.add(item);
16285                }
16286            }
16287
16288            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16289            if (!brief && !oomOnly && !isCompact) {
16290                pw.println();
16291                pw.println("Total PSS by process:");
16292                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16293                pw.println();
16294            }
16295            if (!isCompact) {
16296                pw.println("Total PSS by OOM adjustment:");
16297            }
16298            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16299            if (!brief && !oomOnly) {
16300                PrintWriter out = categoryPw != null ? categoryPw : pw;
16301                if (!isCompact) {
16302                    out.println();
16303                    out.println("Total PSS by category:");
16304                }
16305                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16306            }
16307            if (!isCompact) {
16308                pw.println();
16309            }
16310            MemInfoReader memInfo = new MemInfoReader();
16311            memInfo.readMemInfo();
16312            if (nativeProcTotalPss > 0) {
16313                synchronized (this) {
16314                    final long cachedKb = memInfo.getCachedSizeKb();
16315                    final long freeKb = memInfo.getFreeSizeKb();
16316                    final long zramKb = memInfo.getZramTotalSizeKb();
16317                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16318                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16319                            kernelKb*1024, nativeProcTotalPss*1024);
16320                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16321                            nativeProcTotalPss);
16322                }
16323            }
16324            if (!brief) {
16325                if (!isCompact) {
16326                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16327                    pw.print(" (status ");
16328                    switch (mLastMemoryLevel) {
16329                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16330                            pw.println("normal)");
16331                            break;
16332                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16333                            pw.println("moderate)");
16334                            break;
16335                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16336                            pw.println("low)");
16337                            break;
16338                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16339                            pw.println("critical)");
16340                            break;
16341                        default:
16342                            pw.print(mLastMemoryLevel);
16343                            pw.println(")");
16344                            break;
16345                    }
16346                    pw.print(" Free RAM: ");
16347                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16348                            + memInfo.getFreeSizeKb()));
16349                    pw.print(" (");
16350                    pw.print(stringifyKBSize(cachedPss));
16351                    pw.print(" cached pss + ");
16352                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16353                    pw.print(" cached kernel + ");
16354                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16355                    pw.println(" free)");
16356                } else {
16357                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16358                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16359                            + memInfo.getFreeSizeKb()); pw.print(",");
16360                    pw.println(totalPss - cachedPss);
16361                }
16362            }
16363            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16364                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16365                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16366            if (!isCompact) {
16367                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16368                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16369                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16370                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16371                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16372            } else {
16373                pw.print("lostram,"); pw.println(lostRAM);
16374            }
16375            if (!brief) {
16376                if (memInfo.getZramTotalSizeKb() != 0) {
16377                    if (!isCompact) {
16378                        pw.print("     ZRAM: ");
16379                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16380                                pw.print(" physical used for ");
16381                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16382                                        - memInfo.getSwapFreeSizeKb()));
16383                                pw.print(" in swap (");
16384                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16385                                pw.println(" total swap)");
16386                    } else {
16387                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16388                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16389                                pw.println(memInfo.getSwapFreeSizeKb());
16390                    }
16391                }
16392                final long[] ksm = getKsmInfo();
16393                if (!isCompact) {
16394                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16395                            || ksm[KSM_VOLATILE] != 0) {
16396                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16397                                pw.print(" saved from shared ");
16398                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16399                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16400                                pw.print(" unshared; ");
16401                                pw.print(stringifyKBSize(
16402                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16403                    }
16404                    pw.print("   Tuning: ");
16405                    pw.print(ActivityManager.staticGetMemoryClass());
16406                    pw.print(" (large ");
16407                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16408                    pw.print("), oom ");
16409                    pw.print(stringifySize(
16410                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16411                    pw.print(", restore limit ");
16412                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16413                    if (ActivityManager.isLowRamDeviceStatic()) {
16414                        pw.print(" (low-ram)");
16415                    }
16416                    if (ActivityManager.isHighEndGfx()) {
16417                        pw.print(" (high-end-gfx)");
16418                    }
16419                    pw.println();
16420                } else {
16421                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16422                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16423                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16424                    pw.print("tuning,");
16425                    pw.print(ActivityManager.staticGetMemoryClass());
16426                    pw.print(',');
16427                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16428                    pw.print(',');
16429                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16430                    if (ActivityManager.isLowRamDeviceStatic()) {
16431                        pw.print(",low-ram");
16432                    }
16433                    if (ActivityManager.isHighEndGfx()) {
16434                        pw.print(",high-end-gfx");
16435                    }
16436                    pw.println();
16437                }
16438            }
16439        }
16440    }
16441
16442    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16443            long memtrack, String name) {
16444        sb.append("  ");
16445        sb.append(ProcessList.makeOomAdjString(oomAdj));
16446        sb.append(' ');
16447        sb.append(ProcessList.makeProcStateString(procState));
16448        sb.append(' ');
16449        ProcessList.appendRamKb(sb, pss);
16450        sb.append(": ");
16451        sb.append(name);
16452        if (memtrack > 0) {
16453            sb.append(" (");
16454            sb.append(stringifyKBSize(memtrack));
16455            sb.append(" memtrack)");
16456        }
16457    }
16458
16459    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16460        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16461        sb.append(" (pid ");
16462        sb.append(mi.pid);
16463        sb.append(") ");
16464        sb.append(mi.adjType);
16465        sb.append('\n');
16466        if (mi.adjReason != null) {
16467            sb.append("                      ");
16468            sb.append(mi.adjReason);
16469            sb.append('\n');
16470        }
16471    }
16472
16473    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16474        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16475        for (int i=0, N=memInfos.size(); i<N; i++) {
16476            ProcessMemInfo mi = memInfos.get(i);
16477            infoMap.put(mi.pid, mi);
16478        }
16479        updateCpuStatsNow();
16480        long[] memtrackTmp = new long[1];
16481        synchronized (mProcessCpuTracker) {
16482            final int N = mProcessCpuTracker.countStats();
16483            for (int i=0; i<N; i++) {
16484                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16485                if (st.vsize > 0) {
16486                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16487                    if (pss > 0) {
16488                        if (infoMap.indexOfKey(st.pid) < 0) {
16489                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16490                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16491                            mi.pss = pss;
16492                            mi.memtrack = memtrackTmp[0];
16493                            memInfos.add(mi);
16494                        }
16495                    }
16496                }
16497            }
16498        }
16499
16500        long totalPss = 0;
16501        long totalMemtrack = 0;
16502        for (int i=0, N=memInfos.size(); i<N; i++) {
16503            ProcessMemInfo mi = memInfos.get(i);
16504            if (mi.pss == 0) {
16505                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16506                mi.memtrack = memtrackTmp[0];
16507            }
16508            totalPss += mi.pss;
16509            totalMemtrack += mi.memtrack;
16510        }
16511        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16512            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16513                if (lhs.oomAdj != rhs.oomAdj) {
16514                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16515                }
16516                if (lhs.pss != rhs.pss) {
16517                    return lhs.pss < rhs.pss ? 1 : -1;
16518                }
16519                return 0;
16520            }
16521        });
16522
16523        StringBuilder tag = new StringBuilder(128);
16524        StringBuilder stack = new StringBuilder(128);
16525        tag.append("Low on memory -- ");
16526        appendMemBucket(tag, totalPss, "total", false);
16527        appendMemBucket(stack, totalPss, "total", true);
16528
16529        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16530        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16531        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16532
16533        boolean firstLine = true;
16534        int lastOomAdj = Integer.MIN_VALUE;
16535        long extraNativeRam = 0;
16536        long extraNativeMemtrack = 0;
16537        long cachedPss = 0;
16538        for (int i=0, N=memInfos.size(); i<N; i++) {
16539            ProcessMemInfo mi = memInfos.get(i);
16540
16541            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16542                cachedPss += mi.pss;
16543            }
16544
16545            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16546                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16547                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16548                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16549                if (lastOomAdj != mi.oomAdj) {
16550                    lastOomAdj = mi.oomAdj;
16551                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16552                        tag.append(" / ");
16553                    }
16554                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16555                        if (firstLine) {
16556                            stack.append(":");
16557                            firstLine = false;
16558                        }
16559                        stack.append("\n\t at ");
16560                    } else {
16561                        stack.append("$");
16562                    }
16563                } else {
16564                    tag.append(" ");
16565                    stack.append("$");
16566                }
16567                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16568                    appendMemBucket(tag, mi.pss, mi.name, false);
16569                }
16570                appendMemBucket(stack, mi.pss, mi.name, true);
16571                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16572                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16573                    stack.append("(");
16574                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16575                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16576                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16577                            stack.append(":");
16578                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16579                        }
16580                    }
16581                    stack.append(")");
16582                }
16583            }
16584
16585            appendMemInfo(fullNativeBuilder, mi);
16586            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16587                // The short form only has native processes that are >= 512K.
16588                if (mi.pss >= 512) {
16589                    appendMemInfo(shortNativeBuilder, mi);
16590                } else {
16591                    extraNativeRam += mi.pss;
16592                    extraNativeMemtrack += mi.memtrack;
16593                }
16594            } else {
16595                // Short form has all other details, but if we have collected RAM
16596                // from smaller native processes let's dump a summary of that.
16597                if (extraNativeRam > 0) {
16598                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16599                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16600                    shortNativeBuilder.append('\n');
16601                    extraNativeRam = 0;
16602                }
16603                appendMemInfo(fullJavaBuilder, mi);
16604            }
16605        }
16606
16607        fullJavaBuilder.append("           ");
16608        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16609        fullJavaBuilder.append(": TOTAL");
16610        if (totalMemtrack > 0) {
16611            fullJavaBuilder.append(" (");
16612            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16613            fullJavaBuilder.append(" memtrack)");
16614        } else {
16615        }
16616        fullJavaBuilder.append("\n");
16617
16618        MemInfoReader memInfo = new MemInfoReader();
16619        memInfo.readMemInfo();
16620        final long[] infos = memInfo.getRawInfo();
16621
16622        StringBuilder memInfoBuilder = new StringBuilder(1024);
16623        Debug.getMemInfo(infos);
16624        memInfoBuilder.append("  MemInfo: ");
16625        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16626        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16627        memInfoBuilder.append(stringifyKBSize(
16628                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16629        memInfoBuilder.append(stringifyKBSize(
16630                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16631        memInfoBuilder.append(stringifyKBSize(
16632                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16633        memInfoBuilder.append("           ");
16634        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16635        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16636        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16637        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16638        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16639            memInfoBuilder.append("  ZRAM: ");
16640            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16641            memInfoBuilder.append(" RAM, ");
16642            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16643            memInfoBuilder.append(" swap total, ");
16644            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16645            memInfoBuilder.append(" swap free\n");
16646        }
16647        final long[] ksm = getKsmInfo();
16648        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16649                || ksm[KSM_VOLATILE] != 0) {
16650            memInfoBuilder.append("  KSM: ");
16651            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16652            memInfoBuilder.append(" saved from shared ");
16653            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16654            memInfoBuilder.append("\n       ");
16655            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16656            memInfoBuilder.append(" unshared; ");
16657            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16658            memInfoBuilder.append(" volatile\n");
16659        }
16660        memInfoBuilder.append("  Free RAM: ");
16661        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16662                + memInfo.getFreeSizeKb()));
16663        memInfoBuilder.append("\n");
16664        memInfoBuilder.append("  Used RAM: ");
16665        memInfoBuilder.append(stringifyKBSize(
16666                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16667        memInfoBuilder.append("\n");
16668        memInfoBuilder.append("  Lost RAM: ");
16669        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16670                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16671                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16672        memInfoBuilder.append("\n");
16673        Slog.i(TAG, "Low on memory:");
16674        Slog.i(TAG, shortNativeBuilder.toString());
16675        Slog.i(TAG, fullJavaBuilder.toString());
16676        Slog.i(TAG, memInfoBuilder.toString());
16677
16678        StringBuilder dropBuilder = new StringBuilder(1024);
16679        /*
16680        StringWriter oomSw = new StringWriter();
16681        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16682        StringWriter catSw = new StringWriter();
16683        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16684        String[] emptyArgs = new String[] { };
16685        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16686        oomPw.flush();
16687        String oomString = oomSw.toString();
16688        */
16689        dropBuilder.append("Low on memory:");
16690        dropBuilder.append(stack);
16691        dropBuilder.append('\n');
16692        dropBuilder.append(fullNativeBuilder);
16693        dropBuilder.append(fullJavaBuilder);
16694        dropBuilder.append('\n');
16695        dropBuilder.append(memInfoBuilder);
16696        dropBuilder.append('\n');
16697        /*
16698        dropBuilder.append(oomString);
16699        dropBuilder.append('\n');
16700        */
16701        StringWriter catSw = new StringWriter();
16702        synchronized (ActivityManagerService.this) {
16703            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16704            String[] emptyArgs = new String[] { };
16705            catPw.println();
16706            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16707            catPw.println();
16708            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16709                    false, null).dumpLocked();
16710            catPw.println();
16711            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16712            catPw.flush();
16713        }
16714        dropBuilder.append(catSw.toString());
16715        addErrorToDropBox("lowmem", null, "system_server", null,
16716                null, tag.toString(), dropBuilder.toString(), null, null);
16717        //Slog.i(TAG, "Sent to dropbox:");
16718        //Slog.i(TAG, dropBuilder.toString());
16719        synchronized (ActivityManagerService.this) {
16720            long now = SystemClock.uptimeMillis();
16721            if (mLastMemUsageReportTime < now) {
16722                mLastMemUsageReportTime = now;
16723            }
16724        }
16725    }
16726
16727    /**
16728     * Searches array of arguments for the specified string
16729     * @param args array of argument strings
16730     * @param value value to search for
16731     * @return true if the value is contained in the array
16732     */
16733    private static boolean scanArgs(String[] args, String value) {
16734        if (args != null) {
16735            for (String arg : args) {
16736                if (value.equals(arg)) {
16737                    return true;
16738                }
16739            }
16740        }
16741        return false;
16742    }
16743
16744    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16745            ContentProviderRecord cpr, boolean always) {
16746        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16747
16748        if (!inLaunching || always) {
16749            synchronized (cpr) {
16750                cpr.launchingApp = null;
16751                cpr.notifyAll();
16752            }
16753            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16754            String names[] = cpr.info.authority.split(";");
16755            for (int j = 0; j < names.length; j++) {
16756                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16757            }
16758        }
16759
16760        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16761            ContentProviderConnection conn = cpr.connections.get(i);
16762            if (conn.waiting) {
16763                // If this connection is waiting for the provider, then we don't
16764                // need to mess with its process unless we are always removing
16765                // or for some reason the provider is not currently launching.
16766                if (inLaunching && !always) {
16767                    continue;
16768                }
16769            }
16770            ProcessRecord capp = conn.client;
16771            conn.dead = true;
16772            if (conn.stableCount > 0) {
16773                if (!capp.persistent && capp.thread != null
16774                        && capp.pid != 0
16775                        && capp.pid != MY_PID) {
16776                    capp.kill("depends on provider "
16777                            + cpr.name.flattenToShortString()
16778                            + " in dying proc " + (proc != null ? proc.processName : "??")
16779                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16780                }
16781            } else if (capp.thread != null && conn.provider.provider != null) {
16782                try {
16783                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16784                } catch (RemoteException e) {
16785                }
16786                // In the protocol here, we don't expect the client to correctly
16787                // clean up this connection, we'll just remove it.
16788                cpr.connections.remove(i);
16789                if (conn.client.conProviders.remove(conn)) {
16790                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16791                }
16792            }
16793        }
16794
16795        if (inLaunching && always) {
16796            mLaunchingProviders.remove(cpr);
16797        }
16798        return inLaunching;
16799    }
16800
16801    /**
16802     * Main code for cleaning up a process when it has gone away.  This is
16803     * called both as a result of the process dying, or directly when stopping
16804     * a process when running in single process mode.
16805     *
16806     * @return Returns true if the given process has been restarted, so the
16807     * app that was passed in must remain on the process lists.
16808     */
16809    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16810            boolean restarting, boolean allowRestart, int index) {
16811        if (index >= 0) {
16812            removeLruProcessLocked(app);
16813            ProcessList.remove(app.pid);
16814        }
16815
16816        mProcessesToGc.remove(app);
16817        mPendingPssProcesses.remove(app);
16818
16819        // Dismiss any open dialogs.
16820        if (app.crashDialog != null && !app.forceCrashReport) {
16821            app.crashDialog.dismiss();
16822            app.crashDialog = null;
16823        }
16824        if (app.anrDialog != null) {
16825            app.anrDialog.dismiss();
16826            app.anrDialog = null;
16827        }
16828        if (app.waitDialog != null) {
16829            app.waitDialog.dismiss();
16830            app.waitDialog = null;
16831        }
16832
16833        app.crashing = false;
16834        app.notResponding = false;
16835
16836        app.resetPackageList(mProcessStats);
16837        app.unlinkDeathRecipient();
16838        app.makeInactive(mProcessStats);
16839        app.waitingToKill = null;
16840        app.forcingToForeground = null;
16841        updateProcessForegroundLocked(app, false, false);
16842        app.foregroundActivities = false;
16843        app.hasShownUi = false;
16844        app.treatLikeActivity = false;
16845        app.hasAboveClient = false;
16846        app.hasClientActivities = false;
16847
16848        mServices.killServicesLocked(app, allowRestart);
16849
16850        boolean restart = false;
16851
16852        // Remove published content providers.
16853        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16854            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16855            final boolean always = app.bad || !allowRestart;
16856            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16857            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16858                // We left the provider in the launching list, need to
16859                // restart it.
16860                restart = true;
16861            }
16862
16863            cpr.provider = null;
16864            cpr.proc = null;
16865        }
16866        app.pubProviders.clear();
16867
16868        // Take care of any launching providers waiting for this process.
16869        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16870            restart = true;
16871        }
16872
16873        // Unregister from connected content providers.
16874        if (!app.conProviders.isEmpty()) {
16875            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16876                ContentProviderConnection conn = app.conProviders.get(i);
16877                conn.provider.connections.remove(conn);
16878                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16879                        conn.provider.name);
16880            }
16881            app.conProviders.clear();
16882        }
16883
16884        // At this point there may be remaining entries in mLaunchingProviders
16885        // where we were the only one waiting, so they are no longer of use.
16886        // Look for these and clean up if found.
16887        // XXX Commented out for now.  Trying to figure out a way to reproduce
16888        // the actual situation to identify what is actually going on.
16889        if (false) {
16890            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16891                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16892                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16893                    synchronized (cpr) {
16894                        cpr.launchingApp = null;
16895                        cpr.notifyAll();
16896                    }
16897                }
16898            }
16899        }
16900
16901        skipCurrentReceiverLocked(app);
16902
16903        // Unregister any receivers.
16904        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16905            removeReceiverLocked(app.receivers.valueAt(i));
16906        }
16907        app.receivers.clear();
16908
16909        // If the app is undergoing backup, tell the backup manager about it
16910        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16911            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16912                    + mBackupTarget.appInfo + " died during backup");
16913            try {
16914                IBackupManager bm = IBackupManager.Stub.asInterface(
16915                        ServiceManager.getService(Context.BACKUP_SERVICE));
16916                bm.agentDisconnected(app.info.packageName);
16917            } catch (RemoteException e) {
16918                // can't happen; backup manager is local
16919            }
16920        }
16921
16922        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16923            ProcessChangeItem item = mPendingProcessChanges.get(i);
16924            if (item.pid == app.pid) {
16925                mPendingProcessChanges.remove(i);
16926                mAvailProcessChanges.add(item);
16927            }
16928        }
16929        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16930                null).sendToTarget();
16931
16932        // If the caller is restarting this app, then leave it in its
16933        // current lists and let the caller take care of it.
16934        if (restarting) {
16935            return false;
16936        }
16937
16938        if (!app.persistent || app.isolated) {
16939            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16940                    "Removing non-persistent process during cleanup: " + app);
16941            removeProcessNameLocked(app.processName, app.uid);
16942            if (mHeavyWeightProcess == app) {
16943                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16944                        mHeavyWeightProcess.userId, 0));
16945                mHeavyWeightProcess = null;
16946            }
16947        } else if (!app.removed) {
16948            // This app is persistent, so we need to keep its record around.
16949            // If it is not already on the pending app list, add it there
16950            // and start a new process for it.
16951            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16952                mPersistentStartingProcesses.add(app);
16953                restart = true;
16954            }
16955        }
16956        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16957                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16958        mProcessesOnHold.remove(app);
16959
16960        if (app == mHomeProcess) {
16961            mHomeProcess = null;
16962        }
16963        if (app == mPreviousProcess) {
16964            mPreviousProcess = null;
16965        }
16966
16967        if (restart && !app.isolated) {
16968            // We have components that still need to be running in the
16969            // process, so re-launch it.
16970            if (index < 0) {
16971                ProcessList.remove(app.pid);
16972            }
16973            addProcessNameLocked(app);
16974            startProcessLocked(app, "restart", app.processName);
16975            return true;
16976        } else if (app.pid > 0 && app.pid != MY_PID) {
16977            // Goodbye!
16978            boolean removed;
16979            synchronized (mPidsSelfLocked) {
16980                mPidsSelfLocked.remove(app.pid);
16981                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16982            }
16983            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16984            if (app.isolated) {
16985                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16986            }
16987            app.setPid(0);
16988        }
16989        return false;
16990    }
16991
16992    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16993        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16994            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16995            if (cpr.launchingApp == app) {
16996                return true;
16997            }
16998        }
16999        return false;
17000    }
17001
17002    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17003        // Look through the content providers we are waiting to have launched,
17004        // and if any run in this process then either schedule a restart of
17005        // the process or kill the client waiting for it if this process has
17006        // gone bad.
17007        boolean restart = false;
17008        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17009            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17010            if (cpr.launchingApp == app) {
17011                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17012                    restart = true;
17013                } else {
17014                    removeDyingProviderLocked(app, cpr, true);
17015                }
17016            }
17017        }
17018        return restart;
17019    }
17020
17021    // =========================================================
17022    // SERVICES
17023    // =========================================================
17024
17025    @Override
17026    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17027            int flags) {
17028        enforceNotIsolatedCaller("getServices");
17029        synchronized (this) {
17030            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17031        }
17032    }
17033
17034    @Override
17035    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17036        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17037        synchronized (this) {
17038            return mServices.getRunningServiceControlPanelLocked(name);
17039        }
17040    }
17041
17042    @Override
17043    public ComponentName startService(IApplicationThread caller, Intent service,
17044            String resolvedType, String callingPackage, int userId)
17045            throws TransactionTooLargeException {
17046        enforceNotIsolatedCaller("startService");
17047        // Refuse possible leaked file descriptors
17048        if (service != null && service.hasFileDescriptors() == true) {
17049            throw new IllegalArgumentException("File descriptors passed in Intent");
17050        }
17051
17052        if (callingPackage == null) {
17053            throw new IllegalArgumentException("callingPackage cannot be null");
17054        }
17055
17056        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17057                "startService: " + service + " type=" + resolvedType);
17058        synchronized(this) {
17059            final int callingPid = Binder.getCallingPid();
17060            final int callingUid = Binder.getCallingUid();
17061            final long origId = Binder.clearCallingIdentity();
17062            ComponentName res = mServices.startServiceLocked(caller, service,
17063                    resolvedType, callingPid, callingUid, callingPackage, userId);
17064            Binder.restoreCallingIdentity(origId);
17065            return res;
17066        }
17067    }
17068
17069    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17070            String callingPackage, int userId)
17071            throws TransactionTooLargeException {
17072        synchronized(this) {
17073            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17074                    "startServiceInPackage: " + service + " type=" + resolvedType);
17075            final long origId = Binder.clearCallingIdentity();
17076            ComponentName res = mServices.startServiceLocked(null, service,
17077                    resolvedType, -1, uid, callingPackage, userId);
17078            Binder.restoreCallingIdentity(origId);
17079            return res;
17080        }
17081    }
17082
17083    @Override
17084    public int stopService(IApplicationThread caller, Intent service,
17085            String resolvedType, int userId) {
17086        enforceNotIsolatedCaller("stopService");
17087        // Refuse possible leaked file descriptors
17088        if (service != null && service.hasFileDescriptors() == true) {
17089            throw new IllegalArgumentException("File descriptors passed in Intent");
17090        }
17091
17092        synchronized(this) {
17093            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17094        }
17095    }
17096
17097    @Override
17098    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17099        enforceNotIsolatedCaller("peekService");
17100        // Refuse possible leaked file descriptors
17101        if (service != null && service.hasFileDescriptors() == true) {
17102            throw new IllegalArgumentException("File descriptors passed in Intent");
17103        }
17104
17105        if (callingPackage == null) {
17106            throw new IllegalArgumentException("callingPackage cannot be null");
17107        }
17108
17109        synchronized(this) {
17110            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17111        }
17112    }
17113
17114    @Override
17115    public boolean stopServiceToken(ComponentName className, IBinder token,
17116            int startId) {
17117        synchronized(this) {
17118            return mServices.stopServiceTokenLocked(className, token, startId);
17119        }
17120    }
17121
17122    @Override
17123    public void setServiceForeground(ComponentName className, IBinder token,
17124            int id, Notification notification, int flags) {
17125        synchronized(this) {
17126            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17127        }
17128    }
17129
17130    @Override
17131    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17132            boolean requireFull, String name, String callerPackage) {
17133        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17134                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17135    }
17136
17137    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17138            String className, int flags) {
17139        boolean result = false;
17140        // For apps that don't have pre-defined UIDs, check for permission
17141        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17142            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17143                if (ActivityManager.checkUidPermission(
17144                        INTERACT_ACROSS_USERS,
17145                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17146                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17147                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17148                            + " requests FLAG_SINGLE_USER, but app does not hold "
17149                            + INTERACT_ACROSS_USERS;
17150                    Slog.w(TAG, msg);
17151                    throw new SecurityException(msg);
17152                }
17153                // Permission passed
17154                result = true;
17155            }
17156        } else if ("system".equals(componentProcessName)) {
17157            result = true;
17158        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17159            // Phone app and persistent apps are allowed to export singleuser providers.
17160            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17161                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17162        }
17163        if (DEBUG_MU) Slog.v(TAG_MU,
17164                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17165                + Integer.toHexString(flags) + ") = " + result);
17166        return result;
17167    }
17168
17169    /**
17170     * Checks to see if the caller is in the same app as the singleton
17171     * component, or the component is in a special app. It allows special apps
17172     * to export singleton components but prevents exporting singleton
17173     * components for regular apps.
17174     */
17175    boolean isValidSingletonCall(int callingUid, int componentUid) {
17176        int componentAppId = UserHandle.getAppId(componentUid);
17177        return UserHandle.isSameApp(callingUid, componentUid)
17178                || componentAppId == Process.SYSTEM_UID
17179                || componentAppId == Process.PHONE_UID
17180                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17181                        == PackageManager.PERMISSION_GRANTED;
17182    }
17183
17184    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17185            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17186            int userId) throws TransactionTooLargeException {
17187        enforceNotIsolatedCaller("bindService");
17188
17189        // Refuse possible leaked file descriptors
17190        if (service != null && service.hasFileDescriptors() == true) {
17191            throw new IllegalArgumentException("File descriptors passed in Intent");
17192        }
17193
17194        if (callingPackage == null) {
17195            throw new IllegalArgumentException("callingPackage cannot be null");
17196        }
17197
17198        synchronized(this) {
17199            return mServices.bindServiceLocked(caller, token, service,
17200                    resolvedType, connection, flags, callingPackage, userId);
17201        }
17202    }
17203
17204    public boolean unbindService(IServiceConnection connection) {
17205        synchronized (this) {
17206            return mServices.unbindServiceLocked(connection);
17207        }
17208    }
17209
17210    public void publishService(IBinder token, Intent intent, IBinder service) {
17211        // Refuse possible leaked file descriptors
17212        if (intent != null && intent.hasFileDescriptors() == true) {
17213            throw new IllegalArgumentException("File descriptors passed in Intent");
17214        }
17215
17216        synchronized(this) {
17217            if (!(token instanceof ServiceRecord)) {
17218                throw new IllegalArgumentException("Invalid service token");
17219            }
17220            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17221        }
17222    }
17223
17224    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17225        // Refuse possible leaked file descriptors
17226        if (intent != null && intent.hasFileDescriptors() == true) {
17227            throw new IllegalArgumentException("File descriptors passed in Intent");
17228        }
17229
17230        synchronized(this) {
17231            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17232        }
17233    }
17234
17235    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17236        synchronized(this) {
17237            if (!(token instanceof ServiceRecord)) {
17238                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17239                throw new IllegalArgumentException("Invalid service token");
17240            }
17241            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17242        }
17243    }
17244
17245    // =========================================================
17246    // BACKUP AND RESTORE
17247    // =========================================================
17248
17249    // Cause the target app to be launched if necessary and its backup agent
17250    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17251    // activity manager to announce its creation.
17252    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17253        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17254        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17255
17256        IPackageManager pm = AppGlobals.getPackageManager();
17257        ApplicationInfo app = null;
17258        try {
17259            app = pm.getApplicationInfo(packageName, 0, userId);
17260        } catch (RemoteException e) {
17261            // can't happen; package manager is process-local
17262        }
17263        if (app == null) {
17264            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17265            return false;
17266        }
17267
17268        synchronized(this) {
17269            // !!! TODO: currently no check here that we're already bound
17270            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17271            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17272            synchronized (stats) {
17273                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17274            }
17275
17276            // Backup agent is now in use, its package can't be stopped.
17277            try {
17278                AppGlobals.getPackageManager().setPackageStoppedState(
17279                        app.packageName, false, UserHandle.getUserId(app.uid));
17280            } catch (RemoteException e) {
17281            } catch (IllegalArgumentException e) {
17282                Slog.w(TAG, "Failed trying to unstop package "
17283                        + app.packageName + ": " + e);
17284            }
17285
17286            BackupRecord r = new BackupRecord(ss, app, backupMode);
17287            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17288                    ? new ComponentName(app.packageName, app.backupAgentName)
17289                    : new ComponentName("android", "FullBackupAgent");
17290            // startProcessLocked() returns existing proc's record if it's already running
17291            ProcessRecord proc = startProcessLocked(app.processName, app,
17292                    false, 0, "backup", hostingName, false, false, false);
17293            if (proc == null) {
17294                Slog.e(TAG, "Unable to start backup agent process " + r);
17295                return false;
17296            }
17297
17298            // If the app is a regular app (uid >= 10000) and not the system server or phone
17299            // process, etc, then mark it as being in full backup so that certain calls to the
17300            // process can be blocked. This is not reset to false anywhere because we kill the
17301            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17302            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17303                proc.inFullBackup = true;
17304            }
17305            r.app = proc;
17306            mBackupTarget = r;
17307            mBackupAppName = app.packageName;
17308
17309            // Try not to kill the process during backup
17310            updateOomAdjLocked(proc);
17311
17312            // If the process is already attached, schedule the creation of the backup agent now.
17313            // If it is not yet live, this will be done when it attaches to the framework.
17314            if (proc.thread != null) {
17315                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17316                try {
17317                    proc.thread.scheduleCreateBackupAgent(app,
17318                            compatibilityInfoForPackageLocked(app), backupMode);
17319                } catch (RemoteException e) {
17320                    // Will time out on the backup manager side
17321                }
17322            } else {
17323                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17324            }
17325            // Invariants: at this point, the target app process exists and the application
17326            // is either already running or in the process of coming up.  mBackupTarget and
17327            // mBackupAppName describe the app, so that when it binds back to the AM we
17328            // know that it's scheduled for a backup-agent operation.
17329        }
17330
17331        return true;
17332    }
17333
17334    @Override
17335    public void clearPendingBackup() {
17336        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17337        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17338
17339        synchronized (this) {
17340            mBackupTarget = null;
17341            mBackupAppName = null;
17342        }
17343    }
17344
17345    // A backup agent has just come up
17346    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17347        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17348                + " = " + agent);
17349
17350        synchronized(this) {
17351            if (!agentPackageName.equals(mBackupAppName)) {
17352                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17353                return;
17354            }
17355        }
17356
17357        long oldIdent = Binder.clearCallingIdentity();
17358        try {
17359            IBackupManager bm = IBackupManager.Stub.asInterface(
17360                    ServiceManager.getService(Context.BACKUP_SERVICE));
17361            bm.agentConnected(agentPackageName, agent);
17362        } catch (RemoteException e) {
17363            // can't happen; the backup manager service is local
17364        } catch (Exception e) {
17365            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17366            e.printStackTrace();
17367        } finally {
17368            Binder.restoreCallingIdentity(oldIdent);
17369        }
17370    }
17371
17372    // done with this agent
17373    public void unbindBackupAgent(ApplicationInfo appInfo) {
17374        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17375        if (appInfo == null) {
17376            Slog.w(TAG, "unbind backup agent for null app");
17377            return;
17378        }
17379
17380        synchronized(this) {
17381            try {
17382                if (mBackupAppName == null) {
17383                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17384                    return;
17385                }
17386
17387                if (!mBackupAppName.equals(appInfo.packageName)) {
17388                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17389                    return;
17390                }
17391
17392                // Not backing this app up any more; reset its OOM adjustment
17393                final ProcessRecord proc = mBackupTarget.app;
17394                updateOomAdjLocked(proc);
17395
17396                // If the app crashed during backup, 'thread' will be null here
17397                if (proc.thread != null) {
17398                    try {
17399                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17400                                compatibilityInfoForPackageLocked(appInfo));
17401                    } catch (Exception e) {
17402                        Slog.e(TAG, "Exception when unbinding backup agent:");
17403                        e.printStackTrace();
17404                    }
17405                }
17406            } finally {
17407                mBackupTarget = null;
17408                mBackupAppName = null;
17409            }
17410        }
17411    }
17412    // =========================================================
17413    // BROADCASTS
17414    // =========================================================
17415
17416    boolean isPendingBroadcastProcessLocked(int pid) {
17417        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17418                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17419    }
17420
17421    void skipPendingBroadcastLocked(int pid) {
17422            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17423            for (BroadcastQueue queue : mBroadcastQueues) {
17424                queue.skipPendingBroadcastLocked(pid);
17425            }
17426    }
17427
17428    // The app just attached; send any pending broadcasts that it should receive
17429    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17430        boolean didSomething = false;
17431        for (BroadcastQueue queue : mBroadcastQueues) {
17432            didSomething |= queue.sendPendingBroadcastsLocked(app);
17433        }
17434        return didSomething;
17435    }
17436
17437    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17438            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17439        enforceNotIsolatedCaller("registerReceiver");
17440        ArrayList<Intent> stickyIntents = null;
17441        ProcessRecord callerApp = null;
17442        int callingUid;
17443        int callingPid;
17444        synchronized(this) {
17445            if (caller != null) {
17446                callerApp = getRecordForAppLocked(caller);
17447                if (callerApp == null) {
17448                    throw new SecurityException(
17449                            "Unable to find app for caller " + caller
17450                            + " (pid=" + Binder.getCallingPid()
17451                            + ") when registering receiver " + receiver);
17452                }
17453                if (callerApp.info.uid != Process.SYSTEM_UID &&
17454                        !callerApp.pkgList.containsKey(callerPackage) &&
17455                        !"android".equals(callerPackage)) {
17456                    throw new SecurityException("Given caller package " + callerPackage
17457                            + " is not running in process " + callerApp);
17458                }
17459                callingUid = callerApp.info.uid;
17460                callingPid = callerApp.pid;
17461            } else {
17462                callerPackage = null;
17463                callingUid = Binder.getCallingUid();
17464                callingPid = Binder.getCallingPid();
17465            }
17466
17467            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17468                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17469
17470            Iterator<String> actions = filter.actionsIterator();
17471            if (actions == null) {
17472                ArrayList<String> noAction = new ArrayList<String>(1);
17473                noAction.add(null);
17474                actions = noAction.iterator();
17475            }
17476
17477            // Collect stickies of users
17478            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17479            while (actions.hasNext()) {
17480                String action = actions.next();
17481                for (int id : userIds) {
17482                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17483                    if (stickies != null) {
17484                        ArrayList<Intent> intents = stickies.get(action);
17485                        if (intents != null) {
17486                            if (stickyIntents == null) {
17487                                stickyIntents = new ArrayList<Intent>();
17488                            }
17489                            stickyIntents.addAll(intents);
17490                        }
17491                    }
17492                }
17493            }
17494        }
17495
17496        ArrayList<Intent> allSticky = null;
17497        if (stickyIntents != null) {
17498            final ContentResolver resolver = mContext.getContentResolver();
17499            // Look for any matching sticky broadcasts...
17500            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17501                Intent intent = stickyIntents.get(i);
17502                // If intent has scheme "content", it will need to acccess
17503                // provider that needs to lock mProviderMap in ActivityThread
17504                // and also it may need to wait application response, so we
17505                // cannot lock ActivityManagerService here.
17506                if (filter.match(resolver, intent, true, TAG) >= 0) {
17507                    if (allSticky == null) {
17508                        allSticky = new ArrayList<Intent>();
17509                    }
17510                    allSticky.add(intent);
17511                }
17512            }
17513        }
17514
17515        // The first sticky in the list is returned directly back to the client.
17516        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17517        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17518        if (receiver == null) {
17519            return sticky;
17520        }
17521
17522        synchronized (this) {
17523            if (callerApp != null && (callerApp.thread == null
17524                    || callerApp.thread.asBinder() != caller.asBinder())) {
17525                // Original caller already died
17526                return null;
17527            }
17528            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17529            if (rl == null) {
17530                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17531                        userId, receiver);
17532                if (rl.app != null) {
17533                    rl.app.receivers.add(rl);
17534                } else {
17535                    try {
17536                        receiver.asBinder().linkToDeath(rl, 0);
17537                    } catch (RemoteException e) {
17538                        return sticky;
17539                    }
17540                    rl.linkedToDeath = true;
17541                }
17542                mRegisteredReceivers.put(receiver.asBinder(), rl);
17543            } else if (rl.uid != callingUid) {
17544                throw new IllegalArgumentException(
17545                        "Receiver requested to register for uid " + callingUid
17546                        + " was previously registered for uid " + rl.uid);
17547            } else if (rl.pid != callingPid) {
17548                throw new IllegalArgumentException(
17549                        "Receiver requested to register for pid " + callingPid
17550                        + " was previously registered for pid " + rl.pid);
17551            } else if (rl.userId != userId) {
17552                throw new IllegalArgumentException(
17553                        "Receiver requested to register for user " + userId
17554                        + " was previously registered for user " + rl.userId);
17555            }
17556            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17557                    permission, callingUid, userId);
17558            rl.add(bf);
17559            if (!bf.debugCheck()) {
17560                Slog.w(TAG, "==> For Dynamic broadcast");
17561            }
17562            mReceiverResolver.addFilter(bf);
17563
17564            // Enqueue broadcasts for all existing stickies that match
17565            // this filter.
17566            if (allSticky != null) {
17567                ArrayList receivers = new ArrayList();
17568                receivers.add(bf);
17569
17570                final int stickyCount = allSticky.size();
17571                for (int i = 0; i < stickyCount; i++) {
17572                    Intent intent = allSticky.get(i);
17573                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17574                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17575                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17576                            null, 0, null, null, false, true, true, -1);
17577                    queue.enqueueParallelBroadcastLocked(r);
17578                    queue.scheduleBroadcastsLocked();
17579                }
17580            }
17581
17582            return sticky;
17583        }
17584    }
17585
17586    public void unregisterReceiver(IIntentReceiver receiver) {
17587        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17588
17589        final long origId = Binder.clearCallingIdentity();
17590        try {
17591            boolean doTrim = false;
17592
17593            synchronized(this) {
17594                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17595                if (rl != null) {
17596                    final BroadcastRecord r = rl.curBroadcast;
17597                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17598                        final boolean doNext = r.queue.finishReceiverLocked(
17599                                r, r.resultCode, r.resultData, r.resultExtras,
17600                                r.resultAbort, false);
17601                        if (doNext) {
17602                            doTrim = true;
17603                            r.queue.processNextBroadcast(false);
17604                        }
17605                    }
17606
17607                    if (rl.app != null) {
17608                        rl.app.receivers.remove(rl);
17609                    }
17610                    removeReceiverLocked(rl);
17611                    if (rl.linkedToDeath) {
17612                        rl.linkedToDeath = false;
17613                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17614                    }
17615                }
17616            }
17617
17618            // If we actually concluded any broadcasts, we might now be able
17619            // to trim the recipients' apps from our working set
17620            if (doTrim) {
17621                trimApplications();
17622                return;
17623            }
17624
17625        } finally {
17626            Binder.restoreCallingIdentity(origId);
17627        }
17628    }
17629
17630    void removeReceiverLocked(ReceiverList rl) {
17631        mRegisteredReceivers.remove(rl.receiver.asBinder());
17632        for (int i = rl.size() - 1; i >= 0; i--) {
17633            mReceiverResolver.removeFilter(rl.get(i));
17634        }
17635    }
17636
17637    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17638        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17639            ProcessRecord r = mLruProcesses.get(i);
17640            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17641                try {
17642                    r.thread.dispatchPackageBroadcast(cmd, packages);
17643                } catch (RemoteException ex) {
17644                }
17645            }
17646        }
17647    }
17648
17649    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17650            int callingUid, int[] users) {
17651        // TODO: come back and remove this assumption to triage all broadcasts
17652        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17653
17654        List<ResolveInfo> receivers = null;
17655        try {
17656            HashSet<ComponentName> singleUserReceivers = null;
17657            boolean scannedFirstReceivers = false;
17658            for (int user : users) {
17659                // Skip users that have Shell restrictions, with exception of always permitted
17660                // Shell broadcasts
17661                if (callingUid == Process.SHELL_UID
17662                        && mUserController.hasUserRestriction(
17663                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17664                        && !isPermittedShellBroadcast(intent)) {
17665                    continue;
17666                }
17667                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17668                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17669                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17670                    // If this is not the system user, we need to check for
17671                    // any receivers that should be filtered out.
17672                    for (int i=0; i<newReceivers.size(); i++) {
17673                        ResolveInfo ri = newReceivers.get(i);
17674                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17675                            newReceivers.remove(i);
17676                            i--;
17677                        }
17678                    }
17679                }
17680                if (newReceivers != null && newReceivers.size() == 0) {
17681                    newReceivers = null;
17682                }
17683                if (receivers == null) {
17684                    receivers = newReceivers;
17685                } else if (newReceivers != null) {
17686                    // We need to concatenate the additional receivers
17687                    // found with what we have do far.  This would be easy,
17688                    // but we also need to de-dup any receivers that are
17689                    // singleUser.
17690                    if (!scannedFirstReceivers) {
17691                        // Collect any single user receivers we had already retrieved.
17692                        scannedFirstReceivers = true;
17693                        for (int i=0; i<receivers.size(); i++) {
17694                            ResolveInfo ri = receivers.get(i);
17695                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17696                                ComponentName cn = new ComponentName(
17697                                        ri.activityInfo.packageName, ri.activityInfo.name);
17698                                if (singleUserReceivers == null) {
17699                                    singleUserReceivers = new HashSet<ComponentName>();
17700                                }
17701                                singleUserReceivers.add(cn);
17702                            }
17703                        }
17704                    }
17705                    // Add the new results to the existing results, tracking
17706                    // and de-dupping single user receivers.
17707                    for (int i=0; i<newReceivers.size(); i++) {
17708                        ResolveInfo ri = newReceivers.get(i);
17709                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17710                            ComponentName cn = new ComponentName(
17711                                    ri.activityInfo.packageName, ri.activityInfo.name);
17712                            if (singleUserReceivers == null) {
17713                                singleUserReceivers = new HashSet<ComponentName>();
17714                            }
17715                            if (!singleUserReceivers.contains(cn)) {
17716                                singleUserReceivers.add(cn);
17717                                receivers.add(ri);
17718                            }
17719                        } else {
17720                            receivers.add(ri);
17721                        }
17722                    }
17723                }
17724            }
17725        } catch (RemoteException ex) {
17726            // pm is in same process, this will never happen.
17727        }
17728        return receivers;
17729    }
17730
17731    private boolean isPermittedShellBroadcast(Intent intent) {
17732        // remote bugreport should always be allowed to be taken
17733        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17734    }
17735
17736    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17737            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17738        final String action = intent.getAction();
17739        if (isProtectedBroadcast
17740                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17741                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17742                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17743                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17744                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17745                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17746                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17747                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17748                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17749                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17750            // Broadcast is either protected, or it's a public action that
17751            // we've relaxed, so it's fine for system internals to send.
17752            return;
17753        }
17754
17755        // This broadcast may be a problem...  but there are often system components that
17756        // want to send an internal broadcast to themselves, which is annoying to have to
17757        // explicitly list each action as a protected broadcast, so we will check for that
17758        // one safe case and allow it: an explicit broadcast, only being received by something
17759        // that has protected itself.
17760        if (receivers != null && receivers.size() > 0
17761                && (intent.getPackage() != null || intent.getComponent() != null)) {
17762            boolean allProtected = true;
17763            for (int i = receivers.size()-1; i >= 0; i--) {
17764                Object target = receivers.get(i);
17765                if (target instanceof ResolveInfo) {
17766                    ResolveInfo ri = (ResolveInfo)target;
17767                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17768                        allProtected = false;
17769                        break;
17770                    }
17771                } else {
17772                    BroadcastFilter bf = (BroadcastFilter)target;
17773                    if (bf.requiredPermission == null) {
17774                        allProtected = false;
17775                        break;
17776                    }
17777                }
17778            }
17779            if (allProtected) {
17780                // All safe!
17781                return;
17782            }
17783        }
17784
17785        // The vast majority of broadcasts sent from system internals
17786        // should be protected to avoid security holes, so yell loudly
17787        // to ensure we examine these cases.
17788        if (callerApp != null) {
17789            Log.wtf(TAG, "Sending non-protected broadcast " + action
17790                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17791                    new Throwable());
17792        } else {
17793            Log.wtf(TAG, "Sending non-protected broadcast " + action
17794                            + " from system uid " + UserHandle.formatUid(callingUid)
17795                            + " pkg " + callerPackage,
17796                    new Throwable());
17797        }
17798    }
17799
17800    final int broadcastIntentLocked(ProcessRecord callerApp,
17801            String callerPackage, Intent intent, String resolvedType,
17802            IIntentReceiver resultTo, int resultCode, String resultData,
17803            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17804            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17805        intent = new Intent(intent);
17806
17807        // By default broadcasts do not go to stopped apps.
17808        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17809
17810        // If we have not finished booting, don't allow this to launch new processes.
17811        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17812            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17813        }
17814
17815        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17816                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17817                + " ordered=" + ordered + " userid=" + userId);
17818        if ((resultTo != null) && !ordered) {
17819            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17820        }
17821
17822        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17823                ALLOW_NON_FULL, "broadcast", callerPackage);
17824
17825        // Make sure that the user who is receiving this broadcast is running.
17826        // If not, we will just skip it. Make an exception for shutdown broadcasts
17827        // and upgrade steps.
17828
17829        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17830            if ((callingUid != Process.SYSTEM_UID
17831                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17832                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17833                Slog.w(TAG, "Skipping broadcast of " + intent
17834                        + ": user " + userId + " is stopped");
17835                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17836            }
17837        }
17838
17839        BroadcastOptions brOptions = null;
17840        if (bOptions != null) {
17841            brOptions = new BroadcastOptions(bOptions);
17842            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17843                // See if the caller is allowed to do this.  Note we are checking against
17844                // the actual real caller (not whoever provided the operation as say a
17845                // PendingIntent), because that who is actually supplied the arguments.
17846                if (checkComponentPermission(
17847                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17848                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17849                        != PackageManager.PERMISSION_GRANTED) {
17850                    String msg = "Permission Denial: " + intent.getAction()
17851                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17852                            + ", uid=" + callingUid + ")"
17853                            + " requires "
17854                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17855                    Slog.w(TAG, msg);
17856                    throw new SecurityException(msg);
17857                }
17858            }
17859        }
17860
17861        // Verify that protected broadcasts are only being sent by system code,
17862        // and that system code is only sending protected broadcasts.
17863        final String action = intent.getAction();
17864        final boolean isProtectedBroadcast;
17865        try {
17866            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17867        } catch (RemoteException e) {
17868            Slog.w(TAG, "Remote exception", e);
17869            return ActivityManager.BROADCAST_SUCCESS;
17870        }
17871
17872        final boolean isCallerSystem;
17873        switch (UserHandle.getAppId(callingUid)) {
17874            case Process.ROOT_UID:
17875            case Process.SYSTEM_UID:
17876            case Process.PHONE_UID:
17877            case Process.BLUETOOTH_UID:
17878            case Process.NFC_UID:
17879                isCallerSystem = true;
17880                break;
17881            default:
17882                isCallerSystem = (callerApp != null) && callerApp.persistent;
17883                break;
17884        }
17885
17886        // First line security check before anything else: stop non-system apps from
17887        // sending protected broadcasts.
17888        if (!isCallerSystem) {
17889            if (isProtectedBroadcast) {
17890                String msg = "Permission Denial: not allowed to send broadcast "
17891                        + action + " from pid="
17892                        + callingPid + ", uid=" + callingUid;
17893                Slog.w(TAG, msg);
17894                throw new SecurityException(msg);
17895
17896            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17897                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17898                // Special case for compatibility: we don't want apps to send this,
17899                // but historically it has not been protected and apps may be using it
17900                // to poke their own app widget.  So, instead of making it protected,
17901                // just limit it to the caller.
17902                if (callerPackage == null) {
17903                    String msg = "Permission Denial: not allowed to send broadcast "
17904                            + action + " from unknown caller.";
17905                    Slog.w(TAG, msg);
17906                    throw new SecurityException(msg);
17907                } else if (intent.getComponent() != null) {
17908                    // They are good enough to send to an explicit component...  verify
17909                    // it is being sent to the calling app.
17910                    if (!intent.getComponent().getPackageName().equals(
17911                            callerPackage)) {
17912                        String msg = "Permission Denial: not allowed to send broadcast "
17913                                + action + " to "
17914                                + intent.getComponent().getPackageName() + " from "
17915                                + callerPackage;
17916                        Slog.w(TAG, msg);
17917                        throw new SecurityException(msg);
17918                    }
17919                } else {
17920                    // Limit broadcast to their own package.
17921                    intent.setPackage(callerPackage);
17922                }
17923            }
17924        }
17925
17926        if (action != null) {
17927            switch (action) {
17928                case Intent.ACTION_UID_REMOVED:
17929                case Intent.ACTION_PACKAGE_REMOVED:
17930                case Intent.ACTION_PACKAGE_CHANGED:
17931                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17932                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17933                case Intent.ACTION_PACKAGES_SUSPENDED:
17934                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17935                    // Handle special intents: if this broadcast is from the package
17936                    // manager about a package being removed, we need to remove all of
17937                    // its activities from the history stack.
17938                    if (checkComponentPermission(
17939                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17940                            callingPid, callingUid, -1, true)
17941                            != PackageManager.PERMISSION_GRANTED) {
17942                        String msg = "Permission Denial: " + intent.getAction()
17943                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17944                                + ", uid=" + callingUid + ")"
17945                                + " requires "
17946                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17947                        Slog.w(TAG, msg);
17948                        throw new SecurityException(msg);
17949                    }
17950                    switch (action) {
17951                        case Intent.ACTION_UID_REMOVED:
17952                            final Bundle intentExtras = intent.getExtras();
17953                            final int uid = intentExtras != null
17954                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17955                            if (uid >= 0) {
17956                                mBatteryStatsService.removeUid(uid);
17957                                mAppOpsService.uidRemoved(uid);
17958                            }
17959                            break;
17960                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17961                            // If resources are unavailable just force stop all those packages
17962                            // and flush the attribute cache as well.
17963                            String list[] =
17964                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17965                            if (list != null && list.length > 0) {
17966                                for (int i = 0; i < list.length; i++) {
17967                                    forceStopPackageLocked(list[i], -1, false, true, true,
17968                                            false, false, userId, "storage unmount");
17969                                }
17970                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17971                                sendPackageBroadcastLocked(
17972                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17973                                        userId);
17974                            }
17975                            break;
17976                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17977                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17978                            break;
17979                        case Intent.ACTION_PACKAGE_REMOVED:
17980                        case Intent.ACTION_PACKAGE_CHANGED:
17981                            Uri data = intent.getData();
17982                            String ssp;
17983                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17984                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17985                                final boolean replacing =
17986                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17987                                final boolean killProcess =
17988                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17989                                final boolean fullUninstall = removed && !replacing;
17990                                if (removed) {
17991                                    if (killProcess) {
17992                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17993                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17994                                                false, true, true, false, fullUninstall, userId,
17995                                                removed ? "pkg removed" : "pkg changed");
17996                                    }
17997                                    final int cmd = killProcess
17998                                            ? IApplicationThread.PACKAGE_REMOVED
17999                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18000                                    sendPackageBroadcastLocked(cmd,
18001                                            new String[] {ssp}, userId);
18002                                    if (fullUninstall) {
18003                                        mAppOpsService.packageRemoved(
18004                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18005
18006                                        // Remove all permissions granted from/to this package
18007                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18008
18009                                        removeTasksByPackageNameLocked(ssp, userId);
18010
18011                                        // Hide the "unsupported display" dialog if necessary.
18012                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18013                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18014                                            mUnsupportedDisplaySizeDialog.dismiss();
18015                                            mUnsupportedDisplaySizeDialog = null;
18016                                        }
18017                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18018                                        mBatteryStatsService.notePackageUninstalled(ssp);
18019                                    }
18020                                } else {
18021                                    if (killProcess) {
18022                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18023                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18024                                                userId, ProcessList.INVALID_ADJ,
18025                                                false, true, true, false, "change " + ssp);
18026                                    }
18027                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18028                                            intent.getStringArrayExtra(
18029                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18030                                }
18031                            }
18032                            break;
18033                        case Intent.ACTION_PACKAGES_SUSPENDED:
18034                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18035                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18036                                    intent.getAction());
18037                            final String[] packageNames = intent.getStringArrayExtra(
18038                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18039                            final int userHandle = intent.getIntExtra(
18040                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18041
18042                            synchronized(ActivityManagerService.this) {
18043                                mRecentTasks.onPackagesSuspendedChanged(
18044                                        packageNames, suspended, userHandle);
18045                            }
18046                            break;
18047                    }
18048                    break;
18049                case Intent.ACTION_PACKAGE_REPLACED:
18050                {
18051                    final Uri data = intent.getData();
18052                    final String ssp;
18053                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18054                        final ApplicationInfo aInfo =
18055                                getPackageManagerInternalLocked().getApplicationInfo(
18056                                        ssp,
18057                                        userId);
18058                        if (aInfo == null) {
18059                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18060                                    + " ssp=" + ssp + " data=" + data);
18061                            return ActivityManager.BROADCAST_SUCCESS;
18062                        }
18063                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18064                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18065                                new String[] {ssp}, userId);
18066                    }
18067                    break;
18068                }
18069                case Intent.ACTION_PACKAGE_ADDED:
18070                {
18071                    // Special case for adding a package: by default turn on compatibility mode.
18072                    Uri data = intent.getData();
18073                    String ssp;
18074                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18075                        final boolean replacing =
18076                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18077                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18078
18079                        try {
18080                            ApplicationInfo ai = AppGlobals.getPackageManager().
18081                                    getApplicationInfo(ssp, 0, 0);
18082                            mBatteryStatsService.notePackageInstalled(ssp,
18083                                    ai != null ? ai.versionCode : 0);
18084                        } catch (RemoteException e) {
18085                        }
18086                    }
18087                    break;
18088                }
18089                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18090                {
18091                    Uri data = intent.getData();
18092                    String ssp;
18093                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18094                        // Hide the "unsupported display" dialog if necessary.
18095                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18096                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18097                            mUnsupportedDisplaySizeDialog.dismiss();
18098                            mUnsupportedDisplaySizeDialog = null;
18099                        }
18100                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18101                    }
18102                    break;
18103                }
18104                case Intent.ACTION_TIMEZONE_CHANGED:
18105                    // If this is the time zone changed action, queue up a message that will reset
18106                    // the timezone of all currently running processes. This message will get
18107                    // queued up before the broadcast happens.
18108                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18109                    break;
18110                case Intent.ACTION_TIME_CHANGED:
18111                    // If the user set the time, let all running processes know.
18112                    final int is24Hour =
18113                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18114                                    : 0;
18115                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18116                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18117                    synchronized (stats) {
18118                        stats.noteCurrentTimeChangedLocked();
18119                    }
18120                    break;
18121                case Intent.ACTION_CLEAR_DNS_CACHE:
18122                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18123                    break;
18124                case Proxy.PROXY_CHANGE_ACTION:
18125                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18126                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18127                    break;
18128                case android.hardware.Camera.ACTION_NEW_PICTURE:
18129                case android.hardware.Camera.ACTION_NEW_VIDEO:
18130                    // These broadcasts are no longer allowed by the system, since they can
18131                    // cause significant thrashing at a crictical point (using the camera).
18132                    // Apps should use JobScehduler to monitor for media provider changes.
18133                    Slog.w(TAG, action + " no longer allowed; dropping from "
18134                            + UserHandle.formatUid(callingUid));
18135                    if (resultTo != null) {
18136                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18137                        try {
18138                            queue.performReceiveLocked(callerApp, resultTo, intent,
18139                                    Activity.RESULT_CANCELED, null, null,
18140                                    false, false, userId);
18141                        } catch (RemoteException e) {
18142                            Slog.w(TAG, "Failure ["
18143                                    + queue.mQueueName + "] sending broadcast result of "
18144                                    + intent, e);
18145
18146                        }
18147                    }
18148                    // Lie; we don't want to crash the app.
18149                    return ActivityManager.BROADCAST_SUCCESS;
18150            }
18151        }
18152
18153        // Add to the sticky list if requested.
18154        if (sticky) {
18155            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18156                    callingPid, callingUid)
18157                    != PackageManager.PERMISSION_GRANTED) {
18158                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18159                        + callingPid + ", uid=" + callingUid
18160                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18161                Slog.w(TAG, msg);
18162                throw new SecurityException(msg);
18163            }
18164            if (requiredPermissions != null && requiredPermissions.length > 0) {
18165                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18166                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18167                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18168            }
18169            if (intent.getComponent() != null) {
18170                throw new SecurityException(
18171                        "Sticky broadcasts can't target a specific component");
18172            }
18173            // We use userId directly here, since the "all" target is maintained
18174            // as a separate set of sticky broadcasts.
18175            if (userId != UserHandle.USER_ALL) {
18176                // But first, if this is not a broadcast to all users, then
18177                // make sure it doesn't conflict with an existing broadcast to
18178                // all users.
18179                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18180                        UserHandle.USER_ALL);
18181                if (stickies != null) {
18182                    ArrayList<Intent> list = stickies.get(intent.getAction());
18183                    if (list != null) {
18184                        int N = list.size();
18185                        int i;
18186                        for (i=0; i<N; i++) {
18187                            if (intent.filterEquals(list.get(i))) {
18188                                throw new IllegalArgumentException(
18189                                        "Sticky broadcast " + intent + " for user "
18190                                        + userId + " conflicts with existing global broadcast");
18191                            }
18192                        }
18193                    }
18194                }
18195            }
18196            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18197            if (stickies == null) {
18198                stickies = new ArrayMap<>();
18199                mStickyBroadcasts.put(userId, stickies);
18200            }
18201            ArrayList<Intent> list = stickies.get(intent.getAction());
18202            if (list == null) {
18203                list = new ArrayList<>();
18204                stickies.put(intent.getAction(), list);
18205            }
18206            final int stickiesCount = list.size();
18207            int i;
18208            for (i = 0; i < stickiesCount; i++) {
18209                if (intent.filterEquals(list.get(i))) {
18210                    // This sticky already exists, replace it.
18211                    list.set(i, new Intent(intent));
18212                    break;
18213                }
18214            }
18215            if (i >= stickiesCount) {
18216                list.add(new Intent(intent));
18217            }
18218        }
18219
18220        int[] users;
18221        if (userId == UserHandle.USER_ALL) {
18222            // Caller wants broadcast to go to all started users.
18223            users = mUserController.getStartedUserArrayLocked();
18224        } else {
18225            // Caller wants broadcast to go to one specific user.
18226            users = new int[] {userId};
18227        }
18228
18229        // Figure out who all will receive this broadcast.
18230        List receivers = null;
18231        List<BroadcastFilter> registeredReceivers = null;
18232        // Need to resolve the intent to interested receivers...
18233        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18234                 == 0) {
18235            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18236        }
18237        if (intent.getComponent() == null) {
18238            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18239                // Query one target user at a time, excluding shell-restricted users
18240                for (int i = 0; i < users.length; i++) {
18241                    if (mUserController.hasUserRestriction(
18242                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18243                        continue;
18244                    }
18245                    List<BroadcastFilter> registeredReceiversForUser =
18246                            mReceiverResolver.queryIntent(intent,
18247                                    resolvedType, false, users[i]);
18248                    if (registeredReceivers == null) {
18249                        registeredReceivers = registeredReceiversForUser;
18250                    } else if (registeredReceiversForUser != null) {
18251                        registeredReceivers.addAll(registeredReceiversForUser);
18252                    }
18253                }
18254            } else {
18255                registeredReceivers = mReceiverResolver.queryIntent(intent,
18256                        resolvedType, false, userId);
18257            }
18258        }
18259
18260        final boolean replacePending =
18261                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18262
18263        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18264                + " replacePending=" + replacePending);
18265
18266        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18267        if (!ordered && NR > 0) {
18268            // If we are not serializing this broadcast, then send the
18269            // registered receivers separately so they don't wait for the
18270            // components to be launched.
18271            if (isCallerSystem) {
18272                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18273                        isProtectedBroadcast, registeredReceivers);
18274            }
18275            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18276            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18277                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18278                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18279                    resultExtras, ordered, sticky, false, userId);
18280            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18281            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18282            if (!replaced) {
18283                queue.enqueueParallelBroadcastLocked(r);
18284                queue.scheduleBroadcastsLocked();
18285            }
18286            registeredReceivers = null;
18287            NR = 0;
18288        }
18289
18290        // Merge into one list.
18291        int ir = 0;
18292        if (receivers != null) {
18293            // A special case for PACKAGE_ADDED: do not allow the package
18294            // being added to see this broadcast.  This prevents them from
18295            // using this as a back door to get run as soon as they are
18296            // installed.  Maybe in the future we want to have a special install
18297            // broadcast or such for apps, but we'd like to deliberately make
18298            // this decision.
18299            String skipPackages[] = null;
18300            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18301                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18302                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18303                Uri data = intent.getData();
18304                if (data != null) {
18305                    String pkgName = data.getSchemeSpecificPart();
18306                    if (pkgName != null) {
18307                        skipPackages = new String[] { pkgName };
18308                    }
18309                }
18310            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18311                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18312            }
18313            if (skipPackages != null && (skipPackages.length > 0)) {
18314                for (String skipPackage : skipPackages) {
18315                    if (skipPackage != null) {
18316                        int NT = receivers.size();
18317                        for (int it=0; it<NT; it++) {
18318                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18319                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18320                                receivers.remove(it);
18321                                it--;
18322                                NT--;
18323                            }
18324                        }
18325                    }
18326                }
18327            }
18328
18329            int NT = receivers != null ? receivers.size() : 0;
18330            int it = 0;
18331            ResolveInfo curt = null;
18332            BroadcastFilter curr = null;
18333            while (it < NT && ir < NR) {
18334                if (curt == null) {
18335                    curt = (ResolveInfo)receivers.get(it);
18336                }
18337                if (curr == null) {
18338                    curr = registeredReceivers.get(ir);
18339                }
18340                if (curr.getPriority() >= curt.priority) {
18341                    // Insert this broadcast record into the final list.
18342                    receivers.add(it, curr);
18343                    ir++;
18344                    curr = null;
18345                    it++;
18346                    NT++;
18347                } else {
18348                    // Skip to the next ResolveInfo in the final list.
18349                    it++;
18350                    curt = null;
18351                }
18352            }
18353        }
18354        while (ir < NR) {
18355            if (receivers == null) {
18356                receivers = new ArrayList();
18357            }
18358            receivers.add(registeredReceivers.get(ir));
18359            ir++;
18360        }
18361
18362        if (isCallerSystem) {
18363            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18364                    isProtectedBroadcast, receivers);
18365        }
18366
18367        if ((receivers != null && receivers.size() > 0)
18368                || resultTo != null) {
18369            BroadcastQueue queue = broadcastQueueForIntent(intent);
18370            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18371                    callerPackage, callingPid, callingUid, resolvedType,
18372                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18373                    resultData, resultExtras, ordered, sticky, false, userId);
18374
18375            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18376                    + ": prev had " + queue.mOrderedBroadcasts.size());
18377            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18378                    "Enqueueing broadcast " + r.intent.getAction());
18379
18380            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18381            if (!replaced) {
18382                queue.enqueueOrderedBroadcastLocked(r);
18383                queue.scheduleBroadcastsLocked();
18384            }
18385        } else {
18386            // There was nobody interested in the broadcast, but we still want to record
18387            // that it happened.
18388            if (intent.getComponent() == null && intent.getPackage() == null
18389                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18390                // This was an implicit broadcast... let's record it for posterity.
18391                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18392            }
18393        }
18394
18395        return ActivityManager.BROADCAST_SUCCESS;
18396    }
18397
18398    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18399            int skipCount, long dispatchTime) {
18400        final long now = SystemClock.elapsedRealtime();
18401        if (mCurBroadcastStats == null ||
18402                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18403            mLastBroadcastStats = mCurBroadcastStats;
18404            if (mLastBroadcastStats != null) {
18405                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18406                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18407            }
18408            mCurBroadcastStats = new BroadcastStats();
18409        }
18410        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18411    }
18412
18413    final Intent verifyBroadcastLocked(Intent intent) {
18414        // Refuse possible leaked file descriptors
18415        if (intent != null && intent.hasFileDescriptors() == true) {
18416            throw new IllegalArgumentException("File descriptors passed in Intent");
18417        }
18418
18419        int flags = intent.getFlags();
18420
18421        if (!mProcessesReady) {
18422            // if the caller really truly claims to know what they're doing, go
18423            // ahead and allow the broadcast without launching any receivers
18424            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18425                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18426            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18427                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18428                        + " before boot completion");
18429                throw new IllegalStateException("Cannot broadcast before boot completed");
18430            }
18431        }
18432
18433        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18434            throw new IllegalArgumentException(
18435                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18436        }
18437
18438        return intent;
18439    }
18440
18441    public final int broadcastIntent(IApplicationThread caller,
18442            Intent intent, String resolvedType, IIntentReceiver resultTo,
18443            int resultCode, String resultData, Bundle resultExtras,
18444            String[] requiredPermissions, int appOp, Bundle bOptions,
18445            boolean serialized, boolean sticky, int userId) {
18446        enforceNotIsolatedCaller("broadcastIntent");
18447        synchronized(this) {
18448            intent = verifyBroadcastLocked(intent);
18449
18450            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18451            final int callingPid = Binder.getCallingPid();
18452            final int callingUid = Binder.getCallingUid();
18453            final long origId = Binder.clearCallingIdentity();
18454            int res = broadcastIntentLocked(callerApp,
18455                    callerApp != null ? callerApp.info.packageName : null,
18456                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18457                    requiredPermissions, appOp, bOptions, serialized, sticky,
18458                    callingPid, callingUid, userId);
18459            Binder.restoreCallingIdentity(origId);
18460            return res;
18461        }
18462    }
18463
18464
18465    int broadcastIntentInPackage(String packageName, int uid,
18466            Intent intent, String resolvedType, IIntentReceiver resultTo,
18467            int resultCode, String resultData, Bundle resultExtras,
18468            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18469            int userId) {
18470        synchronized(this) {
18471            intent = verifyBroadcastLocked(intent);
18472
18473            final long origId = Binder.clearCallingIdentity();
18474            String[] requiredPermissions = requiredPermission == null ? null
18475                    : new String[] {requiredPermission};
18476            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18477                    resultTo, resultCode, resultData, resultExtras,
18478                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18479                    sticky, -1, uid, userId);
18480            Binder.restoreCallingIdentity(origId);
18481            return res;
18482        }
18483    }
18484
18485    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18486        // Refuse possible leaked file descriptors
18487        if (intent != null && intent.hasFileDescriptors() == true) {
18488            throw new IllegalArgumentException("File descriptors passed in Intent");
18489        }
18490
18491        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18492                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18493
18494        synchronized(this) {
18495            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18496                    != PackageManager.PERMISSION_GRANTED) {
18497                String msg = "Permission Denial: unbroadcastIntent() from pid="
18498                        + Binder.getCallingPid()
18499                        + ", uid=" + Binder.getCallingUid()
18500                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18501                Slog.w(TAG, msg);
18502                throw new SecurityException(msg);
18503            }
18504            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18505            if (stickies != null) {
18506                ArrayList<Intent> list = stickies.get(intent.getAction());
18507                if (list != null) {
18508                    int N = list.size();
18509                    int i;
18510                    for (i=0; i<N; i++) {
18511                        if (intent.filterEquals(list.get(i))) {
18512                            list.remove(i);
18513                            break;
18514                        }
18515                    }
18516                    if (list.size() <= 0) {
18517                        stickies.remove(intent.getAction());
18518                    }
18519                }
18520                if (stickies.size() <= 0) {
18521                    mStickyBroadcasts.remove(userId);
18522                }
18523            }
18524        }
18525    }
18526
18527    void backgroundServicesFinishedLocked(int userId) {
18528        for (BroadcastQueue queue : mBroadcastQueues) {
18529            queue.backgroundServicesFinishedLocked(userId);
18530        }
18531    }
18532
18533    public void finishReceiver(IBinder who, int resultCode, String resultData,
18534            Bundle resultExtras, boolean resultAbort, int flags) {
18535        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18536
18537        // Refuse possible leaked file descriptors
18538        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18539            throw new IllegalArgumentException("File descriptors passed in Bundle");
18540        }
18541
18542        final long origId = Binder.clearCallingIdentity();
18543        try {
18544            boolean doNext = false;
18545            BroadcastRecord r;
18546
18547            synchronized(this) {
18548                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18549                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18550                r = queue.getMatchingOrderedReceiver(who);
18551                if (r != null) {
18552                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18553                        resultData, resultExtras, resultAbort, true);
18554                }
18555            }
18556
18557            if (doNext) {
18558                r.queue.processNextBroadcast(false);
18559            }
18560            trimApplications();
18561        } finally {
18562            Binder.restoreCallingIdentity(origId);
18563        }
18564    }
18565
18566    // =========================================================
18567    // INSTRUMENTATION
18568    // =========================================================
18569
18570    public boolean startInstrumentation(ComponentName className,
18571            String profileFile, int flags, Bundle arguments,
18572            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18573            int userId, String abiOverride) {
18574        enforceNotIsolatedCaller("startInstrumentation");
18575        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18576                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18577        // Refuse possible leaked file descriptors
18578        if (arguments != null && arguments.hasFileDescriptors()) {
18579            throw new IllegalArgumentException("File descriptors passed in Bundle");
18580        }
18581
18582        synchronized(this) {
18583            InstrumentationInfo ii = null;
18584            ApplicationInfo ai = null;
18585            try {
18586                ii = mContext.getPackageManager().getInstrumentationInfo(
18587                    className, STOCK_PM_FLAGS);
18588                ai = AppGlobals.getPackageManager().getApplicationInfo(
18589                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18590            } catch (PackageManager.NameNotFoundException e) {
18591            } catch (RemoteException e) {
18592            }
18593            if (ii == null) {
18594                reportStartInstrumentationFailureLocked(watcher, className,
18595                        "Unable to find instrumentation info for: " + className);
18596                return false;
18597            }
18598            if (ai == null) {
18599                reportStartInstrumentationFailureLocked(watcher, className,
18600                        "Unable to find instrumentation target package: " + ii.targetPackage);
18601                return false;
18602            }
18603            if (!ai.hasCode()) {
18604                reportStartInstrumentationFailureLocked(watcher, className,
18605                        "Instrumentation target has no code: " + ii.targetPackage);
18606                return false;
18607            }
18608
18609            int match = mContext.getPackageManager().checkSignatures(
18610                    ii.targetPackage, ii.packageName);
18611            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18612                String msg = "Permission Denial: starting instrumentation "
18613                        + className + " from pid="
18614                        + Binder.getCallingPid()
18615                        + ", uid=" + Binder.getCallingPid()
18616                        + " not allowed because package " + ii.packageName
18617                        + " does not have a signature matching the target "
18618                        + ii.targetPackage;
18619                reportStartInstrumentationFailureLocked(watcher, className, msg);
18620                throw new SecurityException(msg);
18621            }
18622
18623            final long origId = Binder.clearCallingIdentity();
18624            // Instrumentation can kill and relaunch even persistent processes
18625            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18626                    "start instr");
18627            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18628            app.instrumentationClass = className;
18629            app.instrumentationInfo = ai;
18630            app.instrumentationProfileFile = profileFile;
18631            app.instrumentationArguments = arguments;
18632            app.instrumentationWatcher = watcher;
18633            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18634            app.instrumentationResultClass = className;
18635            Binder.restoreCallingIdentity(origId);
18636        }
18637
18638        return true;
18639    }
18640
18641    /**
18642     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18643     * error to the logs, but if somebody is watching, send the report there too.  This enables
18644     * the "am" command to report errors with more information.
18645     *
18646     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18647     * @param cn The component name of the instrumentation.
18648     * @param report The error report.
18649     */
18650    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18651            ComponentName cn, String report) {
18652        Slog.w(TAG, report);
18653        if (watcher != null) {
18654            Bundle results = new Bundle();
18655            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18656            results.putString("Error", report);
18657            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18658        }
18659    }
18660
18661    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18662        if (app.instrumentationWatcher != null) {
18663            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18664                    app.instrumentationClass, resultCode, results);
18665        }
18666
18667        // Can't call out of the system process with a lock held, so post a message.
18668        if (app.instrumentationUiAutomationConnection != null) {
18669            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18670                    app.instrumentationUiAutomationConnection).sendToTarget();
18671        }
18672
18673        app.instrumentationWatcher = null;
18674        app.instrumentationUiAutomationConnection = null;
18675        app.instrumentationClass = null;
18676        app.instrumentationInfo = null;
18677        app.instrumentationProfileFile = null;
18678        app.instrumentationArguments = null;
18679
18680        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18681                "finished inst");
18682    }
18683
18684    public void finishInstrumentation(IApplicationThread target,
18685            int resultCode, Bundle results) {
18686        int userId = UserHandle.getCallingUserId();
18687        // Refuse possible leaked file descriptors
18688        if (results != null && results.hasFileDescriptors()) {
18689            throw new IllegalArgumentException("File descriptors passed in Intent");
18690        }
18691
18692        synchronized(this) {
18693            ProcessRecord app = getRecordForAppLocked(target);
18694            if (app == null) {
18695                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18696                return;
18697            }
18698            final long origId = Binder.clearCallingIdentity();
18699            finishInstrumentationLocked(app, resultCode, results);
18700            Binder.restoreCallingIdentity(origId);
18701        }
18702    }
18703
18704    // =========================================================
18705    // CONFIGURATION
18706    // =========================================================
18707
18708    public ConfigurationInfo getDeviceConfigurationInfo() {
18709        ConfigurationInfo config = new ConfigurationInfo();
18710        synchronized (this) {
18711            config.reqTouchScreen = mConfiguration.touchscreen;
18712            config.reqKeyboardType = mConfiguration.keyboard;
18713            config.reqNavigation = mConfiguration.navigation;
18714            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18715                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18716                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18717            }
18718            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18719                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18720                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18721            }
18722            config.reqGlEsVersion = GL_ES_VERSION;
18723        }
18724        return config;
18725    }
18726
18727    ActivityStack getFocusedStack() {
18728        return mStackSupervisor.getFocusedStack();
18729    }
18730
18731    @Override
18732    public int getFocusedStackId() throws RemoteException {
18733        ActivityStack focusedStack = getFocusedStack();
18734        if (focusedStack != null) {
18735            return focusedStack.getStackId();
18736        }
18737        return -1;
18738    }
18739
18740    public Configuration getConfiguration() {
18741        Configuration ci;
18742        synchronized(this) {
18743            ci = new Configuration(mConfiguration);
18744            ci.userSetLocale = false;
18745        }
18746        return ci;
18747    }
18748
18749    @Override
18750    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18751        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18752        synchronized (this) {
18753            mSuppressResizeConfigChanges = suppress;
18754        }
18755    }
18756
18757    @Override
18758    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18759        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18760        if (fromStackId == HOME_STACK_ID) {
18761            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18762        }
18763        synchronized (this) {
18764            final long origId = Binder.clearCallingIdentity();
18765            try {
18766                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18767            } finally {
18768                Binder.restoreCallingIdentity(origId);
18769            }
18770        }
18771    }
18772
18773    @Override
18774    public void updatePersistentConfiguration(Configuration values) {
18775        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18776                "updateConfiguration()");
18777        enforceWriteSettingsPermission("updateConfiguration()");
18778        if (values == null) {
18779            throw new NullPointerException("Configuration must not be null");
18780        }
18781
18782        int userId = UserHandle.getCallingUserId();
18783
18784        synchronized(this) {
18785            updatePersistentConfigurationLocked(values, userId);
18786        }
18787    }
18788
18789    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18790        final long origId = Binder.clearCallingIdentity();
18791        try {
18792            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18793        } finally {
18794            Binder.restoreCallingIdentity(origId);
18795        }
18796    }
18797
18798    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18799        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18800                FONT_SCALE, 1.0f, userId);
18801        if (mConfiguration.fontScale != scaleFactor) {
18802            final Configuration configuration = mWindowManager.computeNewConfiguration();
18803            configuration.fontScale = scaleFactor;
18804            synchronized (this) {
18805                updatePersistentConfigurationLocked(configuration, userId);
18806            }
18807        }
18808    }
18809
18810    private void enforceWriteSettingsPermission(String func) {
18811        int uid = Binder.getCallingUid();
18812        if (uid == Process.ROOT_UID) {
18813            return;
18814        }
18815
18816        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18817                Settings.getPackageNameForUid(mContext, uid), false)) {
18818            return;
18819        }
18820
18821        String msg = "Permission Denial: " + func + " from pid="
18822                + Binder.getCallingPid()
18823                + ", uid=" + uid
18824                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18825        Slog.w(TAG, msg);
18826        throw new SecurityException(msg);
18827    }
18828
18829    public void updateConfiguration(Configuration values) {
18830        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18831                "updateConfiguration()");
18832
18833        synchronized(this) {
18834            if (values == null && mWindowManager != null) {
18835                // sentinel: fetch the current configuration from the window manager
18836                values = mWindowManager.computeNewConfiguration();
18837            }
18838
18839            if (mWindowManager != null) {
18840                mProcessList.applyDisplaySize(mWindowManager);
18841            }
18842
18843            final long origId = Binder.clearCallingIdentity();
18844            if (values != null) {
18845                Settings.System.clearConfiguration(values);
18846            }
18847            updateConfigurationLocked(values, null, false);
18848            Binder.restoreCallingIdentity(origId);
18849        }
18850    }
18851
18852    void updateUserConfigurationLocked() {
18853        Configuration configuration = new Configuration(mConfiguration);
18854        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18855                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18856        updateConfigurationLocked(configuration, null, false);
18857    }
18858
18859    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18860            boolean initLocale) {
18861        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18862    }
18863
18864    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18865            boolean initLocale, boolean deferResume) {
18866        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18867        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18868                UserHandle.USER_NULL, deferResume);
18869    }
18870
18871    // To cache the list of supported system locales
18872    private String[] mSupportedSystemLocales = null;
18873
18874    /**
18875     * Do either or both things: (1) change the current configuration, and (2)
18876     * make sure the given activity is running with the (now) current
18877     * configuration.  Returns true if the activity has been left running, or
18878     * false if <var>starting</var> is being destroyed to match the new
18879     * configuration.
18880     *
18881     * @param userId is only used when persistent parameter is set to true to persist configuration
18882     *               for that particular user
18883     */
18884    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18885            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18886        int changes = 0;
18887
18888        if (mWindowManager != null) {
18889            mWindowManager.deferSurfaceLayout();
18890        }
18891        if (values != null) {
18892            Configuration newConfig = new Configuration(mConfiguration);
18893            changes = newConfig.updateFrom(values);
18894            if (changes != 0) {
18895                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18896                        "Updating configuration to: " + values);
18897
18898                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18899
18900                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18901                    final LocaleList locales = values.getLocales();
18902                    int bestLocaleIndex = 0;
18903                    if (locales.size() > 1) {
18904                        if (mSupportedSystemLocales == null) {
18905                            mSupportedSystemLocales =
18906                                    Resources.getSystem().getAssets().getLocales();
18907                        }
18908                        bestLocaleIndex = Math.max(0,
18909                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18910                    }
18911                    SystemProperties.set("persist.sys.locale",
18912                            locales.get(bestLocaleIndex).toLanguageTag());
18913                    LocaleList.setDefault(locales, bestLocaleIndex);
18914                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18915                            locales.get(bestLocaleIndex)));
18916                }
18917
18918                mConfigurationSeq++;
18919                if (mConfigurationSeq <= 0) {
18920                    mConfigurationSeq = 1;
18921                }
18922                newConfig.seq = mConfigurationSeq;
18923                mConfiguration = newConfig;
18924                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18925                mUsageStatsService.reportConfigurationChange(newConfig,
18926                        mUserController.getCurrentUserIdLocked());
18927                //mUsageStatsService.noteStartConfig(newConfig);
18928
18929                final Configuration configCopy = new Configuration(mConfiguration);
18930
18931                // TODO: If our config changes, should we auto dismiss any currently
18932                // showing dialogs?
18933                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18934
18935                AttributeCache ac = AttributeCache.instance();
18936                if (ac != null) {
18937                    ac.updateConfiguration(configCopy);
18938                }
18939
18940                // Make sure all resources in our process are updated
18941                // right now, so that anyone who is going to retrieve
18942                // resource values after we return will be sure to get
18943                // the new ones.  This is especially important during
18944                // boot, where the first config change needs to guarantee
18945                // all resources have that config before following boot
18946                // code is executed.
18947                mSystemThread.applyConfigurationToResources(configCopy);
18948
18949                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18950                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18951                    msg.obj = new Configuration(configCopy);
18952                    msg.arg1 = userId;
18953                    mHandler.sendMessage(msg);
18954                }
18955
18956                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18957                if (isDensityChange) {
18958                    // Reset the unsupported display size dialog.
18959                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18960
18961                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18962                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18963                }
18964
18965                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18966                    ProcessRecord app = mLruProcesses.get(i);
18967                    try {
18968                        if (app.thread != null) {
18969                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18970                                    + app.processName + " new config " + mConfiguration);
18971                            app.thread.scheduleConfigurationChanged(configCopy);
18972                        }
18973                    } catch (Exception e) {
18974                    }
18975                }
18976                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18977                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18978                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18979                        | Intent.FLAG_RECEIVER_FOREGROUND);
18980                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18981                        null, AppOpsManager.OP_NONE, null, false, false,
18982                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18983                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18984                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18985                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18986                    if (!mProcessesReady) {
18987                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18988                    }
18989                    broadcastIntentLocked(null, null, intent,
18990                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18991                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18992                }
18993            }
18994            // Update the configuration with WM first and check if any of the stacks need to be
18995            // resized due to the configuration change. If so, resize the stacks now and do any
18996            // relaunches if necessary. This way we don't need to relaunch again below in
18997            // ensureActivityConfigurationLocked().
18998            if (mWindowManager != null) {
18999                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19000                if (resizedStacks != null) {
19001                    for (int stackId : resizedStacks) {
19002                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19003                        mStackSupervisor.resizeStackLocked(
19004                                stackId, newBounds, null, null, false, false, deferResume);
19005                    }
19006                }
19007            }
19008        }
19009
19010        boolean kept = true;
19011        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19012        // mainStack is null during startup.
19013        if (mainStack != null) {
19014            if (changes != 0 && starting == null) {
19015                // If the configuration changed, and the caller is not already
19016                // in the process of starting an activity, then find the top
19017                // activity to check if its configuration needs to change.
19018                starting = mainStack.topRunningActivityLocked();
19019            }
19020
19021            if (starting != null) {
19022                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19023                // And we need to make sure at this point that all other activities
19024                // are made visible with the correct configuration.
19025                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19026                        !PRESERVE_WINDOWS);
19027            }
19028        }
19029        if (mWindowManager != null) {
19030            mWindowManager.continueSurfaceLayout();
19031        }
19032        return kept;
19033    }
19034
19035    /**
19036     * Decide based on the configuration whether we should shouw the ANR,
19037     * crash, etc dialogs.  The idea is that if there is no affordence to
19038     * press the on-screen buttons, or the user experience would be more
19039     * greatly impacted than the crash itself, we shouldn't show the dialog.
19040     *
19041     * A thought: SystemUI might also want to get told about this, the Power
19042     * dialog / global actions also might want different behaviors.
19043     */
19044    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19045        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19046                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19047                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19048        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19049        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19050                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19051        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19052    }
19053
19054    @Override
19055    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19056        synchronized (this) {
19057            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19058            if (srec != null) {
19059                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19060            }
19061        }
19062        return false;
19063    }
19064
19065    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19066            Intent resultData) {
19067
19068        synchronized (this) {
19069            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19070            if (r != null) {
19071                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19072            }
19073            return false;
19074        }
19075    }
19076
19077    public int getLaunchedFromUid(IBinder activityToken) {
19078        ActivityRecord srec;
19079        synchronized (this) {
19080            srec = ActivityRecord.forTokenLocked(activityToken);
19081        }
19082        if (srec == null) {
19083            return -1;
19084        }
19085        return srec.launchedFromUid;
19086    }
19087
19088    public String getLaunchedFromPackage(IBinder activityToken) {
19089        ActivityRecord srec;
19090        synchronized (this) {
19091            srec = ActivityRecord.forTokenLocked(activityToken);
19092        }
19093        if (srec == null) {
19094            return null;
19095        }
19096        return srec.launchedFromPackage;
19097    }
19098
19099    // =========================================================
19100    // LIFETIME MANAGEMENT
19101    // =========================================================
19102
19103    // Returns which broadcast queue the app is the current [or imminent] receiver
19104    // on, or 'null' if the app is not an active broadcast recipient.
19105    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19106        BroadcastRecord r = app.curReceiver;
19107        if (r != null) {
19108            return r.queue;
19109        }
19110
19111        // It's not the current receiver, but it might be starting up to become one
19112        synchronized (this) {
19113            for (BroadcastQueue queue : mBroadcastQueues) {
19114                r = queue.mPendingBroadcast;
19115                if (r != null && r.curApp == app) {
19116                    // found it; report which queue it's in
19117                    return queue;
19118                }
19119            }
19120        }
19121
19122        return null;
19123    }
19124
19125    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19126            int targetUid, ComponentName targetComponent, String targetProcess) {
19127        if (!mTrackingAssociations) {
19128            return null;
19129        }
19130        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19131                = mAssociations.get(targetUid);
19132        if (components == null) {
19133            components = new ArrayMap<>();
19134            mAssociations.put(targetUid, components);
19135        }
19136        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19137        if (sourceUids == null) {
19138            sourceUids = new SparseArray<>();
19139            components.put(targetComponent, sourceUids);
19140        }
19141        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19142        if (sourceProcesses == null) {
19143            sourceProcesses = new ArrayMap<>();
19144            sourceUids.put(sourceUid, sourceProcesses);
19145        }
19146        Association ass = sourceProcesses.get(sourceProcess);
19147        if (ass == null) {
19148            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19149                    targetProcess);
19150            sourceProcesses.put(sourceProcess, ass);
19151        }
19152        ass.mCount++;
19153        ass.mNesting++;
19154        if (ass.mNesting == 1) {
19155            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19156            ass.mLastState = sourceState;
19157        }
19158        return ass;
19159    }
19160
19161    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19162            ComponentName targetComponent) {
19163        if (!mTrackingAssociations) {
19164            return;
19165        }
19166        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19167                = mAssociations.get(targetUid);
19168        if (components == null) {
19169            return;
19170        }
19171        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19172        if (sourceUids == null) {
19173            return;
19174        }
19175        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19176        if (sourceProcesses == null) {
19177            return;
19178        }
19179        Association ass = sourceProcesses.get(sourceProcess);
19180        if (ass == null || ass.mNesting <= 0) {
19181            return;
19182        }
19183        ass.mNesting--;
19184        if (ass.mNesting == 0) {
19185            long uptime = SystemClock.uptimeMillis();
19186            ass.mTime += uptime - ass.mStartTime;
19187            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19188                    += uptime - ass.mLastStateUptime;
19189            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19190        }
19191    }
19192
19193    private void noteUidProcessState(final int uid, final int state) {
19194        mBatteryStatsService.noteUidProcessState(uid, state);
19195        if (mTrackingAssociations) {
19196            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19197                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19198                        = mAssociations.valueAt(i1);
19199                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19200                    SparseArray<ArrayMap<String, Association>> sourceUids
19201                            = targetComponents.valueAt(i2);
19202                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19203                    if (sourceProcesses != null) {
19204                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19205                            Association ass = sourceProcesses.valueAt(i4);
19206                            if (ass.mNesting >= 1) {
19207                                // currently associated
19208                                long uptime = SystemClock.uptimeMillis();
19209                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19210                                        += uptime - ass.mLastStateUptime;
19211                                ass.mLastState = state;
19212                                ass.mLastStateUptime = uptime;
19213                            }
19214                        }
19215                    }
19216                }
19217            }
19218        }
19219    }
19220
19221    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19222            boolean doingAll, long now) {
19223        if (mAdjSeq == app.adjSeq) {
19224            // This adjustment has already been computed.
19225            return app.curRawAdj;
19226        }
19227
19228        if (app.thread == null) {
19229            app.adjSeq = mAdjSeq;
19230            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19231            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19232            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19233        }
19234
19235        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19236        app.adjSource = null;
19237        app.adjTarget = null;
19238        app.empty = false;
19239        app.cached = false;
19240
19241        final int activitiesSize = app.activities.size();
19242
19243        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19244            // The max adjustment doesn't allow this app to be anything
19245            // below foreground, so it is not worth doing work for it.
19246            app.adjType = "fixed";
19247            app.adjSeq = mAdjSeq;
19248            app.curRawAdj = app.maxAdj;
19249            app.foregroundActivities = false;
19250            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19251            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19252            // System processes can do UI, and when they do we want to have
19253            // them trim their memory after the user leaves the UI.  To
19254            // facilitate this, here we need to determine whether or not it
19255            // is currently showing UI.
19256            app.systemNoUi = true;
19257            if (app == TOP_APP) {
19258                app.systemNoUi = false;
19259                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19260                app.adjType = "pers-top-activity";
19261            } else if (app.hasTopUi) {
19262                app.systemNoUi = false;
19263                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19264                app.adjType = "pers-top-ui";
19265            } else if (activitiesSize > 0) {
19266                for (int j = 0; j < activitiesSize; j++) {
19267                    final ActivityRecord r = app.activities.get(j);
19268                    if (r.visible) {
19269                        app.systemNoUi = false;
19270                    }
19271                }
19272            }
19273            if (!app.systemNoUi) {
19274                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19275            }
19276            return (app.curAdj=app.maxAdj);
19277        }
19278
19279        app.systemNoUi = false;
19280
19281        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19282
19283        // Determine the importance of the process, starting with most
19284        // important to least, and assign an appropriate OOM adjustment.
19285        int adj;
19286        int schedGroup;
19287        int procState;
19288        boolean foregroundActivities = false;
19289        BroadcastQueue queue;
19290        if (app == TOP_APP) {
19291            // The last app on the list is the foreground app.
19292            adj = ProcessList.FOREGROUND_APP_ADJ;
19293            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19294            app.adjType = "top-activity";
19295            foregroundActivities = true;
19296            procState = PROCESS_STATE_CUR_TOP;
19297        } else if (app.instrumentationClass != null) {
19298            // Don't want to kill running instrumentation.
19299            adj = ProcessList.FOREGROUND_APP_ADJ;
19300            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19301            app.adjType = "instrumentation";
19302            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19303        } else if ((queue = isReceivingBroadcast(app)) != null) {
19304            // An app that is currently receiving a broadcast also
19305            // counts as being in the foreground for OOM killer purposes.
19306            // It's placed in a sched group based on the nature of the
19307            // broadcast as reflected by which queue it's active in.
19308            adj = ProcessList.FOREGROUND_APP_ADJ;
19309            schedGroup = (queue == mFgBroadcastQueue)
19310                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19311            app.adjType = "broadcast";
19312            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19313        } else if (app.executingServices.size() > 0) {
19314            // An app that is currently executing a service callback also
19315            // counts as being in the foreground.
19316            adj = ProcessList.FOREGROUND_APP_ADJ;
19317            schedGroup = app.execServicesFg ?
19318                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19319            app.adjType = "exec-service";
19320            procState = ActivityManager.PROCESS_STATE_SERVICE;
19321            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19322        } else {
19323            // As far as we know the process is empty.  We may change our mind later.
19324            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19325            // At this point we don't actually know the adjustment.  Use the cached adj
19326            // value that the caller wants us to.
19327            adj = cachedAdj;
19328            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19329            app.cached = true;
19330            app.empty = true;
19331            app.adjType = "cch-empty";
19332        }
19333
19334        // Examine all activities if not already foreground.
19335        if (!foregroundActivities && activitiesSize > 0) {
19336            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19337            for (int j = 0; j < activitiesSize; j++) {
19338                final ActivityRecord r = app.activities.get(j);
19339                if (r.app != app) {
19340                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19341                            + " instead of expected " + app);
19342                    if (r.app == null || (r.app.uid == app.uid)) {
19343                        // Only fix things up when they look sane
19344                        r.app = app;
19345                    } else {
19346                        continue;
19347                    }
19348                }
19349                if (r.visible) {
19350                    // App has a visible activity; only upgrade adjustment.
19351                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19352                        adj = ProcessList.VISIBLE_APP_ADJ;
19353                        app.adjType = "visible";
19354                    }
19355                    if (procState > PROCESS_STATE_CUR_TOP) {
19356                        procState = PROCESS_STATE_CUR_TOP;
19357                    }
19358                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19359                    app.cached = false;
19360                    app.empty = false;
19361                    foregroundActivities = true;
19362                    if (r.task != null && minLayer > 0) {
19363                        final int layer = r.task.mLayerRank;
19364                        if (layer >= 0 && minLayer > layer) {
19365                            minLayer = layer;
19366                        }
19367                    }
19368                    break;
19369                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19370                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19371                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19372                        app.adjType = "pausing";
19373                    }
19374                    if (procState > PROCESS_STATE_CUR_TOP) {
19375                        procState = PROCESS_STATE_CUR_TOP;
19376                    }
19377                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19378                    app.cached = false;
19379                    app.empty = false;
19380                    foregroundActivities = true;
19381                } else if (r.state == ActivityState.STOPPING) {
19382                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19383                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19384                        app.adjType = "stopping";
19385                    }
19386                    // For the process state, we will at this point consider the
19387                    // process to be cached.  It will be cached either as an activity
19388                    // or empty depending on whether the activity is finishing.  We do
19389                    // this so that we can treat the process as cached for purposes of
19390                    // memory trimming (determing current memory level, trim command to
19391                    // send to process) since there can be an arbitrary number of stopping
19392                    // processes and they should soon all go into the cached state.
19393                    if (!r.finishing) {
19394                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19395                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19396                        }
19397                    }
19398                    app.cached = false;
19399                    app.empty = false;
19400                    foregroundActivities = true;
19401                } else {
19402                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19403                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19404                        app.adjType = "cch-act";
19405                    }
19406                }
19407            }
19408            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19409                adj += minLayer;
19410            }
19411        }
19412
19413        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19414                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19415            if (app.foregroundServices) {
19416                // The user is aware of this app, so make it visible.
19417                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19418                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19419                app.cached = false;
19420                app.adjType = "fg-service";
19421                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19422            } else if (app.forcingToForeground != null) {
19423                // The user is aware of this app, so make it visible.
19424                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19425                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19426                app.cached = false;
19427                app.adjType = "force-fg";
19428                app.adjSource = app.forcingToForeground;
19429                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19430            }
19431        }
19432
19433        if (app == mHeavyWeightProcess) {
19434            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19435                // We don't want to kill the current heavy-weight process.
19436                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19437                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19438                app.cached = false;
19439                app.adjType = "heavy";
19440            }
19441            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19442                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19443            }
19444        }
19445
19446        if (app == mHomeProcess) {
19447            if (adj > ProcessList.HOME_APP_ADJ) {
19448                // This process is hosting what we currently consider to be the
19449                // home app, so we don't want to let it go into the background.
19450                adj = ProcessList.HOME_APP_ADJ;
19451                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19452                app.cached = false;
19453                app.adjType = "home";
19454            }
19455            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19456                procState = ActivityManager.PROCESS_STATE_HOME;
19457            }
19458        }
19459
19460        if (app == mPreviousProcess && app.activities.size() > 0) {
19461            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19462                // This was the previous process that showed UI to the user.
19463                // We want to try to keep it around more aggressively, to give
19464                // a good experience around switching between two apps.
19465                adj = ProcessList.PREVIOUS_APP_ADJ;
19466                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19467                app.cached = false;
19468                app.adjType = "previous";
19469            }
19470            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19471                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19472            }
19473        }
19474
19475        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19476                + " reason=" + app.adjType);
19477
19478        // By default, we use the computed adjustment.  It may be changed if
19479        // there are applications dependent on our services or providers, but
19480        // this gives us a baseline and makes sure we don't get into an
19481        // infinite recursion.
19482        app.adjSeq = mAdjSeq;
19483        app.curRawAdj = adj;
19484        app.hasStartedServices = false;
19485
19486        if (mBackupTarget != null && app == mBackupTarget.app) {
19487            // If possible we want to avoid killing apps while they're being backed up
19488            if (adj > ProcessList.BACKUP_APP_ADJ) {
19489                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19490                adj = ProcessList.BACKUP_APP_ADJ;
19491                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19492                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19493                }
19494                app.adjType = "backup";
19495                app.cached = false;
19496            }
19497            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19498                procState = ActivityManager.PROCESS_STATE_BACKUP;
19499            }
19500        }
19501
19502        boolean mayBeTop = false;
19503
19504        for (int is = app.services.size()-1;
19505                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19506                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19507                        || procState > ActivityManager.PROCESS_STATE_TOP);
19508                is--) {
19509            ServiceRecord s = app.services.valueAt(is);
19510            if (s.startRequested) {
19511                app.hasStartedServices = true;
19512                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19513                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19514                }
19515                if (app.hasShownUi && app != mHomeProcess) {
19516                    // If this process has shown some UI, let it immediately
19517                    // go to the LRU list because it may be pretty heavy with
19518                    // UI stuff.  We'll tag it with a label just to help
19519                    // debug and understand what is going on.
19520                    if (adj > ProcessList.SERVICE_ADJ) {
19521                        app.adjType = "cch-started-ui-services";
19522                    }
19523                } else {
19524                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19525                        // This service has seen some activity within
19526                        // recent memory, so we will keep its process ahead
19527                        // of the background processes.
19528                        if (adj > ProcessList.SERVICE_ADJ) {
19529                            adj = ProcessList.SERVICE_ADJ;
19530                            app.adjType = "started-services";
19531                            app.cached = false;
19532                        }
19533                    }
19534                    // If we have let the service slide into the background
19535                    // state, still have some text describing what it is doing
19536                    // even though the service no longer has an impact.
19537                    if (adj > ProcessList.SERVICE_ADJ) {
19538                        app.adjType = "cch-started-services";
19539                    }
19540                }
19541            }
19542
19543            for (int conni = s.connections.size()-1;
19544                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19545                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19546                            || procState > ActivityManager.PROCESS_STATE_TOP);
19547                    conni--) {
19548                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19549                for (int i = 0;
19550                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19551                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19552                                || procState > ActivityManager.PROCESS_STATE_TOP);
19553                        i++) {
19554                    // XXX should compute this based on the max of
19555                    // all connected clients.
19556                    ConnectionRecord cr = clist.get(i);
19557                    if (cr.binding.client == app) {
19558                        // Binding to ourself is not interesting.
19559                        continue;
19560                    }
19561
19562                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19563                        ProcessRecord client = cr.binding.client;
19564                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19565                                TOP_APP, doingAll, now);
19566                        int clientProcState = client.curProcState;
19567                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19568                            // If the other app is cached for any reason, for purposes here
19569                            // we are going to consider it empty.  The specific cached state
19570                            // doesn't propagate except under certain conditions.
19571                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19572                        }
19573                        String adjType = null;
19574                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19575                            // Not doing bind OOM management, so treat
19576                            // this guy more like a started service.
19577                            if (app.hasShownUi && app != mHomeProcess) {
19578                                // If this process has shown some UI, let it immediately
19579                                // go to the LRU list because it may be pretty heavy with
19580                                // UI stuff.  We'll tag it with a label just to help
19581                                // debug and understand what is going on.
19582                                if (adj > clientAdj) {
19583                                    adjType = "cch-bound-ui-services";
19584                                }
19585                                app.cached = false;
19586                                clientAdj = adj;
19587                                clientProcState = procState;
19588                            } else {
19589                                if (now >= (s.lastActivity
19590                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19591                                    // This service has not seen activity within
19592                                    // recent memory, so allow it to drop to the
19593                                    // LRU list if there is no other reason to keep
19594                                    // it around.  We'll also tag it with a label just
19595                                    // to help debug and undertand what is going on.
19596                                    if (adj > clientAdj) {
19597                                        adjType = "cch-bound-services";
19598                                    }
19599                                    clientAdj = adj;
19600                                }
19601                            }
19602                        }
19603                        if (adj > clientAdj) {
19604                            // If this process has recently shown UI, and
19605                            // the process that is binding to it is less
19606                            // important than being visible, then we don't
19607                            // care about the binding as much as we care
19608                            // about letting this process get into the LRU
19609                            // list to be killed and restarted if needed for
19610                            // memory.
19611                            if (app.hasShownUi && app != mHomeProcess
19612                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19613                                adjType = "cch-bound-ui-services";
19614                            } else {
19615                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19616                                        |Context.BIND_IMPORTANT)) != 0) {
19617                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19618                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19619                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19620                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19621                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19622                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19623                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19624                                    adj = clientAdj;
19625                                } else {
19626                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19627                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19628                                    }
19629                                }
19630                                if (!client.cached) {
19631                                    app.cached = false;
19632                                }
19633                                adjType = "service";
19634                            }
19635                        }
19636                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19637                            // This will treat important bound services identically to
19638                            // the top app, which may behave differently than generic
19639                            // foreground work.
19640                            if (client.curSchedGroup > schedGroup) {
19641                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19642                                    schedGroup = client.curSchedGroup;
19643                                } else {
19644                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19645                                }
19646                            }
19647                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19648                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19649                                    // Special handling of clients who are in the top state.
19650                                    // We *may* want to consider this process to be in the
19651                                    // top state as well, but only if there is not another
19652                                    // reason for it to be running.  Being on the top is a
19653                                    // special state, meaning you are specifically running
19654                                    // for the current top app.  If the process is already
19655                                    // running in the background for some other reason, it
19656                                    // is more important to continue considering it to be
19657                                    // in the background state.
19658                                    mayBeTop = true;
19659                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19660                                } else {
19661                                    // Special handling for above-top states (persistent
19662                                    // processes).  These should not bring the current process
19663                                    // into the top state, since they are not on top.  Instead
19664                                    // give them the best state after that.
19665                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19666                                        clientProcState =
19667                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19668                                    } else if (mWakefulness
19669                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19670                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19671                                                    != 0) {
19672                                        clientProcState =
19673                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19674                                    } else {
19675                                        clientProcState =
19676                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19677                                    }
19678                                }
19679                            }
19680                        } else {
19681                            if (clientProcState <
19682                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19683                                clientProcState =
19684                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19685                            }
19686                        }
19687                        if (procState > clientProcState) {
19688                            procState = clientProcState;
19689                        }
19690                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19691                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19692                            app.pendingUiClean = true;
19693                        }
19694                        if (adjType != null) {
19695                            app.adjType = adjType;
19696                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19697                                    .REASON_SERVICE_IN_USE;
19698                            app.adjSource = cr.binding.client;
19699                            app.adjSourceProcState = clientProcState;
19700                            app.adjTarget = s.name;
19701                        }
19702                    }
19703                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19704                        app.treatLikeActivity = true;
19705                    }
19706                    final ActivityRecord a = cr.activity;
19707                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19708                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19709                            (a.visible || a.state == ActivityState.RESUMED ||
19710                             a.state == ActivityState.PAUSING)) {
19711                            adj = ProcessList.FOREGROUND_APP_ADJ;
19712                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19713                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19714                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19715                                } else {
19716                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19717                                }
19718                            }
19719                            app.cached = false;
19720                            app.adjType = "service";
19721                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19722                                    .REASON_SERVICE_IN_USE;
19723                            app.adjSource = a;
19724                            app.adjSourceProcState = procState;
19725                            app.adjTarget = s.name;
19726                        }
19727                    }
19728                }
19729            }
19730        }
19731
19732        for (int provi = app.pubProviders.size()-1;
19733                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19734                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19735                        || procState > ActivityManager.PROCESS_STATE_TOP);
19736                provi--) {
19737            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19738            for (int i = cpr.connections.size()-1;
19739                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19740                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19741                            || procState > ActivityManager.PROCESS_STATE_TOP);
19742                    i--) {
19743                ContentProviderConnection conn = cpr.connections.get(i);
19744                ProcessRecord client = conn.client;
19745                if (client == app) {
19746                    // Being our own client is not interesting.
19747                    continue;
19748                }
19749                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19750                int clientProcState = client.curProcState;
19751                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19752                    // If the other app is cached for any reason, for purposes here
19753                    // we are going to consider it empty.
19754                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19755                }
19756                if (adj > clientAdj) {
19757                    if (app.hasShownUi && app != mHomeProcess
19758                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19759                        app.adjType = "cch-ui-provider";
19760                    } else {
19761                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19762                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19763                        app.adjType = "provider";
19764                    }
19765                    app.cached &= client.cached;
19766                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19767                            .REASON_PROVIDER_IN_USE;
19768                    app.adjSource = client;
19769                    app.adjSourceProcState = clientProcState;
19770                    app.adjTarget = cpr.name;
19771                }
19772                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19773                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19774                        // Special handling of clients who are in the top state.
19775                        // We *may* want to consider this process to be in the
19776                        // top state as well, but only if there is not another
19777                        // reason for it to be running.  Being on the top is a
19778                        // special state, meaning you are specifically running
19779                        // for the current top app.  If the process is already
19780                        // running in the background for some other reason, it
19781                        // is more important to continue considering it to be
19782                        // in the background state.
19783                        mayBeTop = true;
19784                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19785                    } else {
19786                        // Special handling for above-top states (persistent
19787                        // processes).  These should not bring the current process
19788                        // into the top state, since they are not on top.  Instead
19789                        // give them the best state after that.
19790                        clientProcState =
19791                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19792                    }
19793                }
19794                if (procState > clientProcState) {
19795                    procState = clientProcState;
19796                }
19797                if (client.curSchedGroup > schedGroup) {
19798                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19799                }
19800            }
19801            // If the provider has external (non-framework) process
19802            // dependencies, ensure that its adjustment is at least
19803            // FOREGROUND_APP_ADJ.
19804            if (cpr.hasExternalProcessHandles()) {
19805                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19806                    adj = ProcessList.FOREGROUND_APP_ADJ;
19807                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19808                    app.cached = false;
19809                    app.adjType = "provider";
19810                    app.adjTarget = cpr.name;
19811                }
19812                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19813                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19814                }
19815            }
19816        }
19817
19818        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19819            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19820                adj = ProcessList.PREVIOUS_APP_ADJ;
19821                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19822                app.cached = false;
19823                app.adjType = "provider";
19824            }
19825            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19826                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19827            }
19828        }
19829
19830        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19831            // A client of one of our services or providers is in the top state.  We
19832            // *may* want to be in the top state, but not if we are already running in
19833            // the background for some other reason.  For the decision here, we are going
19834            // to pick out a few specific states that we want to remain in when a client
19835            // is top (states that tend to be longer-term) and otherwise allow it to go
19836            // to the top state.
19837            switch (procState) {
19838                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19839                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19840                case ActivityManager.PROCESS_STATE_SERVICE:
19841                    // These all are longer-term states, so pull them up to the top
19842                    // of the background states, but not all the way to the top state.
19843                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19844                    break;
19845                default:
19846                    // Otherwise, top is a better choice, so take it.
19847                    procState = ActivityManager.PROCESS_STATE_TOP;
19848                    break;
19849            }
19850        }
19851
19852        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19853            if (app.hasClientActivities) {
19854                // This is a cached process, but with client activities.  Mark it so.
19855                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19856                app.adjType = "cch-client-act";
19857            } else if (app.treatLikeActivity) {
19858                // This is a cached process, but somebody wants us to treat it like it has
19859                // an activity, okay!
19860                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19861                app.adjType = "cch-as-act";
19862            }
19863        }
19864
19865        if (adj == ProcessList.SERVICE_ADJ) {
19866            if (doingAll) {
19867                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19868                mNewNumServiceProcs++;
19869                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19870                if (!app.serviceb) {
19871                    // This service isn't far enough down on the LRU list to
19872                    // normally be a B service, but if we are low on RAM and it
19873                    // is large we want to force it down since we would prefer to
19874                    // keep launcher over it.
19875                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19876                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19877                        app.serviceHighRam = true;
19878                        app.serviceb = true;
19879                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19880                    } else {
19881                        mNewNumAServiceProcs++;
19882                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19883                    }
19884                } else {
19885                    app.serviceHighRam = false;
19886                }
19887            }
19888            if (app.serviceb) {
19889                adj = ProcessList.SERVICE_B_ADJ;
19890            }
19891        }
19892
19893        app.curRawAdj = adj;
19894
19895        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19896        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19897        if (adj > app.maxAdj) {
19898            adj = app.maxAdj;
19899            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19900                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19901            }
19902        }
19903
19904        // Do final modification to adj.  Everything we do between here and applying
19905        // the final setAdj must be done in this function, because we will also use
19906        // it when computing the final cached adj later.  Note that we don't need to
19907        // worry about this for max adj above, since max adj will always be used to
19908        // keep it out of the cached vaues.
19909        app.curAdj = app.modifyRawOomAdj(adj);
19910        app.curSchedGroup = schedGroup;
19911        app.curProcState = procState;
19912        app.foregroundActivities = foregroundActivities;
19913
19914        return app.curRawAdj;
19915    }
19916
19917    /**
19918     * Record new PSS sample for a process.
19919     */
19920    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19921            long now) {
19922        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19923                swapPss * 1024);
19924        proc.lastPssTime = now;
19925        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19926        if (DEBUG_PSS) Slog.d(TAG_PSS,
19927                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19928                + " state=" + ProcessList.makeProcStateString(procState));
19929        if (proc.initialIdlePss == 0) {
19930            proc.initialIdlePss = pss;
19931        }
19932        proc.lastPss = pss;
19933        proc.lastSwapPss = swapPss;
19934        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19935            proc.lastCachedPss = pss;
19936            proc.lastCachedSwapPss = swapPss;
19937        }
19938
19939        final SparseArray<Pair<Long, String>> watchUids
19940                = mMemWatchProcesses.getMap().get(proc.processName);
19941        Long check = null;
19942        if (watchUids != null) {
19943            Pair<Long, String> val = watchUids.get(proc.uid);
19944            if (val == null) {
19945                val = watchUids.get(0);
19946            }
19947            if (val != null) {
19948                check = val.first;
19949            }
19950        }
19951        if (check != null) {
19952            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19953                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19954                if (!isDebuggable) {
19955                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19956                        isDebuggable = true;
19957                    }
19958                }
19959                if (isDebuggable) {
19960                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19961                    final ProcessRecord myProc = proc;
19962                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19963                    mMemWatchDumpProcName = proc.processName;
19964                    mMemWatchDumpFile = heapdumpFile.toString();
19965                    mMemWatchDumpPid = proc.pid;
19966                    mMemWatchDumpUid = proc.uid;
19967                    BackgroundThread.getHandler().post(new Runnable() {
19968                        @Override
19969                        public void run() {
19970                            revokeUriPermission(ActivityThread.currentActivityThread()
19971                                            .getApplicationThread(),
19972                                    DumpHeapActivity.JAVA_URI,
19973                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19974                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19975                                    UserHandle.myUserId());
19976                            ParcelFileDescriptor fd = null;
19977                            try {
19978                                heapdumpFile.delete();
19979                                fd = ParcelFileDescriptor.open(heapdumpFile,
19980                                        ParcelFileDescriptor.MODE_CREATE |
19981                                                ParcelFileDescriptor.MODE_TRUNCATE |
19982                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19983                                                ParcelFileDescriptor.MODE_APPEND);
19984                                IApplicationThread thread = myProc.thread;
19985                                if (thread != null) {
19986                                    try {
19987                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19988                                                "Requesting dump heap from "
19989                                                + myProc + " to " + heapdumpFile);
19990                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19991                                    } catch (RemoteException e) {
19992                                    }
19993                                }
19994                            } catch (FileNotFoundException e) {
19995                                e.printStackTrace();
19996                            } finally {
19997                                if (fd != null) {
19998                                    try {
19999                                        fd.close();
20000                                    } catch (IOException e) {
20001                                    }
20002                                }
20003                            }
20004                        }
20005                    });
20006                } else {
20007                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20008                            + ", but debugging not enabled");
20009                }
20010            }
20011        }
20012    }
20013
20014    /**
20015     * Schedule PSS collection of a process.
20016     */
20017    void requestPssLocked(ProcessRecord proc, int procState) {
20018        if (mPendingPssProcesses.contains(proc)) {
20019            return;
20020        }
20021        if (mPendingPssProcesses.size() == 0) {
20022            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20023        }
20024        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20025        proc.pssProcState = procState;
20026        mPendingPssProcesses.add(proc);
20027    }
20028
20029    /**
20030     * Schedule PSS collection of all processes.
20031     */
20032    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20033        if (!always) {
20034            if (now < (mLastFullPssTime +
20035                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20036                return;
20037            }
20038        }
20039        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20040        mLastFullPssTime = now;
20041        mFullPssPending = true;
20042        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20043        mPendingPssProcesses.clear();
20044        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20045            ProcessRecord app = mLruProcesses.get(i);
20046            if (app.thread == null
20047                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20048                continue;
20049            }
20050            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20051                app.pssProcState = app.setProcState;
20052                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20053                        mTestPssMode, isSleepingLocked(), now);
20054                mPendingPssProcesses.add(app);
20055            }
20056        }
20057        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20058    }
20059
20060    public void setTestPssMode(boolean enabled) {
20061        synchronized (this) {
20062            mTestPssMode = enabled;
20063            if (enabled) {
20064                // Whenever we enable the mode, we want to take a snapshot all of current
20065                // process mem use.
20066                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20067            }
20068        }
20069    }
20070
20071    /**
20072     * Ask a given process to GC right now.
20073     */
20074    final void performAppGcLocked(ProcessRecord app) {
20075        try {
20076            app.lastRequestedGc = SystemClock.uptimeMillis();
20077            if (app.thread != null) {
20078                if (app.reportLowMemory) {
20079                    app.reportLowMemory = false;
20080                    app.thread.scheduleLowMemory();
20081                } else {
20082                    app.thread.processInBackground();
20083                }
20084            }
20085        } catch (Exception e) {
20086            // whatever.
20087        }
20088    }
20089
20090    /**
20091     * Returns true if things are idle enough to perform GCs.
20092     */
20093    private final boolean canGcNowLocked() {
20094        boolean processingBroadcasts = false;
20095        for (BroadcastQueue q : mBroadcastQueues) {
20096            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20097                processingBroadcasts = true;
20098            }
20099        }
20100        return !processingBroadcasts
20101                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20102    }
20103
20104    /**
20105     * Perform GCs on all processes that are waiting for it, but only
20106     * if things are idle.
20107     */
20108    final void performAppGcsLocked() {
20109        final int N = mProcessesToGc.size();
20110        if (N <= 0) {
20111            return;
20112        }
20113        if (canGcNowLocked()) {
20114            while (mProcessesToGc.size() > 0) {
20115                ProcessRecord proc = mProcessesToGc.remove(0);
20116                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20117                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20118                            <= SystemClock.uptimeMillis()) {
20119                        // To avoid spamming the system, we will GC processes one
20120                        // at a time, waiting a few seconds between each.
20121                        performAppGcLocked(proc);
20122                        scheduleAppGcsLocked();
20123                        return;
20124                    } else {
20125                        // It hasn't been long enough since we last GCed this
20126                        // process...  put it in the list to wait for its time.
20127                        addProcessToGcListLocked(proc);
20128                        break;
20129                    }
20130                }
20131            }
20132
20133            scheduleAppGcsLocked();
20134        }
20135    }
20136
20137    /**
20138     * If all looks good, perform GCs on all processes waiting for them.
20139     */
20140    final void performAppGcsIfAppropriateLocked() {
20141        if (canGcNowLocked()) {
20142            performAppGcsLocked();
20143            return;
20144        }
20145        // Still not idle, wait some more.
20146        scheduleAppGcsLocked();
20147    }
20148
20149    /**
20150     * Schedule the execution of all pending app GCs.
20151     */
20152    final void scheduleAppGcsLocked() {
20153        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20154
20155        if (mProcessesToGc.size() > 0) {
20156            // Schedule a GC for the time to the next process.
20157            ProcessRecord proc = mProcessesToGc.get(0);
20158            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20159
20160            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20161            long now = SystemClock.uptimeMillis();
20162            if (when < (now+GC_TIMEOUT)) {
20163                when = now + GC_TIMEOUT;
20164            }
20165            mHandler.sendMessageAtTime(msg, when);
20166        }
20167    }
20168
20169    /**
20170     * Add a process to the array of processes waiting to be GCed.  Keeps the
20171     * list in sorted order by the last GC time.  The process can't already be
20172     * on the list.
20173     */
20174    final void addProcessToGcListLocked(ProcessRecord proc) {
20175        boolean added = false;
20176        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20177            if (mProcessesToGc.get(i).lastRequestedGc <
20178                    proc.lastRequestedGc) {
20179                added = true;
20180                mProcessesToGc.add(i+1, proc);
20181                break;
20182            }
20183        }
20184        if (!added) {
20185            mProcessesToGc.add(0, proc);
20186        }
20187    }
20188
20189    /**
20190     * Set up to ask a process to GC itself.  This will either do it
20191     * immediately, or put it on the list of processes to gc the next
20192     * time things are idle.
20193     */
20194    final void scheduleAppGcLocked(ProcessRecord app) {
20195        long now = SystemClock.uptimeMillis();
20196        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20197            return;
20198        }
20199        if (!mProcessesToGc.contains(app)) {
20200            addProcessToGcListLocked(app);
20201            scheduleAppGcsLocked();
20202        }
20203    }
20204
20205    final void checkExcessivePowerUsageLocked(boolean doKills) {
20206        updateCpuStatsNow();
20207
20208        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20209        boolean doWakeKills = doKills;
20210        boolean doCpuKills = doKills;
20211        if (mLastPowerCheckRealtime == 0) {
20212            doWakeKills = false;
20213        }
20214        if (mLastPowerCheckUptime == 0) {
20215            doCpuKills = false;
20216        }
20217        if (stats.isScreenOn()) {
20218            doWakeKills = false;
20219        }
20220        final long curRealtime = SystemClock.elapsedRealtime();
20221        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20222        final long curUptime = SystemClock.uptimeMillis();
20223        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20224        mLastPowerCheckRealtime = curRealtime;
20225        mLastPowerCheckUptime = curUptime;
20226        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20227            doWakeKills = false;
20228        }
20229        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20230            doCpuKills = false;
20231        }
20232        int i = mLruProcesses.size();
20233        while (i > 0) {
20234            i--;
20235            ProcessRecord app = mLruProcesses.get(i);
20236            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20237                long wtime;
20238                synchronized (stats) {
20239                    wtime = stats.getProcessWakeTime(app.info.uid,
20240                            app.pid, curRealtime);
20241                }
20242                long wtimeUsed = wtime - app.lastWakeTime;
20243                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20244                if (DEBUG_POWER) {
20245                    StringBuilder sb = new StringBuilder(128);
20246                    sb.append("Wake for ");
20247                    app.toShortString(sb);
20248                    sb.append(": over ");
20249                    TimeUtils.formatDuration(realtimeSince, sb);
20250                    sb.append(" used ");
20251                    TimeUtils.formatDuration(wtimeUsed, sb);
20252                    sb.append(" (");
20253                    sb.append((wtimeUsed*100)/realtimeSince);
20254                    sb.append("%)");
20255                    Slog.i(TAG_POWER, sb.toString());
20256                    sb.setLength(0);
20257                    sb.append("CPU for ");
20258                    app.toShortString(sb);
20259                    sb.append(": over ");
20260                    TimeUtils.formatDuration(uptimeSince, sb);
20261                    sb.append(" used ");
20262                    TimeUtils.formatDuration(cputimeUsed, sb);
20263                    sb.append(" (");
20264                    sb.append((cputimeUsed*100)/uptimeSince);
20265                    sb.append("%)");
20266                    Slog.i(TAG_POWER, sb.toString());
20267                }
20268                // If a process has held a wake lock for more
20269                // than 50% of the time during this period,
20270                // that sounds bad.  Kill!
20271                if (doWakeKills && realtimeSince > 0
20272                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20273                    synchronized (stats) {
20274                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20275                                realtimeSince, wtimeUsed);
20276                    }
20277                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20278                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20279                } else if (doCpuKills && uptimeSince > 0
20280                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20281                    synchronized (stats) {
20282                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20283                                uptimeSince, cputimeUsed);
20284                    }
20285                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20286                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20287                } else {
20288                    app.lastWakeTime = wtime;
20289                    app.lastCpuTime = app.curCpuTime;
20290                }
20291            }
20292        }
20293    }
20294
20295    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20296            long nowElapsed) {
20297        boolean success = true;
20298
20299        if (app.curRawAdj != app.setRawAdj) {
20300            app.setRawAdj = app.curRawAdj;
20301        }
20302
20303        int changes = 0;
20304
20305        if (app.curAdj != app.setAdj) {
20306            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20307            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20308                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20309                    + app.adjType);
20310            app.setAdj = app.curAdj;
20311            app.verifiedAdj = ProcessList.INVALID_ADJ;
20312        }
20313
20314        if (app.setSchedGroup != app.curSchedGroup) {
20315            int oldSchedGroup = app.setSchedGroup;
20316            app.setSchedGroup = app.curSchedGroup;
20317            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20318                    "Setting sched group of " + app.processName
20319                    + " to " + app.curSchedGroup);
20320            if (app.waitingToKill != null && app.curReceiver == null
20321                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20322                app.kill(app.waitingToKill, true);
20323                success = false;
20324            } else {
20325                int processGroup;
20326                switch (app.curSchedGroup) {
20327                    case ProcessList.SCHED_GROUP_BACKGROUND:
20328                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20329                        break;
20330                    case ProcessList.SCHED_GROUP_TOP_APP:
20331                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20332                        processGroup = Process.THREAD_GROUP_TOP_APP;
20333                        break;
20334                    default:
20335                        processGroup = Process.THREAD_GROUP_DEFAULT;
20336                        break;
20337                }
20338                long oldId = Binder.clearCallingIdentity();
20339                try {
20340                    Process.setProcessGroup(app.pid, processGroup);
20341                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20342                        // do nothing if we already switched to RT
20343                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20344                            // Switch VR thread for app to SCHED_FIFO
20345                            if (mInVrMode && app.vrThreadTid != 0) {
20346                                Process.setThreadScheduler(app.vrThreadTid,
20347                                    Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20348                            }
20349                            if (mUseFifoUiScheduling) {
20350                                // Switch UI pipeline for app to SCHED_FIFO
20351                                app.savedPriority = Process.getThreadPriority(app.pid);
20352                                Process.setThreadScheduler(app.pid,
20353                                    Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20354                                if (app.renderThreadTid != 0) {
20355                                    Process.setThreadScheduler(app.renderThreadTid,
20356                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20357                                    if (DEBUG_OOM_ADJ) {
20358                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20359                                            app.renderThreadTid + ") to FIFO");
20360                                    }
20361                                } else {
20362                                    if (DEBUG_OOM_ADJ) {
20363                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20364                                    }
20365                                }
20366                            } else {
20367                                // Boost priority for top app UI and render threads
20368                                Process.setThreadPriority(app.pid, -10);
20369                                if (app.renderThreadTid != 0) {
20370                                    Process.setThreadPriority(app.renderThreadTid, -10);
20371                                }
20372                            }
20373                        }
20374                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20375                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20376                        // Reset VR thread to SCHED_OTHER
20377                        // Safe to do even if we're not in VR mode
20378                        if (app.vrThreadTid != 0) {
20379                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20380                        }
20381                        if (mUseFifoUiScheduling) {
20382                            // Reset UI pipeline to SCHED_OTHER
20383                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20384                            Process.setThreadPriority(app.pid, app.savedPriority);
20385                            if (app.renderThreadTid != 0) {
20386                                Process.setThreadScheduler(app.renderThreadTid,
20387                                    Process.SCHED_OTHER, 0);
20388                                Process.setThreadPriority(app.renderThreadTid, -4);
20389                            }
20390                        } else {
20391                            // Reset priority for top app UI and render threads
20392                            Process.setThreadPriority(app.pid, 0);
20393                            if (app.renderThreadTid != 0) {
20394                                Process.setThreadPriority(app.renderThreadTid, 0);
20395                            }
20396                        }
20397                    }
20398                } catch (Exception e) {
20399                    Slog.w(TAG, "Failed setting process group of " + app.pid
20400                            + " to " + app.curSchedGroup);
20401                    e.printStackTrace();
20402                } finally {
20403                    Binder.restoreCallingIdentity(oldId);
20404                }
20405            }
20406        }
20407        if (app.repForegroundActivities != app.foregroundActivities) {
20408            app.repForegroundActivities = app.foregroundActivities;
20409            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20410        }
20411        if (app.repProcState != app.curProcState) {
20412            app.repProcState = app.curProcState;
20413            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20414            if (app.thread != null) {
20415                try {
20416                    if (false) {
20417                        //RuntimeException h = new RuntimeException("here");
20418                        Slog.i(TAG, "Sending new process state " + app.repProcState
20419                                + " to " + app /*, h*/);
20420                    }
20421                    app.thread.setProcessState(app.repProcState);
20422                } catch (RemoteException e) {
20423                }
20424            }
20425        }
20426        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20427                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20428            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20429                // Experimental code to more aggressively collect pss while
20430                // running test...  the problem is that this tends to collect
20431                // the data right when a process is transitioning between process
20432                // states, which well tend to give noisy data.
20433                long start = SystemClock.uptimeMillis();
20434                long pss = Debug.getPss(app.pid, mTmpLong, null);
20435                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20436                mPendingPssProcesses.remove(app);
20437                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20438                        + " to " + app.curProcState + ": "
20439                        + (SystemClock.uptimeMillis()-start) + "ms");
20440            }
20441            app.lastStateTime = now;
20442            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20443                    mTestPssMode, isSleepingLocked(), now);
20444            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20445                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20446                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20447                    + (app.nextPssTime-now) + ": " + app);
20448        } else {
20449            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20450                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20451                    mTestPssMode)))) {
20452                requestPssLocked(app, app.setProcState);
20453                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20454                        mTestPssMode, isSleepingLocked(), now);
20455            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20456                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20457        }
20458        if (app.setProcState != app.curProcState) {
20459            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20460                    "Proc state change of " + app.processName
20461                            + " to " + app.curProcState);
20462            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20463            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20464            if (setImportant && !curImportant) {
20465                // This app is no longer something we consider important enough to allow to
20466                // use arbitrary amounts of battery power.  Note
20467                // its current wake lock time to later know to kill it if
20468                // it is not behaving well.
20469                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20470                synchronized (stats) {
20471                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20472                            app.pid, nowElapsed);
20473                }
20474                app.lastCpuTime = app.curCpuTime;
20475
20476            }
20477            // Inform UsageStats of important process state change
20478            // Must be called before updating setProcState
20479            maybeUpdateUsageStatsLocked(app, nowElapsed);
20480
20481            app.setProcState = app.curProcState;
20482            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20483                app.notCachedSinceIdle = false;
20484            }
20485            if (!doingAll) {
20486                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20487            } else {
20488                app.procStateChanged = true;
20489            }
20490        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20491                > USAGE_STATS_INTERACTION_INTERVAL) {
20492            // For apps that sit around for a long time in the interactive state, we need
20493            // to report this at least once a day so they don't go idle.
20494            maybeUpdateUsageStatsLocked(app, nowElapsed);
20495        }
20496
20497        if (changes != 0) {
20498            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20499                    "Changes in " + app + ": " + changes);
20500            int i = mPendingProcessChanges.size()-1;
20501            ProcessChangeItem item = null;
20502            while (i >= 0) {
20503                item = mPendingProcessChanges.get(i);
20504                if (item.pid == app.pid) {
20505                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20506                            "Re-using existing item: " + item);
20507                    break;
20508                }
20509                i--;
20510            }
20511            if (i < 0) {
20512                // No existing item in pending changes; need a new one.
20513                final int NA = mAvailProcessChanges.size();
20514                if (NA > 0) {
20515                    item = mAvailProcessChanges.remove(NA-1);
20516                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20517                            "Retrieving available item: " + item);
20518                } else {
20519                    item = new ProcessChangeItem();
20520                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20521                            "Allocating new item: " + item);
20522                }
20523                item.changes = 0;
20524                item.pid = app.pid;
20525                item.uid = app.info.uid;
20526                if (mPendingProcessChanges.size() == 0) {
20527                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20528                            "*** Enqueueing dispatch processes changed!");
20529                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20530                }
20531                mPendingProcessChanges.add(item);
20532            }
20533            item.changes |= changes;
20534            item.processState = app.repProcState;
20535            item.foregroundActivities = app.repForegroundActivities;
20536            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20537                    "Item " + Integer.toHexString(System.identityHashCode(item))
20538                    + " " + app.toShortString() + ": changes=" + item.changes
20539                    + " procState=" + item.processState
20540                    + " foreground=" + item.foregroundActivities
20541                    + " type=" + app.adjType + " source=" + app.adjSource
20542                    + " target=" + app.adjTarget);
20543        }
20544
20545        return success;
20546    }
20547
20548    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20549        final UidRecord.ChangeItem pendingChange;
20550        if (uidRec == null || uidRec.pendingChange == null) {
20551            if (mPendingUidChanges.size() == 0) {
20552                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20553                        "*** Enqueueing dispatch uid changed!");
20554                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20555            }
20556            final int NA = mAvailUidChanges.size();
20557            if (NA > 0) {
20558                pendingChange = mAvailUidChanges.remove(NA-1);
20559                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20560                        "Retrieving available item: " + pendingChange);
20561            } else {
20562                pendingChange = new UidRecord.ChangeItem();
20563                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20564                        "Allocating new item: " + pendingChange);
20565            }
20566            if (uidRec != null) {
20567                uidRec.pendingChange = pendingChange;
20568                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20569                    // If this uid is going away, and we haven't yet reported it is gone,
20570                    // then do so now.
20571                    change = UidRecord.CHANGE_GONE_IDLE;
20572                }
20573            } else if (uid < 0) {
20574                throw new IllegalArgumentException("No UidRecord or uid");
20575            }
20576            pendingChange.uidRecord = uidRec;
20577            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20578            mPendingUidChanges.add(pendingChange);
20579        } else {
20580            pendingChange = uidRec.pendingChange;
20581            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20582                change = UidRecord.CHANGE_GONE_IDLE;
20583            }
20584        }
20585        pendingChange.change = change;
20586        pendingChange.processState = uidRec != null
20587                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20588    }
20589
20590    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20591            String authority) {
20592        if (app == null) return;
20593        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20594            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20595            if (userState == null) return;
20596            final long now = SystemClock.elapsedRealtime();
20597            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20598            if (lastReported == null || lastReported < now - 60 * 1000L) {
20599                mUsageStatsService.reportContentProviderUsage(
20600                        authority, providerPkgName, app.userId);
20601                userState.mProviderLastReportedFg.put(authority, now);
20602            }
20603        }
20604    }
20605
20606    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20607        if (DEBUG_USAGE_STATS) {
20608            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20609                    + "] state changes: old = " + app.setProcState + ", new = "
20610                    + app.curProcState);
20611        }
20612        if (mUsageStatsService == null) {
20613            return;
20614        }
20615        boolean isInteraction;
20616        // To avoid some abuse patterns, we are going to be careful about what we consider
20617        // to be an app interaction.  Being the top activity doesn't count while the display
20618        // is sleeping, nor do short foreground services.
20619        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20620            isInteraction = true;
20621            app.fgInteractionTime = 0;
20622        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20623            if (app.fgInteractionTime == 0) {
20624                app.fgInteractionTime = nowElapsed;
20625                isInteraction = false;
20626            } else {
20627                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20628            }
20629        } else {
20630            isInteraction = app.curProcState
20631                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20632            app.fgInteractionTime = 0;
20633        }
20634        if (isInteraction && (!app.reportedInteraction
20635                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20636            app.interactionEventTime = nowElapsed;
20637            String[] packages = app.getPackageList();
20638            if (packages != null) {
20639                for (int i = 0; i < packages.length; i++) {
20640                    mUsageStatsService.reportEvent(packages[i], app.userId,
20641                            UsageEvents.Event.SYSTEM_INTERACTION);
20642                }
20643            }
20644        }
20645        app.reportedInteraction = isInteraction;
20646        if (!isInteraction) {
20647            app.interactionEventTime = 0;
20648        }
20649    }
20650
20651    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20652        if (proc.thread != null) {
20653            if (proc.baseProcessTracker != null) {
20654                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20655            }
20656        }
20657    }
20658
20659    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20660            ProcessRecord TOP_APP, boolean doingAll, long now) {
20661        if (app.thread == null) {
20662            return false;
20663        }
20664
20665        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20666
20667        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20668    }
20669
20670    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20671            boolean oomAdj) {
20672        if (isForeground != proc.foregroundServices) {
20673            proc.foregroundServices = isForeground;
20674            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20675                    proc.info.uid);
20676            if (isForeground) {
20677                if (curProcs == null) {
20678                    curProcs = new ArrayList<ProcessRecord>();
20679                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20680                }
20681                if (!curProcs.contains(proc)) {
20682                    curProcs.add(proc);
20683                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20684                            proc.info.packageName, proc.info.uid);
20685                }
20686            } else {
20687                if (curProcs != null) {
20688                    if (curProcs.remove(proc)) {
20689                        mBatteryStatsService.noteEvent(
20690                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20691                                proc.info.packageName, proc.info.uid);
20692                        if (curProcs.size() <= 0) {
20693                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20694                        }
20695                    }
20696                }
20697            }
20698            if (oomAdj) {
20699                updateOomAdjLocked();
20700            }
20701        }
20702    }
20703
20704    private final ActivityRecord resumedAppLocked() {
20705        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20706        String pkg;
20707        int uid;
20708        if (act != null) {
20709            pkg = act.packageName;
20710            uid = act.info.applicationInfo.uid;
20711        } else {
20712            pkg = null;
20713            uid = -1;
20714        }
20715        // Has the UID or resumed package name changed?
20716        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20717                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20718            if (mCurResumedPackage != null) {
20719                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20720                        mCurResumedPackage, mCurResumedUid);
20721            }
20722            mCurResumedPackage = pkg;
20723            mCurResumedUid = uid;
20724            if (mCurResumedPackage != null) {
20725                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20726                        mCurResumedPackage, mCurResumedUid);
20727            }
20728        }
20729        return act;
20730    }
20731
20732    final boolean updateOomAdjLocked(ProcessRecord app) {
20733        final ActivityRecord TOP_ACT = resumedAppLocked();
20734        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20735        final boolean wasCached = app.cached;
20736
20737        mAdjSeq++;
20738
20739        // This is the desired cached adjusment we want to tell it to use.
20740        // If our app is currently cached, we know it, and that is it.  Otherwise,
20741        // we don't know it yet, and it needs to now be cached we will then
20742        // need to do a complete oom adj.
20743        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20744                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20745        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20746                SystemClock.uptimeMillis());
20747        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20748            // Changed to/from cached state, so apps after it in the LRU
20749            // list may also be changed.
20750            updateOomAdjLocked();
20751        }
20752        return success;
20753    }
20754
20755    final void updateOomAdjLocked() {
20756        final ActivityRecord TOP_ACT = resumedAppLocked();
20757        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20758        final long now = SystemClock.uptimeMillis();
20759        final long nowElapsed = SystemClock.elapsedRealtime();
20760        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20761        final int N = mLruProcesses.size();
20762
20763        if (false) {
20764            RuntimeException e = new RuntimeException();
20765            e.fillInStackTrace();
20766            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20767        }
20768
20769        // Reset state in all uid records.
20770        for (int i=mActiveUids.size()-1; i>=0; i--) {
20771            final UidRecord uidRec = mActiveUids.valueAt(i);
20772            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20773                    "Starting update of " + uidRec);
20774            uidRec.reset();
20775        }
20776
20777        mStackSupervisor.rankTaskLayersIfNeeded();
20778
20779        mAdjSeq++;
20780        mNewNumServiceProcs = 0;
20781        mNewNumAServiceProcs = 0;
20782
20783        final int emptyProcessLimit;
20784        final int cachedProcessLimit;
20785        if (mProcessLimit <= 0) {
20786            emptyProcessLimit = cachedProcessLimit = 0;
20787        } else if (mProcessLimit == 1) {
20788            emptyProcessLimit = 1;
20789            cachedProcessLimit = 0;
20790        } else {
20791            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20792            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20793        }
20794
20795        // Let's determine how many processes we have running vs.
20796        // how many slots we have for background processes; we may want
20797        // to put multiple processes in a slot of there are enough of
20798        // them.
20799        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20800                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20801        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20802        if (numEmptyProcs > cachedProcessLimit) {
20803            // If there are more empty processes than our limit on cached
20804            // processes, then use the cached process limit for the factor.
20805            // This ensures that the really old empty processes get pushed
20806            // down to the bottom, so if we are running low on memory we will
20807            // have a better chance at keeping around more cached processes
20808            // instead of a gazillion empty processes.
20809            numEmptyProcs = cachedProcessLimit;
20810        }
20811        int emptyFactor = numEmptyProcs/numSlots;
20812        if (emptyFactor < 1) emptyFactor = 1;
20813        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20814        if (cachedFactor < 1) cachedFactor = 1;
20815        int stepCached = 0;
20816        int stepEmpty = 0;
20817        int numCached = 0;
20818        int numEmpty = 0;
20819        int numTrimming = 0;
20820
20821        mNumNonCachedProcs = 0;
20822        mNumCachedHiddenProcs = 0;
20823
20824        // First update the OOM adjustment for each of the
20825        // application processes based on their current state.
20826        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20827        int nextCachedAdj = curCachedAdj+1;
20828        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20829        int nextEmptyAdj = curEmptyAdj+2;
20830        for (int i=N-1; i>=0; i--) {
20831            ProcessRecord app = mLruProcesses.get(i);
20832            if (!app.killedByAm && app.thread != null) {
20833                app.procStateChanged = false;
20834                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20835
20836                // If we haven't yet assigned the final cached adj
20837                // to the process, do that now.
20838                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20839                    switch (app.curProcState) {
20840                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20841                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20842                            // This process is a cached process holding activities...
20843                            // assign it the next cached value for that type, and then
20844                            // step that cached level.
20845                            app.curRawAdj = curCachedAdj;
20846                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20847                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20848                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20849                                    + ")");
20850                            if (curCachedAdj != nextCachedAdj) {
20851                                stepCached++;
20852                                if (stepCached >= cachedFactor) {
20853                                    stepCached = 0;
20854                                    curCachedAdj = nextCachedAdj;
20855                                    nextCachedAdj += 2;
20856                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20857                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20858                                    }
20859                                }
20860                            }
20861                            break;
20862                        default:
20863                            // For everything else, assign next empty cached process
20864                            // level and bump that up.  Note that this means that
20865                            // long-running services that have dropped down to the
20866                            // cached level will be treated as empty (since their process
20867                            // state is still as a service), which is what we want.
20868                            app.curRawAdj = curEmptyAdj;
20869                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20870                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20871                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20872                                    + ")");
20873                            if (curEmptyAdj != nextEmptyAdj) {
20874                                stepEmpty++;
20875                                if (stepEmpty >= emptyFactor) {
20876                                    stepEmpty = 0;
20877                                    curEmptyAdj = nextEmptyAdj;
20878                                    nextEmptyAdj += 2;
20879                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20880                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20881                                    }
20882                                }
20883                            }
20884                            break;
20885                    }
20886                }
20887
20888                applyOomAdjLocked(app, true, now, nowElapsed);
20889
20890                // Count the number of process types.
20891                switch (app.curProcState) {
20892                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20893                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20894                        mNumCachedHiddenProcs++;
20895                        numCached++;
20896                        if (numCached > cachedProcessLimit) {
20897                            app.kill("cached #" + numCached, true);
20898                        }
20899                        break;
20900                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20901                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20902                                && app.lastActivityTime < oldTime) {
20903                            app.kill("empty for "
20904                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20905                                    / 1000) + "s", true);
20906                        } else {
20907                            numEmpty++;
20908                            if (numEmpty > emptyProcessLimit) {
20909                                app.kill("empty #" + numEmpty, true);
20910                            }
20911                        }
20912                        break;
20913                    default:
20914                        mNumNonCachedProcs++;
20915                        break;
20916                }
20917
20918                if (app.isolated && app.services.size() <= 0) {
20919                    // If this is an isolated process, and there are no
20920                    // services running in it, then the process is no longer
20921                    // needed.  We agressively kill these because we can by
20922                    // definition not re-use the same process again, and it is
20923                    // good to avoid having whatever code was running in them
20924                    // left sitting around after no longer needed.
20925                    app.kill("isolated not needed", true);
20926                } else {
20927                    // Keeping this process, update its uid.
20928                    final UidRecord uidRec = app.uidRecord;
20929                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20930                        uidRec.curProcState = app.curProcState;
20931                    }
20932                }
20933
20934                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20935                        && !app.killedByAm) {
20936                    numTrimming++;
20937                }
20938            }
20939        }
20940
20941        mNumServiceProcs = mNewNumServiceProcs;
20942
20943        // Now determine the memory trimming level of background processes.
20944        // Unfortunately we need to start at the back of the list to do this
20945        // properly.  We only do this if the number of background apps we
20946        // are managing to keep around is less than half the maximum we desire;
20947        // if we are keeping a good number around, we'll let them use whatever
20948        // memory they want.
20949        final int numCachedAndEmpty = numCached + numEmpty;
20950        int memFactor;
20951        if (numCached <= ProcessList.TRIM_CACHED_APPS
20952                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20953            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20954                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20955            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20956                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20957            } else {
20958                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20959            }
20960        } else {
20961            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20962        }
20963        // We always allow the memory level to go up (better).  We only allow it to go
20964        // down if we are in a state where that is allowed, *and* the total number of processes
20965        // has gone down since last time.
20966        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20967                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20968                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20969        if (memFactor > mLastMemoryLevel) {
20970            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20971                memFactor = mLastMemoryLevel;
20972                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20973            }
20974        }
20975        if (memFactor != mLastMemoryLevel) {
20976            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20977        }
20978        mLastMemoryLevel = memFactor;
20979        mLastNumProcesses = mLruProcesses.size();
20980        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20981        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20982        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20983            if (mLowRamStartTime == 0) {
20984                mLowRamStartTime = now;
20985            }
20986            int step = 0;
20987            int fgTrimLevel;
20988            switch (memFactor) {
20989                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20990                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20991                    break;
20992                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20993                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20994                    break;
20995                default:
20996                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20997                    break;
20998            }
20999            int factor = numTrimming/3;
21000            int minFactor = 2;
21001            if (mHomeProcess != null) minFactor++;
21002            if (mPreviousProcess != null) minFactor++;
21003            if (factor < minFactor) factor = minFactor;
21004            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21005            for (int i=N-1; i>=0; i--) {
21006                ProcessRecord app = mLruProcesses.get(i);
21007                if (allChanged || app.procStateChanged) {
21008                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21009                    app.procStateChanged = false;
21010                }
21011                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21012                        && !app.killedByAm) {
21013                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21014                        try {
21015                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21016                                    "Trimming memory of " + app.processName + " to " + curLevel);
21017                            app.thread.scheduleTrimMemory(curLevel);
21018                        } catch (RemoteException e) {
21019                        }
21020                        if (false) {
21021                            // For now we won't do this; our memory trimming seems
21022                            // to be good enough at this point that destroying
21023                            // activities causes more harm than good.
21024                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21025                                    && app != mHomeProcess && app != mPreviousProcess) {
21026                                // Need to do this on its own message because the stack may not
21027                                // be in a consistent state at this point.
21028                                // For these apps we will also finish their activities
21029                                // to help them free memory.
21030                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21031                            }
21032                        }
21033                    }
21034                    app.trimMemoryLevel = curLevel;
21035                    step++;
21036                    if (step >= factor) {
21037                        step = 0;
21038                        switch (curLevel) {
21039                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21040                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21041                                break;
21042                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21043                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21044                                break;
21045                        }
21046                    }
21047                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21048                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21049                            && app.thread != null) {
21050                        try {
21051                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21052                                    "Trimming memory of heavy-weight " + app.processName
21053                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21054                            app.thread.scheduleTrimMemory(
21055                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21056                        } catch (RemoteException e) {
21057                        }
21058                    }
21059                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21060                } else {
21061                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21062                            || app.systemNoUi) && app.pendingUiClean) {
21063                        // If this application is now in the background and it
21064                        // had done UI, then give it the special trim level to
21065                        // have it free UI resources.
21066                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21067                        if (app.trimMemoryLevel < level && app.thread != null) {
21068                            try {
21069                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21070                                        "Trimming memory of bg-ui " + app.processName
21071                                        + " to " + level);
21072                                app.thread.scheduleTrimMemory(level);
21073                            } catch (RemoteException e) {
21074                            }
21075                        }
21076                        app.pendingUiClean = false;
21077                    }
21078                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21079                        try {
21080                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21081                                    "Trimming memory of fg " + app.processName
21082                                    + " to " + fgTrimLevel);
21083                            app.thread.scheduleTrimMemory(fgTrimLevel);
21084                        } catch (RemoteException e) {
21085                        }
21086                    }
21087                    app.trimMemoryLevel = fgTrimLevel;
21088                }
21089            }
21090        } else {
21091            if (mLowRamStartTime != 0) {
21092                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21093                mLowRamStartTime = 0;
21094            }
21095            for (int i=N-1; i>=0; i--) {
21096                ProcessRecord app = mLruProcesses.get(i);
21097                if (allChanged || app.procStateChanged) {
21098                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21099                    app.procStateChanged = false;
21100                }
21101                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21102                        || app.systemNoUi) && app.pendingUiClean) {
21103                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21104                            && app.thread != null) {
21105                        try {
21106                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21107                                    "Trimming memory of ui hidden " + app.processName
21108                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21109                            app.thread.scheduleTrimMemory(
21110                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21111                        } catch (RemoteException e) {
21112                        }
21113                    }
21114                    app.pendingUiClean = false;
21115                }
21116                app.trimMemoryLevel = 0;
21117            }
21118        }
21119
21120        if (mAlwaysFinishActivities) {
21121            // Need to do this on its own message because the stack may not
21122            // be in a consistent state at this point.
21123            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21124        }
21125
21126        if (allChanged) {
21127            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21128        }
21129
21130        // Update from any uid changes.
21131        for (int i=mActiveUids.size()-1; i>=0; i--) {
21132            final UidRecord uidRec = mActiveUids.valueAt(i);
21133            int uidChange = UidRecord.CHANGE_PROCSTATE;
21134            if (uidRec.setProcState != uidRec.curProcState) {
21135                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21136                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21137                        + " to " + uidRec.curProcState);
21138                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21139                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21140                        uidRec.lastBackgroundTime = nowElapsed;
21141                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21142                            // Note: the background settle time is in elapsed realtime, while
21143                            // the handler time base is uptime.  All this means is that we may
21144                            // stop background uids later than we had intended, but that only
21145                            // happens because the device was sleeping so we are okay anyway.
21146                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21147                        }
21148                    }
21149                } else {
21150                    if (uidRec.idle) {
21151                        uidChange = UidRecord.CHANGE_ACTIVE;
21152                        uidRec.idle = false;
21153                    }
21154                    uidRec.lastBackgroundTime = 0;
21155                }
21156                uidRec.setProcState = uidRec.curProcState;
21157                enqueueUidChangeLocked(uidRec, -1, uidChange);
21158                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21159            }
21160        }
21161
21162        if (mProcessStats.shouldWriteNowLocked(now)) {
21163            mHandler.post(new Runnable() {
21164                @Override public void run() {
21165                    synchronized (ActivityManagerService.this) {
21166                        mProcessStats.writeStateAsyncLocked();
21167                    }
21168                }
21169            });
21170        }
21171
21172        if (DEBUG_OOM_ADJ) {
21173            final long duration = SystemClock.uptimeMillis() - now;
21174            if (false) {
21175                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21176                        new RuntimeException("here").fillInStackTrace());
21177            } else {
21178                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21179            }
21180        }
21181    }
21182
21183    final void idleUids() {
21184        synchronized (this) {
21185            final long nowElapsed = SystemClock.elapsedRealtime();
21186            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21187            long nextTime = 0;
21188            for (int i=mActiveUids.size()-1; i>=0; i--) {
21189                final UidRecord uidRec = mActiveUids.valueAt(i);
21190                final long bgTime = uidRec.lastBackgroundTime;
21191                if (bgTime > 0 && !uidRec.idle) {
21192                    if (bgTime <= maxBgTime) {
21193                        uidRec.idle = true;
21194                        doStopUidLocked(uidRec.uid, uidRec);
21195                    } else {
21196                        if (nextTime == 0 || nextTime > bgTime) {
21197                            nextTime = bgTime;
21198                        }
21199                    }
21200                }
21201            }
21202            if (nextTime > 0) {
21203                mHandler.removeMessages(IDLE_UIDS_MSG);
21204                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21205                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21206            }
21207        }
21208    }
21209
21210    final void runInBackgroundDisabled(int uid) {
21211        synchronized (this) {
21212            UidRecord uidRec = mActiveUids.get(uid);
21213            if (uidRec != null) {
21214                // This uid is actually running...  should it be considered background now?
21215                if (uidRec.idle) {
21216                    doStopUidLocked(uidRec.uid, uidRec);
21217                }
21218            } else {
21219                // This uid isn't actually running...  still send a report about it being "stopped".
21220                doStopUidLocked(uid, null);
21221            }
21222        }
21223    }
21224
21225    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21226        mServices.stopInBackgroundLocked(uid);
21227        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21228    }
21229
21230    final void trimApplications() {
21231        synchronized (this) {
21232            int i;
21233
21234            // First remove any unused application processes whose package
21235            // has been removed.
21236            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21237                final ProcessRecord app = mRemovedProcesses.get(i);
21238                if (app.activities.size() == 0
21239                        && app.curReceiver == null && app.services.size() == 0) {
21240                    Slog.i(
21241                        TAG, "Exiting empty application process "
21242                        + app.toShortString() + " ("
21243                        + (app.thread != null ? app.thread.asBinder() : null)
21244                        + ")\n");
21245                    if (app.pid > 0 && app.pid != MY_PID) {
21246                        app.kill("empty", false);
21247                    } else {
21248                        try {
21249                            app.thread.scheduleExit();
21250                        } catch (Exception e) {
21251                            // Ignore exceptions.
21252                        }
21253                    }
21254                    cleanUpApplicationRecordLocked(app, false, true, -1);
21255                    mRemovedProcesses.remove(i);
21256
21257                    if (app.persistent) {
21258                        addAppLocked(app.info, false, null /* ABI override */);
21259                    }
21260                }
21261            }
21262
21263            // Now update the oom adj for all processes.
21264            updateOomAdjLocked();
21265        }
21266    }
21267
21268    /** This method sends the specified signal to each of the persistent apps */
21269    public void signalPersistentProcesses(int sig) throws RemoteException {
21270        if (sig != Process.SIGNAL_USR1) {
21271            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21272        }
21273
21274        synchronized (this) {
21275            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21276                    != PackageManager.PERMISSION_GRANTED) {
21277                throw new SecurityException("Requires permission "
21278                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21279            }
21280
21281            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21282                ProcessRecord r = mLruProcesses.get(i);
21283                if (r.thread != null && r.persistent) {
21284                    Process.sendSignal(r.pid, sig);
21285                }
21286            }
21287        }
21288    }
21289
21290    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21291        if (proc == null || proc == mProfileProc) {
21292            proc = mProfileProc;
21293            profileType = mProfileType;
21294            clearProfilerLocked();
21295        }
21296        if (proc == null) {
21297            return;
21298        }
21299        try {
21300            proc.thread.profilerControl(false, null, profileType);
21301        } catch (RemoteException e) {
21302            throw new IllegalStateException("Process disappeared");
21303        }
21304    }
21305
21306    private void clearProfilerLocked() {
21307        if (mProfileFd != null) {
21308            try {
21309                mProfileFd.close();
21310            } catch (IOException e) {
21311            }
21312        }
21313        mProfileApp = null;
21314        mProfileProc = null;
21315        mProfileFile = null;
21316        mProfileType = 0;
21317        mAutoStopProfiler = false;
21318        mSamplingInterval = 0;
21319    }
21320
21321    public boolean profileControl(String process, int userId, boolean start,
21322            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21323
21324        try {
21325            synchronized (this) {
21326                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21327                // its own permission.
21328                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21329                        != PackageManager.PERMISSION_GRANTED) {
21330                    throw new SecurityException("Requires permission "
21331                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21332                }
21333
21334                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21335                    throw new IllegalArgumentException("null profile info or fd");
21336                }
21337
21338                ProcessRecord proc = null;
21339                if (process != null) {
21340                    proc = findProcessLocked(process, userId, "profileControl");
21341                }
21342
21343                if (start && (proc == null || proc.thread == null)) {
21344                    throw new IllegalArgumentException("Unknown process: " + process);
21345                }
21346
21347                if (start) {
21348                    stopProfilerLocked(null, 0);
21349                    setProfileApp(proc.info, proc.processName, profilerInfo);
21350                    mProfileProc = proc;
21351                    mProfileType = profileType;
21352                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21353                    try {
21354                        fd = fd.dup();
21355                    } catch (IOException e) {
21356                        fd = null;
21357                    }
21358                    profilerInfo.profileFd = fd;
21359                    proc.thread.profilerControl(start, profilerInfo, profileType);
21360                    fd = null;
21361                    mProfileFd = null;
21362                } else {
21363                    stopProfilerLocked(proc, profileType);
21364                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21365                        try {
21366                            profilerInfo.profileFd.close();
21367                        } catch (IOException e) {
21368                        }
21369                    }
21370                }
21371
21372                return true;
21373            }
21374        } catch (RemoteException e) {
21375            throw new IllegalStateException("Process disappeared");
21376        } finally {
21377            if (profilerInfo != null && profilerInfo.profileFd != null) {
21378                try {
21379                    profilerInfo.profileFd.close();
21380                } catch (IOException e) {
21381                }
21382            }
21383        }
21384    }
21385
21386    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21387        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21388                userId, true, ALLOW_FULL_ONLY, callName, null);
21389        ProcessRecord proc = null;
21390        try {
21391            int pid = Integer.parseInt(process);
21392            synchronized (mPidsSelfLocked) {
21393                proc = mPidsSelfLocked.get(pid);
21394            }
21395        } catch (NumberFormatException e) {
21396        }
21397
21398        if (proc == null) {
21399            ArrayMap<String, SparseArray<ProcessRecord>> all
21400                    = mProcessNames.getMap();
21401            SparseArray<ProcessRecord> procs = all.get(process);
21402            if (procs != null && procs.size() > 0) {
21403                proc = procs.valueAt(0);
21404                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21405                    for (int i=1; i<procs.size(); i++) {
21406                        ProcessRecord thisProc = procs.valueAt(i);
21407                        if (thisProc.userId == userId) {
21408                            proc = thisProc;
21409                            break;
21410                        }
21411                    }
21412                }
21413            }
21414        }
21415
21416        return proc;
21417    }
21418
21419    public boolean dumpHeap(String process, int userId, boolean managed,
21420            String path, ParcelFileDescriptor fd) throws RemoteException {
21421
21422        try {
21423            synchronized (this) {
21424                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21425                // its own permission (same as profileControl).
21426                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21427                        != PackageManager.PERMISSION_GRANTED) {
21428                    throw new SecurityException("Requires permission "
21429                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21430                }
21431
21432                if (fd == null) {
21433                    throw new IllegalArgumentException("null fd");
21434                }
21435
21436                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21437                if (proc == null || proc.thread == null) {
21438                    throw new IllegalArgumentException("Unknown process: " + process);
21439                }
21440
21441                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21442                if (!isDebuggable) {
21443                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21444                        throw new SecurityException("Process not debuggable: " + proc);
21445                    }
21446                }
21447
21448                proc.thread.dumpHeap(managed, path, fd);
21449                fd = null;
21450                return true;
21451            }
21452        } catch (RemoteException e) {
21453            throw new IllegalStateException("Process disappeared");
21454        } finally {
21455            if (fd != null) {
21456                try {
21457                    fd.close();
21458                } catch (IOException e) {
21459                }
21460            }
21461        }
21462    }
21463
21464    @Override
21465    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21466            String reportPackage) {
21467        if (processName != null) {
21468            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21469                    "setDumpHeapDebugLimit()");
21470        } else {
21471            synchronized (mPidsSelfLocked) {
21472                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21473                if (proc == null) {
21474                    throw new SecurityException("No process found for calling pid "
21475                            + Binder.getCallingPid());
21476                }
21477                if (!Build.IS_DEBUGGABLE
21478                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21479                    throw new SecurityException("Not running a debuggable build");
21480                }
21481                processName = proc.processName;
21482                uid = proc.uid;
21483                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21484                    throw new SecurityException("Package " + reportPackage + " is not running in "
21485                            + proc);
21486                }
21487            }
21488        }
21489        synchronized (this) {
21490            if (maxMemSize > 0) {
21491                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21492            } else {
21493                if (uid != 0) {
21494                    mMemWatchProcesses.remove(processName, uid);
21495                } else {
21496                    mMemWatchProcesses.getMap().remove(processName);
21497                }
21498            }
21499        }
21500    }
21501
21502    @Override
21503    public void dumpHeapFinished(String path) {
21504        synchronized (this) {
21505            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21506                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21507                        + " does not match last pid " + mMemWatchDumpPid);
21508                return;
21509            }
21510            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21511                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21512                        + " does not match last path " + mMemWatchDumpFile);
21513                return;
21514            }
21515            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21516            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21517        }
21518    }
21519
21520    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21521    public void monitor() {
21522        synchronized (this) { }
21523    }
21524
21525    void onCoreSettingsChange(Bundle settings) {
21526        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21527            ProcessRecord processRecord = mLruProcesses.get(i);
21528            try {
21529                if (processRecord.thread != null) {
21530                    processRecord.thread.setCoreSettings(settings);
21531                }
21532            } catch (RemoteException re) {
21533                /* ignore */
21534            }
21535        }
21536    }
21537
21538    // Multi-user methods
21539
21540    /**
21541     * Start user, if its not already running, but don't bring it to foreground.
21542     */
21543    @Override
21544    public boolean startUserInBackground(final int userId) {
21545        return mUserController.startUser(userId, /* foreground */ false);
21546    }
21547
21548    @Override
21549    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21550        return mUserController.unlockUser(userId, token, secret, listener);
21551    }
21552
21553    @Override
21554    public boolean switchUser(final int targetUserId) {
21555        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21556        UserInfo currentUserInfo;
21557        UserInfo targetUserInfo;
21558        synchronized (this) {
21559            int currentUserId = mUserController.getCurrentUserIdLocked();
21560            currentUserInfo = mUserController.getUserInfo(currentUserId);
21561            targetUserInfo = mUserController.getUserInfo(targetUserId);
21562            if (targetUserInfo == null) {
21563                Slog.w(TAG, "No user info for user #" + targetUserId);
21564                return false;
21565            }
21566            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21567                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21568                        + " when device is in demo mode");
21569                return false;
21570            }
21571            if (!targetUserInfo.supportsSwitchTo()) {
21572                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21573                return false;
21574            }
21575            if (targetUserInfo.isManagedProfile()) {
21576                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21577                return false;
21578            }
21579            mUserController.setTargetUserIdLocked(targetUserId);
21580        }
21581        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21582        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21583        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21584        return true;
21585    }
21586
21587    void scheduleStartProfilesLocked() {
21588        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21589            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21590                    DateUtils.SECOND_IN_MILLIS);
21591        }
21592    }
21593
21594    @Override
21595    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21596        return mUserController.stopUser(userId, force, callback);
21597    }
21598
21599    @Override
21600    public UserInfo getCurrentUser() {
21601        return mUserController.getCurrentUser();
21602    }
21603
21604    @Override
21605    public boolean isUserRunning(int userId, int flags) {
21606        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21607                && checkCallingPermission(INTERACT_ACROSS_USERS)
21608                    != PackageManager.PERMISSION_GRANTED) {
21609            String msg = "Permission Denial: isUserRunning() from pid="
21610                    + Binder.getCallingPid()
21611                    + ", uid=" + Binder.getCallingUid()
21612                    + " requires " + INTERACT_ACROSS_USERS;
21613            Slog.w(TAG, msg);
21614            throw new SecurityException(msg);
21615        }
21616        synchronized (this) {
21617            return mUserController.isUserRunningLocked(userId, flags);
21618        }
21619    }
21620
21621    @Override
21622    public int[] getRunningUserIds() {
21623        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21624                != PackageManager.PERMISSION_GRANTED) {
21625            String msg = "Permission Denial: isUserRunning() from pid="
21626                    + Binder.getCallingPid()
21627                    + ", uid=" + Binder.getCallingUid()
21628                    + " requires " + INTERACT_ACROSS_USERS;
21629            Slog.w(TAG, msg);
21630            throw new SecurityException(msg);
21631        }
21632        synchronized (this) {
21633            return mUserController.getStartedUserArrayLocked();
21634        }
21635    }
21636
21637    @Override
21638    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21639        mUserController.registerUserSwitchObserver(observer, name);
21640    }
21641
21642    @Override
21643    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21644        mUserController.unregisterUserSwitchObserver(observer);
21645    }
21646
21647    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21648        if (info == null) return null;
21649        ApplicationInfo newInfo = new ApplicationInfo(info);
21650        newInfo.initForUser(userId);
21651        return newInfo;
21652    }
21653
21654    public boolean isUserStopped(int userId) {
21655        synchronized (this) {
21656            return mUserController.getStartedUserStateLocked(userId) == null;
21657        }
21658    }
21659
21660    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21661        if (aInfo == null
21662                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21663            return aInfo;
21664        }
21665
21666        ActivityInfo info = new ActivityInfo(aInfo);
21667        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21668        return info;
21669    }
21670
21671    private boolean processSanityChecksLocked(ProcessRecord process) {
21672        if (process == null || process.thread == null) {
21673            return false;
21674        }
21675
21676        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21677        if (!isDebuggable) {
21678            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21679                return false;
21680            }
21681        }
21682
21683        return true;
21684    }
21685
21686    public boolean startBinderTracking() throws RemoteException {
21687        synchronized (this) {
21688            mBinderTransactionTrackingEnabled = true;
21689            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21690            // permission (same as profileControl).
21691            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21692                    != PackageManager.PERMISSION_GRANTED) {
21693                throw new SecurityException("Requires permission "
21694                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21695            }
21696
21697            for (int i = 0; i < mLruProcesses.size(); i++) {
21698                ProcessRecord process = mLruProcesses.get(i);
21699                if (!processSanityChecksLocked(process)) {
21700                    continue;
21701                }
21702                try {
21703                    process.thread.startBinderTracking();
21704                } catch (RemoteException e) {
21705                    Log.v(TAG, "Process disappared");
21706                }
21707            }
21708            return true;
21709        }
21710    }
21711
21712    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21713        try {
21714            synchronized (this) {
21715                mBinderTransactionTrackingEnabled = false;
21716                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21717                // permission (same as profileControl).
21718                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21719                        != PackageManager.PERMISSION_GRANTED) {
21720                    throw new SecurityException("Requires permission "
21721                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21722                }
21723
21724                if (fd == null) {
21725                    throw new IllegalArgumentException("null fd");
21726                }
21727
21728                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21729                pw.println("Binder transaction traces for all processes.\n");
21730                for (ProcessRecord process : mLruProcesses) {
21731                    if (!processSanityChecksLocked(process)) {
21732                        continue;
21733                    }
21734
21735                    pw.println("Traces for process: " + process.processName);
21736                    pw.flush();
21737                    try {
21738                        TransferPipe tp = new TransferPipe();
21739                        try {
21740                            process.thread.stopBinderTrackingAndDump(
21741                                    tp.getWriteFd().getFileDescriptor());
21742                            tp.go(fd.getFileDescriptor());
21743                        } finally {
21744                            tp.kill();
21745                        }
21746                    } catch (IOException e) {
21747                        pw.println("Failure while dumping IPC traces from " + process +
21748                                ".  Exception: " + e);
21749                        pw.flush();
21750                    } catch (RemoteException e) {
21751                        pw.println("Got a RemoteException while dumping IPC traces from " +
21752                                process + ".  Exception: " + e);
21753                        pw.flush();
21754                    }
21755                }
21756                fd = null;
21757                return true;
21758            }
21759        } finally {
21760            if (fd != null) {
21761                try {
21762                    fd.close();
21763                } catch (IOException e) {
21764                }
21765            }
21766        }
21767    }
21768
21769    private final class LocalService extends ActivityManagerInternal {
21770        @Override
21771        public void onWakefulnessChanged(int wakefulness) {
21772            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21773        }
21774
21775        @Override
21776        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21777                String processName, String abiOverride, int uid, Runnable crashHandler) {
21778            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21779                    processName, abiOverride, uid, crashHandler);
21780        }
21781
21782        @Override
21783        public SleepToken acquireSleepToken(String tag) {
21784            Preconditions.checkNotNull(tag);
21785
21786            ComponentName requestedVrService = null;
21787            ComponentName callingVrActivity = null;
21788            int userId = -1;
21789            synchronized (ActivityManagerService.this) {
21790                if (mFocusedActivity != null) {
21791                    requestedVrService = mFocusedActivity.requestedVrComponent;
21792                    callingVrActivity = mFocusedActivity.info.getComponentName();
21793                    userId = mFocusedActivity.userId;
21794                }
21795            }
21796
21797            if (requestedVrService != null) {
21798                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21799            }
21800
21801            synchronized (ActivityManagerService.this) {
21802                SleepTokenImpl token = new SleepTokenImpl(tag);
21803                mSleepTokens.add(token);
21804                updateSleepIfNeededLocked();
21805                return token;
21806            }
21807        }
21808
21809        @Override
21810        public ComponentName getHomeActivityForUser(int userId) {
21811            synchronized (ActivityManagerService.this) {
21812                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21813                return homeActivity == null ? null : homeActivity.realActivity;
21814            }
21815        }
21816
21817        @Override
21818        public void onUserRemoved(int userId) {
21819            synchronized (ActivityManagerService.this) {
21820                ActivityManagerService.this.onUserStoppedLocked(userId);
21821            }
21822        }
21823
21824        @Override
21825        public void onLocalVoiceInteractionStarted(IBinder activity,
21826                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21827            synchronized (ActivityManagerService.this) {
21828                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21829                        voiceSession, voiceInteractor);
21830            }
21831        }
21832
21833        @Override
21834        public void notifyStartingWindowDrawn() {
21835            synchronized (ActivityManagerService.this) {
21836                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21837            }
21838        }
21839
21840        @Override
21841        public void notifyAppTransitionStarting(int reason) {
21842            synchronized (ActivityManagerService.this) {
21843                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21844            }
21845        }
21846
21847        @Override
21848        public void notifyAppTransitionFinished() {
21849            synchronized (ActivityManagerService.this) {
21850                mStackSupervisor.notifyAppTransitionDone();
21851            }
21852        }
21853
21854        @Override
21855        public void notifyAppTransitionCancelled() {
21856            synchronized (ActivityManagerService.this) {
21857                mStackSupervisor.notifyAppTransitionDone();
21858            }
21859        }
21860
21861        @Override
21862        public List<IBinder> getTopVisibleActivities() {
21863            synchronized (ActivityManagerService.this) {
21864                return mStackSupervisor.getTopVisibleActivities();
21865            }
21866        }
21867
21868        @Override
21869        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21870            synchronized (ActivityManagerService.this) {
21871                mStackSupervisor.setDockedStackMinimized(minimized);
21872            }
21873        }
21874
21875        @Override
21876        public void killForegroundAppsForUser(int userHandle) {
21877            synchronized (ActivityManagerService.this) {
21878                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21879                final int NP = mProcessNames.getMap().size();
21880                for (int ip = 0; ip < NP; ip++) {
21881                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21882                    final int NA = apps.size();
21883                    for (int ia = 0; ia < NA; ia++) {
21884                        final ProcessRecord app = apps.valueAt(ia);
21885                        if (app.persistent) {
21886                            // We don't kill persistent processes.
21887                            continue;
21888                        }
21889                        if (app.removed) {
21890                            procs.add(app);
21891                        } else if (app.userId == userHandle && app.foregroundActivities) {
21892                            app.removed = true;
21893                            procs.add(app);
21894                        }
21895                    }
21896                }
21897
21898                final int N = procs.size();
21899                for (int i = 0; i < N; i++) {
21900                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21901                }
21902            }
21903        }
21904
21905        @Override
21906        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21907            if (!(target instanceof PendingIntentRecord)) {
21908                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21909                return;
21910            }
21911            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21912        }
21913
21914        @Override
21915        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
21916                int userId) {
21917            Preconditions.checkNotNull(values, "Configuration must not be null");
21918            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
21919            synchronized (ActivityManagerService.this) {
21920                updateConfigurationLocked(values, null, false, true, userId,
21921                        false /* deferResume */);
21922            }
21923        }
21924
21925        @Override
21926        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
21927                Bundle bOptions) {
21928            Preconditions.checkNotNull(intents, "intents");
21929            final String[] resolvedTypes = new String[intents.length];
21930            for (int i = 0; i < intents.length; i++) {
21931                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
21932            }
21933
21934            // UID of the package on user userId.
21935            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
21936            // packageUid may not be initialized.
21937            int packageUid = 0;
21938            try {
21939                packageUid = AppGlobals.getPackageManager().getPackageUid(
21940                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
21941            } catch (RemoteException e) {
21942                // Shouldn't happen.
21943            }
21944
21945            synchronized (ActivityManagerService.this) {
21946                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
21947                        /*resultTo*/ null, bOptions, userId);
21948            }
21949        }
21950
21951        @Override
21952        public int getUidProcessState(int uid) {
21953            return getUidState(uid);
21954        }
21955    }
21956
21957    private final class SleepTokenImpl extends SleepToken {
21958        private final String mTag;
21959        private final long mAcquireTime;
21960
21961        public SleepTokenImpl(String tag) {
21962            mTag = tag;
21963            mAcquireTime = SystemClock.uptimeMillis();
21964        }
21965
21966        @Override
21967        public void release() {
21968            synchronized (ActivityManagerService.this) {
21969                if (mSleepTokens.remove(this)) {
21970                    updateSleepIfNeededLocked();
21971                }
21972            }
21973        }
21974
21975        @Override
21976        public String toString() {
21977            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21978        }
21979    }
21980
21981    /**
21982     * An implementation of IAppTask, that allows an app to manage its own tasks via
21983     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21984     * only the process that calls getAppTasks() can call the AppTask methods.
21985     */
21986    class AppTaskImpl extends IAppTask.Stub {
21987        private int mTaskId;
21988        private int mCallingUid;
21989
21990        public AppTaskImpl(int taskId, int callingUid) {
21991            mTaskId = taskId;
21992            mCallingUid = callingUid;
21993        }
21994
21995        private void checkCaller() {
21996            if (mCallingUid != Binder.getCallingUid()) {
21997                throw new SecurityException("Caller " + mCallingUid
21998                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21999            }
22000        }
22001
22002        @Override
22003        public void finishAndRemoveTask() {
22004            checkCaller();
22005
22006            synchronized (ActivityManagerService.this) {
22007                long origId = Binder.clearCallingIdentity();
22008                try {
22009                    // We remove the task from recents to preserve backwards
22010                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22011                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22012                    }
22013                } finally {
22014                    Binder.restoreCallingIdentity(origId);
22015                }
22016            }
22017        }
22018
22019        @Override
22020        public ActivityManager.RecentTaskInfo getTaskInfo() {
22021            checkCaller();
22022
22023            synchronized (ActivityManagerService.this) {
22024                long origId = Binder.clearCallingIdentity();
22025                try {
22026                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22027                    if (tr == null) {
22028                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22029                    }
22030                    return createRecentTaskInfoFromTaskRecord(tr);
22031                } finally {
22032                    Binder.restoreCallingIdentity(origId);
22033                }
22034            }
22035        }
22036
22037        @Override
22038        public void moveToFront() {
22039            checkCaller();
22040            // Will bring task to front if it already has a root activity.
22041            final long origId = Binder.clearCallingIdentity();
22042            try {
22043                synchronized (this) {
22044                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22045                }
22046            } finally {
22047                Binder.restoreCallingIdentity(origId);
22048            }
22049        }
22050
22051        @Override
22052        public int startActivity(IBinder whoThread, String callingPackage,
22053                Intent intent, String resolvedType, Bundle bOptions) {
22054            checkCaller();
22055
22056            int callingUser = UserHandle.getCallingUserId();
22057            TaskRecord tr;
22058            IApplicationThread appThread;
22059            synchronized (ActivityManagerService.this) {
22060                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22061                if (tr == null) {
22062                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22063                }
22064                appThread = ApplicationThreadNative.asInterface(whoThread);
22065                if (appThread == null) {
22066                    throw new IllegalArgumentException("Bad app thread " + appThread);
22067                }
22068            }
22069            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22070                    resolvedType, null, null, null, null, 0, 0, null, null,
22071                    null, bOptions, false, callingUser, null, tr);
22072        }
22073
22074        @Override
22075        public void setExcludeFromRecents(boolean exclude) {
22076            checkCaller();
22077
22078            synchronized (ActivityManagerService.this) {
22079                long origId = Binder.clearCallingIdentity();
22080                try {
22081                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22082                    if (tr == null) {
22083                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22084                    }
22085                    Intent intent = tr.getBaseIntent();
22086                    if (exclude) {
22087                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22088                    } else {
22089                        intent.setFlags(intent.getFlags()
22090                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22091                    }
22092                } finally {
22093                    Binder.restoreCallingIdentity(origId);
22094                }
22095            }
22096        }
22097    }
22098
22099    /**
22100     * Kill processes for the user with id userId and that depend on the package named packageName
22101     */
22102    @Override
22103    public void killPackageDependents(String packageName, int userId) {
22104        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22105        if (packageName == null) {
22106            throw new NullPointerException(
22107                    "Cannot kill the dependents of a package without its name.");
22108        }
22109
22110        long callingId = Binder.clearCallingIdentity();
22111        IPackageManager pm = AppGlobals.getPackageManager();
22112        int pkgUid = -1;
22113        try {
22114            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22115        } catch (RemoteException e) {
22116        }
22117        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22118            throw new IllegalArgumentException(
22119                    "Cannot kill dependents of non-existing package " + packageName);
22120        }
22121        try {
22122            synchronized(this) {
22123                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22124                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22125                        "dep: " + packageName);
22126            }
22127        } finally {
22128            Binder.restoreCallingIdentity(callingId);
22129        }
22130    }
22131}
22132