ActivityManagerService.java revision ad2e4bf9f36cf612db6c397feca8effb125ee541
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.google.android.collect.Lists;
20import com.google.android.collect.Maps;
21import com.android.internal.R;
22import com.android.internal.annotations.GuardedBy;
23import com.android.internal.app.AssistUtils;
24import com.android.internal.app.DumpHeapActivity;
25import com.android.internal.app.IAppOpsCallback;
26import com.android.internal.app.IAppOpsService;
27import com.android.internal.app.IVoiceInteractor;
28import com.android.internal.app.ProcessMap;
29import com.android.internal.app.SystemUserHomeActivity;
30import com.android.internal.app.procstats.ProcessStats;
31import com.android.internal.os.BackgroundThread;
32import com.android.internal.os.BatteryStatsImpl;
33import com.android.internal.os.IResultReceiver;
34import com.android.internal.os.ProcessCpuTracker;
35import com.android.internal.os.TransferPipe;
36import com.android.internal.os.Zygote;
37import com.android.internal.os.InstallerConnection.InstallerException;
38import com.android.internal.util.ArrayUtils;
39import com.android.internal.util.FastPrintWriter;
40import com.android.internal.util.FastXmlSerializer;
41import com.android.internal.util.MemInfoReader;
42import com.android.internal.util.Preconditions;
43import com.android.internal.util.ProgressReporter;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.KeyguardManager;
101import android.app.Notification;
102import android.app.NotificationManager;
103import android.app.PendingIntent;
104import android.app.ProfilerInfo;
105import android.app.admin.DevicePolicyManager;
106import android.app.admin.DevicePolicyManagerInternal;
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.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.PersistableBundle;
176import android.os.PowerManager;
177import android.os.PowerManagerInternal;
178import android.os.Process;
179import android.os.RemoteCallbackList;
180import android.os.RemoteException;
181import android.os.ResultReceiver;
182import android.os.ServiceManager;
183import android.os.StrictMode;
184import android.os.SystemClock;
185import android.os.SystemProperties;
186import android.os.Trace;
187import android.os.TransactionTooLargeException;
188import android.os.UpdateLock;
189import android.os.UserHandle;
190import android.os.UserManager;
191import android.os.WorkSource;
192import android.os.storage.IMountService;
193import android.os.storage.MountServiceInternal;
194import android.os.storage.StorageManager;
195import android.provider.Settings;
196import android.service.voice.IVoiceInteractionSession;
197import android.service.voice.VoiceInteractionManagerInternal;
198import android.service.voice.VoiceInteractionSession;
199import android.text.format.DateUtils;
200import android.text.format.Time;
201import android.util.ArrayMap;
202import android.util.ArraySet;
203import android.util.AtomicFile;
204import android.util.DebugUtils;
205import android.util.EventLog;
206import android.util.LocaleList;
207import android.util.Log;
208import android.util.Pair;
209import android.util.PrintWriterPrinter;
210import android.util.Slog;
211import android.util.SparseArray;
212import android.util.TimeUtils;
213import android.util.Xml;
214import android.view.Display;
215import android.view.Gravity;
216import android.view.LayoutInflater;
217import android.view.View;
218import android.view.WindowManager;
219
220import java.io.File;
221import java.io.FileDescriptor;
222import java.io.FileInputStream;
223import java.io.FileNotFoundException;
224import java.io.FileOutputStream;
225import java.io.IOException;
226import java.io.InputStreamReader;
227import java.io.PrintWriter;
228import java.io.StringWriter;
229import java.lang.ref.WeakReference;
230import java.nio.charset.StandardCharsets;
231import java.util.ArrayList;
232import java.util.Arrays;
233import java.util.Collections;
234import java.util.Comparator;
235import java.util.HashMap;
236import java.util.HashSet;
237import java.util.Iterator;
238import java.util.List;
239import java.util.Locale;
240import java.util.Map;
241import java.util.Set;
242import java.util.concurrent.atomic.AtomicBoolean;
243import java.util.concurrent.atomic.AtomicLong;
244
245import dalvik.system.VMRuntime;
246
247import libcore.io.IoUtils;
248import libcore.util.EmptyArray;
249
250import static android.Manifest.permission.INTERACT_ACROSS_USERS;
251import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
252import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
253import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
254import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
255import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
256import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
257import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
258import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
259import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
260import static android.app.ActivityManager.StackId.HOME_STACK_ID;
261import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
262import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
263import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
264import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
265import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
266import static android.content.pm.PackageManager.GET_PROVIDERS;
267import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
268import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
269import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
270import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
271import static android.content.pm.PackageManager.PERMISSION_GRANTED;
272import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
273import static android.provider.Settings.Global.DEBUG_APP;
274import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
275import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
276import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
277import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
278import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
279import static android.provider.Settings.System.FONT_SCALE;
280import static com.android.internal.util.XmlUtils.readBooleanAttribute;
281import static com.android.internal.util.XmlUtils.readIntAttribute;
282import static com.android.internal.util.XmlUtils.readLongAttribute;
283import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
284import static com.android.internal.util.XmlUtils.writeIntAttribute;
285import static com.android.internal.util.XmlUtils.writeLongAttribute;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
342import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
343import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
344import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
345import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
346import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
347import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
348import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
349import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
350import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
351import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
352import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
353import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
354import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
355import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
356import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
357import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
358import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
359import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
360import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
361import static org.xmlpull.v1.XmlPullParser.START_TAG;
362
363public final class ActivityManagerService extends ActivityManagerNative
364        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
365
366    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
367    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
368    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
369    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
370    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
371    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
372    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
373    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
374    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
375    private static final String TAG_LRU = TAG + POSTFIX_LRU;
376    private static final String TAG_MU = TAG + POSTFIX_MU;
377    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
378    private static final String TAG_POWER = TAG + POSTFIX_POWER;
379    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
380    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
381    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
382    private static final String TAG_PSS = TAG + POSTFIX_PSS;
383    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
384    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
385    private static final String TAG_STACK = TAG + POSTFIX_STACK;
386    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
387    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
388    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
389    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
390    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
391
392    /** Control over CPU and battery monitoring */
393    // write battery stats every 30 minutes.
394    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
395    static final boolean MONITOR_CPU_USAGE = true;
396    // don't sample cpu less than every 5 seconds.
397    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
398    // wait possibly forever for next cpu sample.
399    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
400    static final boolean MONITOR_THREAD_CPU_USAGE = false;
401
402    // The flags that are set for all calls we make to the package manager.
403    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
404
405    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
406
407    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
408
409    // Amount of time after a call to stopAppSwitches() during which we will
410    // prevent further untrusted switches from happening.
411    static final long APP_SWITCH_DELAY_TIME = 5*1000;
412
413    // How long we wait for a launched process to attach to the activity manager
414    // before we decide it's never going to come up for real.
415    static final int PROC_START_TIMEOUT = 10*1000;
416    // How long we wait for an attached process to publish its content providers
417    // before we decide it must be hung.
418    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
419
420    // How long we will retain processes hosting content providers in the "last activity"
421    // state before allowing them to drop down to the regular cached LRU list.  This is
422    // to avoid thrashing of provider processes under low memory situations.
423    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
424
425    // How long we wait for a launched process to attach to the activity manager
426    // before we decide it's never going to come up for real, when the process was
427    // started with a wrapper for instrumentation (such as Valgrind) because it
428    // could take much longer than usual.
429    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
430
431    // How long to wait after going idle before forcing apps to GC.
432    static final int GC_TIMEOUT = 5*1000;
433
434    // The minimum amount of time between successive GC requests for a process.
435    static final int GC_MIN_INTERVAL = 60*1000;
436
437    // The minimum amount of time between successive PSS requests for a process.
438    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
439
440    // The minimum amount of time between successive PSS requests for a process
441    // when the request is due to the memory state being lowered.
442    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
443
444    // The rate at which we check for apps using excessive power -- 15 mins.
445    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
446
447    // The minimum sample duration we will allow before deciding we have
448    // enough data on wake locks to start killing things.
449    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
450
451    // The minimum sample duration we will allow before deciding we have
452    // enough data on CPU usage to start killing things.
453    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
454
455    // How long we allow a receiver to run before giving up on it.
456    static final int BROADCAST_FG_TIMEOUT = 10*1000;
457    static final int BROADCAST_BG_TIMEOUT = 60*1000;
458
459    // How long we wait until we timeout on key dispatching.
460    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
461
462    // How long we wait until we timeout on key dispatching during instrumentation.
463    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
464
465    // This is the amount of time an app needs to be running a foreground service before
466    // we will consider it to be doing interaction for usage stats.
467    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
468
469    // Maximum amount of time we will allow to elapse before re-reporting usage stats
470    // interaction with foreground processes.
471    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
472
473    // This is the amount of time we allow an app to settle after it goes into the background,
474    // before we start restricting what it can do.
475    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
476
477    // How long to wait in getAssistContextExtras for the activity and foreground services
478    // to respond with the result.
479    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
480
481    // How long top wait when going through the modern assist (which doesn't need to block
482    // on getting this result before starting to launch its UI).
483    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
484
485    // Maximum number of persisted Uri grants a package is allowed
486    static final int MAX_PERSISTED_URI_GRANTS = 128;
487
488    static final int MY_PID = Process.myPid();
489
490    static final String[] EMPTY_STRING_ARRAY = new String[0];
491
492    // How many bytes to write into the dropbox log before truncating
493    static final int DROPBOX_MAX_SIZE = 256 * 1024;
494
495    // Access modes for handleIncomingUser.
496    static final int ALLOW_NON_FULL = 0;
497    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
498    static final int ALLOW_FULL_ONLY = 2;
499
500    // Delay in notifying task stack change listeners (in millis)
501    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
502
503    // Necessary ApplicationInfo flags to mark an app as persistent
504    private static final int PERSISTENT_MASK =
505            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
506
507    // Intent sent when remote bugreport collection has been completed
508    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
509            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
510
511    // Delay to disable app launch boost
512    static final int APP_BOOST_MESSAGE_DELAY = 3000;
513    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
514    static final int APP_BOOST_TIMEOUT = 2500;
515
516    // Used to indicate that a task is removed it should also be removed from recents.
517    private static final boolean REMOVE_FROM_RECENTS = true;
518    // Used to indicate that an app transition should be animated.
519    static final boolean ANIMATE = true;
520
521    // Determines whether to take full screen screenshots
522    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
523    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
524
525    private static native int nativeMigrateToBoost();
526    private static native int nativeMigrateFromBoost();
527    private boolean mIsBoosted = false;
528    private long mBoostStartTime = 0;
529
530    /** All system services */
531    SystemServiceManager mSystemServiceManager;
532
533    private Installer mInstaller;
534
535    /** Run all ActivityStacks through this */
536    final ActivityStackSupervisor mStackSupervisor;
537
538    final ActivityStarter mActivityStarter;
539
540    /** Task stack change listeners. */
541    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
542            new RemoteCallbackList<ITaskStackListener>();
543
544    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
545
546    public IntentFirewall mIntentFirewall;
547
548    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
549    // default actuion automatically.  Important for devices without direct input
550    // devices.
551    private boolean mShowDialogs = true;
552    private boolean mInVrMode = false;
553
554    BroadcastQueue mFgBroadcastQueue;
555    BroadcastQueue mBgBroadcastQueue;
556    // Convenient for easy iteration over the queues. Foreground is first
557    // so that dispatch of foreground broadcasts gets precedence.
558    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
559
560    BroadcastQueue broadcastQueueForIntent(Intent intent) {
561        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
562        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
563                "Broadcast intent " + intent + " on "
564                + (isFg ? "foreground" : "background") + " queue");
565        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
566    }
567
568    /**
569     * Activity we have told the window manager to have key focus.
570     */
571    ActivityRecord mFocusedActivity = null;
572
573    /**
574     * User id of the last activity mFocusedActivity was set to.
575     */
576    private int mLastFocusedUserId;
577
578    /**
579     * If non-null, we are tracking the time the user spends in the currently focused app.
580     */
581    private AppTimeTracker mCurAppTimeTracker;
582
583    /**
584     * List of intents that were used to start the most recent tasks.
585     */
586    final RecentTasks mRecentTasks;
587
588    /**
589     * For addAppTask: cached of the last activity component that was added.
590     */
591    ComponentName mLastAddedTaskComponent;
592
593    /**
594     * For addAppTask: cached of the last activity uid that was added.
595     */
596    int mLastAddedTaskUid;
597
598    /**
599     * For addAppTask: cached of the last ActivityInfo that was added.
600     */
601    ActivityInfo mLastAddedTaskActivity;
602
603    /**
604     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
605     */
606    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
607
608    /**
609     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
610     */
611    String mDeviceOwnerName;
612
613    final UserController mUserController;
614
615    final AppErrors mAppErrors;
616
617    boolean mDoingSetFocusedActivity;
618
619    public boolean canShowErrorDialogs() {
620        return mShowDialogs && !mSleeping && !mShuttingDown;
621    }
622
623    public class PendingAssistExtras extends Binder implements Runnable {
624        public final ActivityRecord activity;
625        public final Bundle extras;
626        public final Intent intent;
627        public final String hint;
628        public final IResultReceiver receiver;
629        public final int userHandle;
630        public boolean haveResult = false;
631        public Bundle result = null;
632        public AssistStructure structure = null;
633        public AssistContent content = null;
634        public Bundle receiverExtras;
635
636        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
637                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
638            activity = _activity;
639            extras = _extras;
640            intent = _intent;
641            hint = _hint;
642            receiver = _receiver;
643            receiverExtras = _receiverExtras;
644            userHandle = _userHandle;
645        }
646        @Override
647        public void run() {
648            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
649            synchronized (this) {
650                haveResult = true;
651                notifyAll();
652            }
653            pendingAssistExtrasTimedOut(this);
654        }
655    }
656
657    final ArrayList<PendingAssistExtras> mPendingAssistExtras
658            = new ArrayList<PendingAssistExtras>();
659
660    /**
661     * Process management.
662     */
663    final ProcessList mProcessList = new ProcessList();
664
665    /**
666     * All of the applications we currently have running organized by name.
667     * The keys are strings of the application package name (as
668     * returned by the package manager), and the keys are ApplicationRecord
669     * objects.
670     */
671    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
672
673    /**
674     * Tracking long-term execution of processes to look for abuse and other
675     * bad app behavior.
676     */
677    final ProcessStatsService mProcessStats;
678
679    /**
680     * The currently running isolated processes.
681     */
682    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
683
684    /**
685     * Counter for assigning isolated process uids, to avoid frequently reusing the
686     * same ones.
687     */
688    int mNextIsolatedProcessUid = 0;
689
690    /**
691     * The currently running heavy-weight process, if any.
692     */
693    ProcessRecord mHeavyWeightProcess = null;
694
695    /**
696     * All of the processes we currently have running organized by pid.
697     * The keys are the pid running the application.
698     *
699     * <p>NOTE: This object is protected by its own lock, NOT the global
700     * activity manager lock!
701     */
702    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
703
704    /**
705     * All of the processes that have been forced to be foreground.  The key
706     * is the pid of the caller who requested it (we hold a death
707     * link on it).
708     */
709    abstract class ForegroundToken implements IBinder.DeathRecipient {
710        int pid;
711        IBinder token;
712    }
713    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
714
715    /**
716     * List of records for processes that someone had tried to start before the
717     * system was ready.  We don't start them at that point, but ensure they
718     * are started by the time booting is complete.
719     */
720    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
721
722    /**
723     * List of persistent applications that are in the process
724     * of being started.
725     */
726    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
727
728    /**
729     * Processes that are being forcibly torn down.
730     */
731    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
732
733    /**
734     * List of running applications, sorted by recent usage.
735     * The first entry in the list is the least recently used.
736     */
737    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
738
739    /**
740     * Where in mLruProcesses that the processes hosting activities start.
741     */
742    int mLruProcessActivityStart = 0;
743
744    /**
745     * Where in mLruProcesses that the processes hosting services start.
746     * This is after (lower index) than mLruProcessesActivityStart.
747     */
748    int mLruProcessServiceStart = 0;
749
750    /**
751     * List of processes that should gc as soon as things are idle.
752     */
753    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
754
755    /**
756     * Processes we want to collect PSS data from.
757     */
758    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
759
760    private boolean mBinderTransactionTrackingEnabled = false;
761
762    /**
763     * Last time we requested PSS data of all processes.
764     */
765    long mLastFullPssTime = SystemClock.uptimeMillis();
766
767    /**
768     * If set, the next time we collect PSS data we should do a full collection
769     * with data from native processes and the kernel.
770     */
771    boolean mFullPssPending = false;
772
773    /**
774     * This is the process holding what we currently consider to be
775     * the "home" activity.
776     */
777    ProcessRecord mHomeProcess;
778
779    /**
780     * This is the process holding the activity the user last visited that
781     * is in a different process from the one they are currently in.
782     */
783    ProcessRecord mPreviousProcess;
784
785    /**
786     * The time at which the previous process was last visible.
787     */
788    long mPreviousProcessVisibleTime;
789
790    /**
791     * Track all uids that have actively running processes.
792     */
793    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
794
795    /**
796     * This is for verifying the UID report flow.
797     */
798    static final boolean VALIDATE_UID_STATES = true;
799    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
800
801    /**
802     * Packages that the user has asked to have run in screen size
803     * compatibility mode instead of filling the screen.
804     */
805    final CompatModePackages mCompatModePackages;
806
807    /**
808     * Set of IntentSenderRecord objects that are currently active.
809     */
810    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
811            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
812
813    /**
814     * Fingerprints (hashCode()) of stack traces that we've
815     * already logged DropBox entries for.  Guarded by itself.  If
816     * something (rogue user app) forces this over
817     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
818     */
819    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
820    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
821
822    /**
823     * Strict Mode background batched logging state.
824     *
825     * The string buffer is guarded by itself, and its lock is also
826     * used to determine if another batched write is already
827     * in-flight.
828     */
829    private final StringBuilder mStrictModeBuffer = new StringBuilder();
830
831    /**
832     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
833     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
834     */
835    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
836
837    /**
838     * Resolver for broadcast intents to registered receivers.
839     * Holds BroadcastFilter (subclass of IntentFilter).
840     */
841    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
842            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
843        @Override
844        protected boolean allowFilterResult(
845                BroadcastFilter filter, List<BroadcastFilter> dest) {
846            IBinder target = filter.receiverList.receiver.asBinder();
847            for (int i = dest.size() - 1; i >= 0; i--) {
848                if (dest.get(i).receiverList.receiver.asBinder() == target) {
849                    return false;
850                }
851            }
852            return true;
853        }
854
855        @Override
856        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
857            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
858                    || userId == filter.owningUserId) {
859                return super.newResult(filter, match, userId);
860            }
861            return null;
862        }
863
864        @Override
865        protected BroadcastFilter[] newArray(int size) {
866            return new BroadcastFilter[size];
867        }
868
869        @Override
870        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
871            return packageName.equals(filter.packageName);
872        }
873    };
874
875    /**
876     * State of all active sticky broadcasts per user.  Keys are the action of the
877     * sticky Intent, values are an ArrayList of all broadcasted intents with
878     * that action (which should usually be one).  The SparseArray is keyed
879     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
880     * for stickies that are sent to all users.
881     */
882    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
883            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
884
885    final ActiveServices mServices;
886
887    final static class Association {
888        final int mSourceUid;
889        final String mSourceProcess;
890        final int mTargetUid;
891        final ComponentName mTargetComponent;
892        final String mTargetProcess;
893
894        int mCount;
895        long mTime;
896
897        int mNesting;
898        long mStartTime;
899
900        // states of the source process when the bind occurred.
901        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
902        long mLastStateUptime;
903        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
904                - ActivityManager.MIN_PROCESS_STATE+1];
905
906        Association(int sourceUid, String sourceProcess, int targetUid,
907                ComponentName targetComponent, String targetProcess) {
908            mSourceUid = sourceUid;
909            mSourceProcess = sourceProcess;
910            mTargetUid = targetUid;
911            mTargetComponent = targetComponent;
912            mTargetProcess = targetProcess;
913        }
914    }
915
916    /**
917     * When service association tracking is enabled, this is all of the associations we
918     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
919     * -> association data.
920     */
921    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
922            mAssociations = new SparseArray<>();
923    boolean mTrackingAssociations;
924
925    /**
926     * Backup/restore process management
927     */
928    String mBackupAppName = null;
929    BackupRecord mBackupTarget = null;
930
931    final ProviderMap mProviderMap;
932
933    /**
934     * List of content providers who have clients waiting for them.  The
935     * application is currently being launched and the provider will be
936     * removed from this list once it is published.
937     */
938    final ArrayList<ContentProviderRecord> mLaunchingProviders
939            = new ArrayList<ContentProviderRecord>();
940
941    /**
942     * File storing persisted {@link #mGrantedUriPermissions}.
943     */
944    private final AtomicFile mGrantFile;
945
946    /** XML constants used in {@link #mGrantFile} */
947    private static final String TAG_URI_GRANTS = "uri-grants";
948    private static final String TAG_URI_GRANT = "uri-grant";
949    private static final String ATTR_USER_HANDLE = "userHandle";
950    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
951    private static final String ATTR_TARGET_USER_ID = "targetUserId";
952    private static final String ATTR_SOURCE_PKG = "sourcePkg";
953    private static final String ATTR_TARGET_PKG = "targetPkg";
954    private static final String ATTR_URI = "uri";
955    private static final String ATTR_MODE_FLAGS = "modeFlags";
956    private static final String ATTR_CREATED_TIME = "createdTime";
957    private static final String ATTR_PREFIX = "prefix";
958
959    /**
960     * Global set of specific {@link Uri} permissions that have been granted.
961     * This optimized lookup structure maps from {@link UriPermission#targetUid}
962     * to {@link UriPermission#uri} to {@link UriPermission}.
963     */
964    @GuardedBy("this")
965    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
966            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
967
968    public static class GrantUri {
969        public final int sourceUserId;
970        public final Uri uri;
971        public boolean prefix;
972
973        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
974            this.sourceUserId = sourceUserId;
975            this.uri = uri;
976            this.prefix = prefix;
977        }
978
979        @Override
980        public int hashCode() {
981            int hashCode = 1;
982            hashCode = 31 * hashCode + sourceUserId;
983            hashCode = 31 * hashCode + uri.hashCode();
984            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
985            return hashCode;
986        }
987
988        @Override
989        public boolean equals(Object o) {
990            if (o instanceof GrantUri) {
991                GrantUri other = (GrantUri) o;
992                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
993                        && prefix == other.prefix;
994            }
995            return false;
996        }
997
998        @Override
999        public String toString() {
1000            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1001            if (prefix) result += " [prefix]";
1002            return result;
1003        }
1004
1005        public String toSafeString() {
1006            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1007            if (prefix) result += " [prefix]";
1008            return result;
1009        }
1010
1011        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1012            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1013                    ContentProvider.getUriWithoutUserId(uri), false);
1014        }
1015    }
1016
1017    CoreSettingsObserver mCoreSettingsObserver;
1018
1019    FontScaleSettingObserver mFontScaleSettingObserver;
1020
1021    private final class FontScaleSettingObserver extends ContentObserver {
1022        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1023
1024        public FontScaleSettingObserver() {
1025            super(mHandler);
1026            ContentResolver resolver = mContext.getContentResolver();
1027            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1028        }
1029
1030        @Override
1031        public void onChange(boolean selfChange, Uri uri) {
1032            if (mFontScaleUri.equals(uri)) {
1033                updateFontScaleIfNeeded();
1034            }
1035        }
1036    }
1037
1038    /**
1039     * Thread-local storage used to carry caller permissions over through
1040     * indirect content-provider access.
1041     */
1042    private class Identity {
1043        public final IBinder token;
1044        public final int pid;
1045        public final int uid;
1046
1047        Identity(IBinder _token, int _pid, int _uid) {
1048            token = _token;
1049            pid = _pid;
1050            uid = _uid;
1051        }
1052    }
1053
1054    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1055
1056    /**
1057     * All information we have collected about the runtime performance of
1058     * any user id that can impact battery performance.
1059     */
1060    final BatteryStatsService mBatteryStatsService;
1061
1062    /**
1063     * Information about component usage
1064     */
1065    UsageStatsManagerInternal mUsageStatsService;
1066
1067    /**
1068     * Access to DeviceIdleController service.
1069     */
1070    DeviceIdleController.LocalService mLocalDeviceIdleController;
1071
1072    /**
1073     * Information about and control over application operations
1074     */
1075    final AppOpsService mAppOpsService;
1076
1077    /**
1078     * Current configuration information.  HistoryRecord objects are given
1079     * a reference to this object to indicate which configuration they are
1080     * currently running in, so this object must be kept immutable.
1081     */
1082    Configuration mConfiguration = new Configuration();
1083
1084    /**
1085     * Current sequencing integer of the configuration, for skipping old
1086     * configurations.
1087     */
1088    int mConfigurationSeq = 0;
1089
1090    boolean mSuppressResizeConfigChanges = false;
1091
1092    /**
1093     * Hardware-reported OpenGLES version.
1094     */
1095    final int GL_ES_VERSION;
1096
1097    /**
1098     * List of initialization arguments to pass to all processes when binding applications to them.
1099     * For example, references to the commonly used services.
1100     */
1101    HashMap<String, IBinder> mAppBindArgs;
1102
1103    /**
1104     * Temporary to avoid allocations.  Protected by main lock.
1105     */
1106    final StringBuilder mStringBuilder = new StringBuilder(256);
1107
1108    /**
1109     * Used to control how we initialize the service.
1110     */
1111    ComponentName mTopComponent;
1112    String mTopAction = Intent.ACTION_MAIN;
1113    String mTopData;
1114
1115    volatile boolean mProcessesReady = false;
1116    volatile boolean mSystemReady = false;
1117    volatile boolean mOnBattery = false;
1118    volatile int mFactoryTest;
1119
1120    @GuardedBy("this") boolean mBooting = false;
1121    @GuardedBy("this") boolean mCallFinishBooting = false;
1122    @GuardedBy("this") boolean mBootAnimationComplete = false;
1123    @GuardedBy("this") boolean mLaunchWarningShown = false;
1124    @GuardedBy("this") boolean mCheckedForSetup = false;
1125
1126    Context mContext;
1127
1128    /**
1129     * The time at which we will allow normal application switches again,
1130     * after a call to {@link #stopAppSwitches()}.
1131     */
1132    long mAppSwitchesAllowedTime;
1133
1134    /**
1135     * This is set to true after the first switch after mAppSwitchesAllowedTime
1136     * is set; any switches after that will clear the time.
1137     */
1138    boolean mDidAppSwitch;
1139
1140    /**
1141     * Last time (in realtime) at which we checked for power usage.
1142     */
1143    long mLastPowerCheckRealtime;
1144
1145    /**
1146     * Last time (in uptime) at which we checked for power usage.
1147     */
1148    long mLastPowerCheckUptime;
1149
1150    /**
1151     * Set while we are wanting to sleep, to prevent any
1152     * activities from being started/resumed.
1153     */
1154    private boolean mSleeping = false;
1155
1156    /**
1157     * The process state used for processes that are running the top activities.
1158     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1159     */
1160    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1161
1162    /**
1163     * Set while we are running a voice interaction.  This overrides
1164     * sleeping while it is active.
1165     */
1166    private IVoiceInteractionSession mRunningVoice;
1167
1168    /**
1169     * For some direct access we need to power manager.
1170     */
1171    PowerManagerInternal mLocalPowerManager;
1172
1173    /**
1174     * We want to hold a wake lock while running a voice interaction session, since
1175     * this may happen with the screen off and we need to keep the CPU running to
1176     * be able to continue to interact with the user.
1177     */
1178    PowerManager.WakeLock mVoiceWakeLock;
1179
1180    /**
1181     * State of external calls telling us if the device is awake or asleep.
1182     */
1183    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1184
1185    /**
1186     * A list of tokens that cause the top activity to be put to sleep.
1187     * They are used by components that may hide and block interaction with underlying
1188     * activities.
1189     */
1190    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1191
1192    static final int LOCK_SCREEN_HIDDEN = 0;
1193    static final int LOCK_SCREEN_LEAVING = 1;
1194    static final int LOCK_SCREEN_SHOWN = 2;
1195    /**
1196     * State of external call telling us if the lock screen is shown.
1197     */
1198    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1199
1200    /**
1201     * Set if we are shutting down the system, similar to sleeping.
1202     */
1203    boolean mShuttingDown = false;
1204
1205    /**
1206     * Current sequence id for oom_adj computation traversal.
1207     */
1208    int mAdjSeq = 0;
1209
1210    /**
1211     * Current sequence id for process LRU updating.
1212     */
1213    int mLruSeq = 0;
1214
1215    /**
1216     * Keep track of the non-cached/empty process we last found, to help
1217     * determine how to distribute cached/empty processes next time.
1218     */
1219    int mNumNonCachedProcs = 0;
1220
1221    /**
1222     * Keep track of the number of cached hidden procs, to balance oom adj
1223     * distribution between those and empty procs.
1224     */
1225    int mNumCachedHiddenProcs = 0;
1226
1227    /**
1228     * Keep track of the number of service processes we last found, to
1229     * determine on the next iteration which should be B services.
1230     */
1231    int mNumServiceProcs = 0;
1232    int mNewNumAServiceProcs = 0;
1233    int mNewNumServiceProcs = 0;
1234
1235    /**
1236     * Allow the current computed overall memory level of the system to go down?
1237     * This is set to false when we are killing processes for reasons other than
1238     * memory management, so that the now smaller process list will not be taken as
1239     * an indication that memory is tighter.
1240     */
1241    boolean mAllowLowerMemLevel = false;
1242
1243    /**
1244     * The last computed memory level, for holding when we are in a state that
1245     * processes are going away for other reasons.
1246     */
1247    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1248
1249    /**
1250     * The last total number of process we have, to determine if changes actually look
1251     * like a shrinking number of process due to lower RAM.
1252     */
1253    int mLastNumProcesses;
1254
1255    /**
1256     * The uptime of the last time we performed idle maintenance.
1257     */
1258    long mLastIdleTime = SystemClock.uptimeMillis();
1259
1260    /**
1261     * Total time spent with RAM that has been added in the past since the last idle time.
1262     */
1263    long mLowRamTimeSinceLastIdle = 0;
1264
1265    /**
1266     * If RAM is currently low, when that horrible situation started.
1267     */
1268    long mLowRamStartTime = 0;
1269
1270    /**
1271     * For reporting to battery stats the current top application.
1272     */
1273    private String mCurResumedPackage = null;
1274    private int mCurResumedUid = -1;
1275
1276    /**
1277     * For reporting to battery stats the apps currently running foreground
1278     * service.  The ProcessMap is package/uid tuples; each of these contain
1279     * an array of the currently foreground processes.
1280     */
1281    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1282            = new ProcessMap<ArrayList<ProcessRecord>>();
1283
1284    /**
1285     * This is set if we had to do a delayed dexopt of an app before launching
1286     * it, to increase the ANR timeouts in that case.
1287     */
1288    boolean mDidDexOpt;
1289
1290    /**
1291     * Set if the systemServer made a call to enterSafeMode.
1292     */
1293    boolean mSafeMode;
1294
1295    /**
1296     * If true, we are running under a test environment so will sample PSS from processes
1297     * much more rapidly to try to collect better data when the tests are rapidly
1298     * running through apps.
1299     */
1300    boolean mTestPssMode = false;
1301
1302    String mDebugApp = null;
1303    boolean mWaitForDebugger = false;
1304    boolean mDebugTransient = false;
1305    String mOrigDebugApp = null;
1306    boolean mOrigWaitForDebugger = false;
1307    boolean mAlwaysFinishActivities = false;
1308    boolean mLenientBackgroundCheck = false;
1309    boolean mForceResizableActivities;
1310    boolean mSupportsMultiWindow;
1311    boolean mSupportsFreeformWindowManagement;
1312    boolean mSupportsPictureInPicture;
1313    Rect mDefaultPinnedStackBounds;
1314    IActivityController mController = null;
1315    boolean mControllerIsAMonkey = false;
1316    String mProfileApp = null;
1317    ProcessRecord mProfileProc = null;
1318    String mProfileFile;
1319    ParcelFileDescriptor mProfileFd;
1320    int mSamplingInterval = 0;
1321    boolean mAutoStopProfiler = false;
1322    int mProfileType = 0;
1323    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1324    String mMemWatchDumpProcName;
1325    String mMemWatchDumpFile;
1326    int mMemWatchDumpPid;
1327    int mMemWatchDumpUid;
1328    String mTrackAllocationApp = null;
1329    String mNativeDebuggingApp = null;
1330
1331    final long[] mTmpLong = new long[2];
1332
1333    static final class ProcessChangeItem {
1334        static final int CHANGE_ACTIVITIES = 1<<0;
1335        static final int CHANGE_PROCESS_STATE = 1<<1;
1336        int changes;
1337        int uid;
1338        int pid;
1339        int processState;
1340        boolean foregroundActivities;
1341    }
1342
1343    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1344    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1345
1346    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1347    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1348
1349    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1350    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1351
1352    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1353    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1354
1355    /**
1356     * Runtime CPU use collection thread.  This object's lock is used to
1357     * perform synchronization with the thread (notifying it to run).
1358     */
1359    final Thread mProcessCpuThread;
1360
1361    /**
1362     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1363     * Must acquire this object's lock when accessing it.
1364     * NOTE: this lock will be held while doing long operations (trawling
1365     * through all processes in /proc), so it should never be acquired by
1366     * any critical paths such as when holding the main activity manager lock.
1367     */
1368    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1369            MONITOR_THREAD_CPU_USAGE);
1370    final AtomicLong mLastCpuTime = new AtomicLong(0);
1371    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1372
1373    long mLastWriteTime = 0;
1374
1375    /**
1376     * Used to retain an update lock when the foreground activity is in
1377     * immersive mode.
1378     */
1379    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1380
1381    /**
1382     * Set to true after the system has finished booting.
1383     */
1384    boolean mBooted = false;
1385
1386    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1387    int mProcessLimitOverride = -1;
1388
1389    WindowManagerService mWindowManager;
1390    final ActivityThread mSystemThread;
1391
1392    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1393        final ProcessRecord mApp;
1394        final int mPid;
1395        final IApplicationThread mAppThread;
1396
1397        AppDeathRecipient(ProcessRecord app, int pid,
1398                IApplicationThread thread) {
1399            if (DEBUG_ALL) Slog.v(
1400                TAG, "New death recipient " + this
1401                + " for thread " + thread.asBinder());
1402            mApp = app;
1403            mPid = pid;
1404            mAppThread = thread;
1405        }
1406
1407        @Override
1408        public void binderDied() {
1409            if (DEBUG_ALL) Slog.v(
1410                TAG, "Death received in " + this
1411                + " for thread " + mAppThread.asBinder());
1412            synchronized(ActivityManagerService.this) {
1413                appDiedLocked(mApp, mPid, mAppThread, true);
1414            }
1415        }
1416    }
1417
1418    static final int SHOW_ERROR_UI_MSG = 1;
1419    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1420    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1421    static final int UPDATE_CONFIGURATION_MSG = 4;
1422    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1423    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1424    static final int SERVICE_TIMEOUT_MSG = 12;
1425    static final int UPDATE_TIME_ZONE = 13;
1426    static final int SHOW_UID_ERROR_UI_MSG = 14;
1427    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1428    static final int PROC_START_TIMEOUT_MSG = 20;
1429    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1430    static final int KILL_APPLICATION_MSG = 22;
1431    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1432    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1433    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1434    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1435    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1436    static final int CLEAR_DNS_CACHE_MSG = 28;
1437    static final int UPDATE_HTTP_PROXY_MSG = 29;
1438    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1439    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1440    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1441    static final int REPORT_MEM_USAGE_MSG = 33;
1442    static final int REPORT_USER_SWITCH_MSG = 34;
1443    static final int CONTINUE_USER_SWITCH_MSG = 35;
1444    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1445    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1446    static final int PERSIST_URI_GRANTS_MSG = 38;
1447    static final int REQUEST_ALL_PSS_MSG = 39;
1448    static final int START_PROFILES_MSG = 40;
1449    static final int UPDATE_TIME = 41;
1450    static final int SYSTEM_USER_START_MSG = 42;
1451    static final int SYSTEM_USER_CURRENT_MSG = 43;
1452    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1453    static final int FINISH_BOOTING_MSG = 45;
1454    static final int START_USER_SWITCH_UI_MSG = 46;
1455    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1456    static final int DISMISS_DIALOG_UI_MSG = 48;
1457    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1458    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1459    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1460    static final int DELETE_DUMPHEAP_MSG = 52;
1461    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1462    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1463    static final int REPORT_TIME_TRACKER_MSG = 55;
1464    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1465    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1466    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1467    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1468    static final int IDLE_UIDS_MSG = 60;
1469    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1470    static final int LOG_STACK_STATE = 62;
1471    static final int VR_MODE_CHANGE_MSG = 63;
1472    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1473    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1474    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1475    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1476    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1477    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1478
1479    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1480    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1481    static final int FIRST_COMPAT_MODE_MSG = 300;
1482    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1483
1484    static ServiceThread sKillThread = null;
1485    static KillHandler sKillHandler = null;
1486
1487    CompatModeDialog mCompatModeDialog;
1488    long mLastMemUsageReportTime = 0;
1489
1490    /**
1491     * Flag whether the current user is a "monkey", i.e. whether
1492     * the UI is driven by a UI automation tool.
1493     */
1494    private boolean mUserIsMonkey;
1495
1496    /** Flag whether the device has a Recents UI */
1497    boolean mHasRecents;
1498
1499    /** The dimensions of the thumbnails in the Recents UI. */
1500    int mThumbnailWidth;
1501    int mThumbnailHeight;
1502    float mFullscreenThumbnailScale;
1503
1504    final ServiceThread mHandlerThread;
1505    final MainHandler mHandler;
1506    final UiHandler mUiHandler;
1507
1508    PackageManagerInternal mPackageManagerInt;
1509
1510    final class KillHandler extends Handler {
1511        static final int KILL_PROCESS_GROUP_MSG = 4000;
1512
1513        public KillHandler(Looper looper) {
1514            super(looper, null, true);
1515        }
1516
1517        @Override
1518        public void handleMessage(Message msg) {
1519            switch (msg.what) {
1520                case KILL_PROCESS_GROUP_MSG:
1521                {
1522                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1523                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1524                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1525                }
1526                break;
1527
1528                default:
1529                    super.handleMessage(msg);
1530            }
1531        }
1532    }
1533
1534    final class UiHandler extends Handler {
1535        public UiHandler() {
1536            super(com.android.server.UiThread.get().getLooper(), null, true);
1537        }
1538
1539        @Override
1540        public void handleMessage(Message msg) {
1541            switch (msg.what) {
1542            case SHOW_ERROR_UI_MSG: {
1543                mAppErrors.handleShowAppErrorUi(msg);
1544                ensureBootCompleted();
1545            } break;
1546            case SHOW_NOT_RESPONDING_UI_MSG: {
1547                mAppErrors.handleShowAnrUi(msg);
1548                ensureBootCompleted();
1549            } break;
1550            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1551                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1552                synchronized (ActivityManagerService.this) {
1553                    ProcessRecord proc = (ProcessRecord) data.get("app");
1554                    if (proc == null) {
1555                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1556                        break;
1557                    }
1558                    if (proc.crashDialog != null) {
1559                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1560                        return;
1561                    }
1562                    AppErrorResult res = (AppErrorResult) data.get("result");
1563                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1564                        Dialog d = new StrictModeViolationDialog(mContext,
1565                                ActivityManagerService.this, res, proc);
1566                        d.show();
1567                        proc.crashDialog = d;
1568                    } else {
1569                        // The device is asleep, so just pretend that the user
1570                        // saw a crash dialog and hit "force quit".
1571                        res.set(0);
1572                    }
1573                }
1574                ensureBootCompleted();
1575            } break;
1576            case SHOW_FACTORY_ERROR_UI_MSG: {
1577                Dialog d = new FactoryErrorDialog(
1578                    mContext, msg.getData().getCharSequence("msg"));
1579                d.show();
1580                ensureBootCompleted();
1581            } break;
1582            case WAIT_FOR_DEBUGGER_UI_MSG: {
1583                synchronized (ActivityManagerService.this) {
1584                    ProcessRecord app = (ProcessRecord)msg.obj;
1585                    if (msg.arg1 != 0) {
1586                        if (!app.waitedForDebugger) {
1587                            Dialog d = new AppWaitingForDebuggerDialog(
1588                                    ActivityManagerService.this,
1589                                    mContext, app);
1590                            app.waitDialog = d;
1591                            app.waitedForDebugger = true;
1592                            d.show();
1593                        }
1594                    } else {
1595                        if (app.waitDialog != null) {
1596                            app.waitDialog.dismiss();
1597                            app.waitDialog = null;
1598                        }
1599                    }
1600                }
1601            } break;
1602            case SHOW_UID_ERROR_UI_MSG: {
1603                if (mShowDialogs) {
1604                    AlertDialog d = new BaseErrorDialog(mContext);
1605                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1606                    d.setCancelable(false);
1607                    d.setTitle(mContext.getText(R.string.android_system_label));
1608                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1609                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1610                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1611                    d.show();
1612                }
1613            } break;
1614            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1615                if (mShowDialogs) {
1616                    AlertDialog d = new BaseErrorDialog(mContext);
1617                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1618                    d.setCancelable(false);
1619                    d.setTitle(mContext.getText(R.string.android_system_label));
1620                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1621                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1622                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1623                    d.show();
1624                }
1625            } break;
1626            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1627                synchronized (ActivityManagerService.this) {
1628                    ActivityRecord ar = (ActivityRecord) msg.obj;
1629                    if (mCompatModeDialog != null) {
1630                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1631                                ar.info.applicationInfo.packageName)) {
1632                            return;
1633                        }
1634                        mCompatModeDialog.dismiss();
1635                        mCompatModeDialog = null;
1636                    }
1637                    if (ar != null && false) {
1638                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1639                                ar.packageName)) {
1640                            int mode = mCompatModePackages.computeCompatModeLocked(
1641                                    ar.info.applicationInfo);
1642                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1643                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1644                                mCompatModeDialog = new CompatModeDialog(
1645                                        ActivityManagerService.this, mContext,
1646                                        ar.info.applicationInfo);
1647                                mCompatModeDialog.show();
1648                            }
1649                        }
1650                    }
1651                }
1652                break;
1653            }
1654            case START_USER_SWITCH_UI_MSG: {
1655                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1656                break;
1657            }
1658            case DISMISS_DIALOG_UI_MSG: {
1659                final Dialog d = (Dialog) msg.obj;
1660                d.dismiss();
1661                break;
1662            }
1663            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1664                dispatchProcessesChanged();
1665                break;
1666            }
1667            case DISPATCH_PROCESS_DIED_UI_MSG: {
1668                final int pid = msg.arg1;
1669                final int uid = msg.arg2;
1670                dispatchProcessDied(pid, uid);
1671                break;
1672            }
1673            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1674                dispatchUidsChanged();
1675            } break;
1676            }
1677        }
1678    }
1679
1680    final class MainHandler extends Handler {
1681        public MainHandler(Looper looper) {
1682            super(looper, null, true);
1683        }
1684
1685        @Override
1686        public void handleMessage(Message msg) {
1687            switch (msg.what) {
1688            case UPDATE_CONFIGURATION_MSG: {
1689                final ContentResolver resolver = mContext.getContentResolver();
1690                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1691                        msg.arg1);
1692            } break;
1693            case GC_BACKGROUND_PROCESSES_MSG: {
1694                synchronized (ActivityManagerService.this) {
1695                    performAppGcsIfAppropriateLocked();
1696                }
1697            } break;
1698            case SERVICE_TIMEOUT_MSG: {
1699                if (mDidDexOpt) {
1700                    mDidDexOpt = false;
1701                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1702                    nmsg.obj = msg.obj;
1703                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1704                    return;
1705                }
1706                mServices.serviceTimeout((ProcessRecord)msg.obj);
1707            } break;
1708            case UPDATE_TIME_ZONE: {
1709                synchronized (ActivityManagerService.this) {
1710                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1711                        ProcessRecord r = mLruProcesses.get(i);
1712                        if (r.thread != null) {
1713                            try {
1714                                r.thread.updateTimeZone();
1715                            } catch (RemoteException ex) {
1716                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1717                            }
1718                        }
1719                    }
1720                }
1721            } break;
1722            case CLEAR_DNS_CACHE_MSG: {
1723                synchronized (ActivityManagerService.this) {
1724                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1725                        ProcessRecord r = mLruProcesses.get(i);
1726                        if (r.thread != null) {
1727                            try {
1728                                r.thread.clearDnsCache();
1729                            } catch (RemoteException ex) {
1730                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1731                            }
1732                        }
1733                    }
1734                }
1735            } break;
1736            case UPDATE_HTTP_PROXY_MSG: {
1737                ProxyInfo proxy = (ProxyInfo)msg.obj;
1738                String host = "";
1739                String port = "";
1740                String exclList = "";
1741                Uri pacFileUrl = Uri.EMPTY;
1742                if (proxy != null) {
1743                    host = proxy.getHost();
1744                    port = Integer.toString(proxy.getPort());
1745                    exclList = proxy.getExclusionListAsString();
1746                    pacFileUrl = proxy.getPacFileUrl();
1747                }
1748                synchronized (ActivityManagerService.this) {
1749                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1750                        ProcessRecord r = mLruProcesses.get(i);
1751                        if (r.thread != null) {
1752                            try {
1753                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1754                            } catch (RemoteException ex) {
1755                                Slog.w(TAG, "Failed to update http proxy for: " +
1756                                        r.info.processName);
1757                            }
1758                        }
1759                    }
1760                }
1761            } break;
1762            case PROC_START_TIMEOUT_MSG: {
1763                if (mDidDexOpt) {
1764                    mDidDexOpt = false;
1765                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1766                    nmsg.obj = msg.obj;
1767                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1768                    return;
1769                }
1770                ProcessRecord app = (ProcessRecord)msg.obj;
1771                synchronized (ActivityManagerService.this) {
1772                    processStartTimedOutLocked(app);
1773                }
1774            } break;
1775            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1776                ProcessRecord app = (ProcessRecord)msg.obj;
1777                synchronized (ActivityManagerService.this) {
1778                    processContentProviderPublishTimedOutLocked(app);
1779                }
1780            } break;
1781            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1782                synchronized (ActivityManagerService.this) {
1783                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1784                }
1785            } break;
1786            case KILL_APPLICATION_MSG: {
1787                synchronized (ActivityManagerService.this) {
1788                    int appid = msg.arg1;
1789                    boolean restart = (msg.arg2 == 1);
1790                    Bundle bundle = (Bundle)msg.obj;
1791                    String pkg = bundle.getString("pkg");
1792                    String reason = bundle.getString("reason");
1793                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1794                            false, UserHandle.USER_ALL, reason);
1795                }
1796            } break;
1797            case FINALIZE_PENDING_INTENT_MSG: {
1798                ((PendingIntentRecord)msg.obj).completeFinalize();
1799            } break;
1800            case POST_HEAVY_NOTIFICATION_MSG: {
1801                INotificationManager inm = NotificationManager.getService();
1802                if (inm == null) {
1803                    return;
1804                }
1805
1806                ActivityRecord root = (ActivityRecord)msg.obj;
1807                ProcessRecord process = root.app;
1808                if (process == null) {
1809                    return;
1810                }
1811
1812                try {
1813                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1814                    String text = mContext.getString(R.string.heavy_weight_notification,
1815                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1816                    Notification notification = new Notification.Builder(context)
1817                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1818                            .setWhen(0)
1819                            .setOngoing(true)
1820                            .setTicker(text)
1821                            .setColor(mContext.getColor(
1822                                    com.android.internal.R.color.system_notification_accent_color))
1823                            .setContentTitle(text)
1824                            .setContentText(
1825                                    mContext.getText(R.string.heavy_weight_notification_detail))
1826                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1827                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1828                                    new UserHandle(root.userId)))
1829                            .build();
1830                    try {
1831                        int[] outId = new int[1];
1832                        inm.enqueueNotificationWithTag("android", "android", null,
1833                                R.string.heavy_weight_notification,
1834                                notification, outId, root.userId);
1835                    } catch (RuntimeException e) {
1836                        Slog.w(ActivityManagerService.TAG,
1837                                "Error showing notification for heavy-weight app", e);
1838                    } catch (RemoteException e) {
1839                    }
1840                } catch (NameNotFoundException e) {
1841                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1842                }
1843            } break;
1844            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1845                INotificationManager inm = NotificationManager.getService();
1846                if (inm == null) {
1847                    return;
1848                }
1849                try {
1850                    inm.cancelNotificationWithTag("android", null,
1851                            R.string.heavy_weight_notification,  msg.arg1);
1852                } catch (RuntimeException e) {
1853                    Slog.w(ActivityManagerService.TAG,
1854                            "Error canceling notification for service", e);
1855                } catch (RemoteException e) {
1856                }
1857            } break;
1858            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1859                synchronized (ActivityManagerService.this) {
1860                    checkExcessivePowerUsageLocked(true);
1861                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1862                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1863                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1864                }
1865            } break;
1866            case REPORT_MEM_USAGE_MSG: {
1867                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1868                Thread thread = new Thread() {
1869                    @Override public void run() {
1870                        reportMemUsage(memInfos);
1871                    }
1872                };
1873                thread.start();
1874                break;
1875            }
1876            case REPORT_USER_SWITCH_MSG: {
1877                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1878                break;
1879            }
1880            case CONTINUE_USER_SWITCH_MSG: {
1881                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1882                break;
1883            }
1884            case USER_SWITCH_TIMEOUT_MSG: {
1885                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1886                break;
1887            }
1888            case IMMERSIVE_MODE_LOCK_MSG: {
1889                final boolean nextState = (msg.arg1 != 0);
1890                if (mUpdateLock.isHeld() != nextState) {
1891                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1892                            "Applying new update lock state '" + nextState
1893                            + "' for " + (ActivityRecord)msg.obj);
1894                    if (nextState) {
1895                        mUpdateLock.acquire();
1896                    } else {
1897                        mUpdateLock.release();
1898                    }
1899                }
1900                break;
1901            }
1902            case PERSIST_URI_GRANTS_MSG: {
1903                writeGrantedUriPermissions();
1904                break;
1905            }
1906            case REQUEST_ALL_PSS_MSG: {
1907                synchronized (ActivityManagerService.this) {
1908                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1909                }
1910                break;
1911            }
1912            case START_PROFILES_MSG: {
1913                synchronized (ActivityManagerService.this) {
1914                    mUserController.startProfilesLocked();
1915                }
1916                break;
1917            }
1918            case UPDATE_TIME: {
1919                synchronized (ActivityManagerService.this) {
1920                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1921                        ProcessRecord r = mLruProcesses.get(i);
1922                        if (r.thread != null) {
1923                            try {
1924                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1925                            } catch (RemoteException ex) {
1926                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1927                            }
1928                        }
1929                    }
1930                }
1931                break;
1932            }
1933            case SYSTEM_USER_START_MSG: {
1934                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1935                        Integer.toString(msg.arg1), msg.arg1);
1936                mSystemServiceManager.startUser(msg.arg1);
1937                break;
1938            }
1939            case SYSTEM_USER_UNLOCK_MSG: {
1940                final int userId = msg.arg1;
1941                mSystemServiceManager.unlockUser(userId);
1942                synchronized (ActivityManagerService.this) {
1943                    mRecentTasks.loadUserRecentsLocked(userId);
1944                }
1945                if (userId == UserHandle.USER_SYSTEM) {
1946                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1947                }
1948                installEncryptionUnawareProviders(userId);
1949                if (msg.obj instanceof ProgressReporter) {
1950                    ((ProgressReporter) msg.obj).finish();
1951                }
1952                break;
1953            }
1954            case SYSTEM_USER_CURRENT_MSG: {
1955                mBatteryStatsService.noteEvent(
1956                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1957                        Integer.toString(msg.arg2), msg.arg2);
1958                mBatteryStatsService.noteEvent(
1959                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1960                        Integer.toString(msg.arg1), msg.arg1);
1961                mSystemServiceManager.switchUser(msg.arg1);
1962                break;
1963            }
1964            case ENTER_ANIMATION_COMPLETE_MSG: {
1965                synchronized (ActivityManagerService.this) {
1966                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1967                    if (r != null && r.app != null && r.app.thread != null) {
1968                        try {
1969                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1970                        } catch (RemoteException e) {
1971                        }
1972                    }
1973                }
1974                break;
1975            }
1976            case FINISH_BOOTING_MSG: {
1977                if (msg.arg1 != 0) {
1978                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1979                    finishBooting();
1980                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1981                }
1982                if (msg.arg2 != 0) {
1983                    enableScreenAfterBoot();
1984                }
1985                break;
1986            }
1987            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1988                try {
1989                    Locale l = (Locale) msg.obj;
1990                    IBinder service = ServiceManager.getService("mount");
1991                    IMountService mountService = IMountService.Stub.asInterface(service);
1992                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1993                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1994                } catch (RemoteException e) {
1995                    Log.e(TAG, "Error storing locale for decryption UI", e);
1996                }
1997                break;
1998            }
1999            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2000                synchronized (ActivityManagerService.this) {
2001                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2002                        try {
2003                            // Make a one-way callback to the listener
2004                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2005                        } catch (RemoteException e){
2006                            // Handled by the RemoteCallbackList
2007                        }
2008                    }
2009                    mTaskStackListeners.finishBroadcast();
2010                }
2011                break;
2012            }
2013            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2014                synchronized (ActivityManagerService.this) {
2015                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2016                        try {
2017                            // Make a one-way callback to the listener
2018                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2019                        } catch (RemoteException e){
2020                            // Handled by the RemoteCallbackList
2021                        }
2022                    }
2023                    mTaskStackListeners.finishBroadcast();
2024                }
2025                break;
2026            }
2027            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2028                synchronized (ActivityManagerService.this) {
2029                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2030                        try {
2031                            // Make a one-way callback to the listener
2032                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2033                        } catch (RemoteException e){
2034                            // Handled by the RemoteCallbackList
2035                        }
2036                    }
2037                    mTaskStackListeners.finishBroadcast();
2038                }
2039                break;
2040            }
2041            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2042                synchronized (ActivityManagerService.this) {
2043                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2044                        try {
2045                            // Make a one-way callback to the listener
2046                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2047                        } catch (RemoteException e){
2048                            // Handled by the RemoteCallbackList
2049                        }
2050                    }
2051                    mTaskStackListeners.finishBroadcast();
2052                }
2053                break;
2054            }
2055            case NOTIFY_FORCED_RESIZABLE_MSG: {
2056                synchronized (ActivityManagerService.this) {
2057                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2058                        try {
2059                            // Make a one-way callback to the listener
2060                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2061                                    (String) msg.obj, msg.arg1);
2062                        } catch (RemoteException e){
2063                            // Handled by the RemoteCallbackList
2064                        }
2065                    }
2066                    mTaskStackListeners.finishBroadcast();
2067                }
2068                break;
2069            }
2070                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2071                    synchronized (ActivityManagerService.this) {
2072                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2073                            try {
2074                                // Make a one-way callback to the listener
2075                                mTaskStackListeners.getBroadcastItem(i)
2076                                        .onActivityDismissingDockedStack();
2077                            } catch (RemoteException e){
2078                                // Handled by the RemoteCallbackList
2079                            }
2080                        }
2081                        mTaskStackListeners.finishBroadcast();
2082                    }
2083                    break;
2084                }
2085            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2086                final int uid = msg.arg1;
2087                final byte[] firstPacket = (byte[]) msg.obj;
2088
2089                synchronized (mPidsSelfLocked) {
2090                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2091                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2092                        if (p.uid == uid) {
2093                            try {
2094                                p.thread.notifyCleartextNetwork(firstPacket);
2095                            } catch (RemoteException ignored) {
2096                            }
2097                        }
2098                    }
2099                }
2100                break;
2101            }
2102            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2103                final String procName;
2104                final int uid;
2105                final long memLimit;
2106                final String reportPackage;
2107                synchronized (ActivityManagerService.this) {
2108                    procName = mMemWatchDumpProcName;
2109                    uid = mMemWatchDumpUid;
2110                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2111                    if (val == null) {
2112                        val = mMemWatchProcesses.get(procName, 0);
2113                    }
2114                    if (val != null) {
2115                        memLimit = val.first;
2116                        reportPackage = val.second;
2117                    } else {
2118                        memLimit = 0;
2119                        reportPackage = null;
2120                    }
2121                }
2122                if (procName == null) {
2123                    return;
2124                }
2125
2126                if (DEBUG_PSS) Slog.d(TAG_PSS,
2127                        "Showing dump heap notification from " + procName + "/" + uid);
2128
2129                INotificationManager inm = NotificationManager.getService();
2130                if (inm == null) {
2131                    return;
2132                }
2133
2134                String text = mContext.getString(R.string.dump_heap_notification, procName);
2135
2136
2137                Intent deleteIntent = new Intent();
2138                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2139                Intent intent = new Intent();
2140                intent.setClassName("android", DumpHeapActivity.class.getName());
2141                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2142                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2143                if (reportPackage != null) {
2144                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2145                }
2146                int userId = UserHandle.getUserId(uid);
2147                Notification notification = new Notification.Builder(mContext)
2148                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2149                        .setWhen(0)
2150                        .setOngoing(true)
2151                        .setAutoCancel(true)
2152                        .setTicker(text)
2153                        .setColor(mContext.getColor(
2154                                com.android.internal.R.color.system_notification_accent_color))
2155                        .setContentTitle(text)
2156                        .setContentText(
2157                                mContext.getText(R.string.dump_heap_notification_detail))
2158                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2159                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2160                                new UserHandle(userId)))
2161                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2162                                deleteIntent, 0, UserHandle.SYSTEM))
2163                        .build();
2164
2165                try {
2166                    int[] outId = new int[1];
2167                    inm.enqueueNotificationWithTag("android", "android", null,
2168                            R.string.dump_heap_notification,
2169                            notification, outId, userId);
2170                } catch (RuntimeException e) {
2171                    Slog.w(ActivityManagerService.TAG,
2172                            "Error showing notification for dump heap", e);
2173                } catch (RemoteException e) {
2174                }
2175            } break;
2176            case DELETE_DUMPHEAP_MSG: {
2177                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2178                        DumpHeapActivity.JAVA_URI,
2179                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2180                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2181                        UserHandle.myUserId());
2182                synchronized (ActivityManagerService.this) {
2183                    mMemWatchDumpFile = null;
2184                    mMemWatchDumpProcName = null;
2185                    mMemWatchDumpPid = -1;
2186                    mMemWatchDumpUid = -1;
2187                }
2188            } break;
2189            case FOREGROUND_PROFILE_CHANGED_MSG: {
2190                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2191            } break;
2192            case REPORT_TIME_TRACKER_MSG: {
2193                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2194                tracker.deliverResult(mContext);
2195            } break;
2196            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2197                mUserController.dispatchUserSwitchComplete(msg.arg1);
2198            } break;
2199            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2200                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2201                try {
2202                    connection.shutdown();
2203                } catch (RemoteException e) {
2204                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2205                }
2206                // Only a UiAutomation can set this flag and now that
2207                // it is finished we make sure it is reset to its default.
2208                mUserIsMonkey = false;
2209            } break;
2210            case APP_BOOST_DEACTIVATE_MSG: {
2211                synchronized(ActivityManagerService.this) {
2212                    if (mIsBoosted) {
2213                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2214                            nativeMigrateFromBoost();
2215                            mIsBoosted = false;
2216                            mBoostStartTime = 0;
2217                        } else {
2218                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2219                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2220                        }
2221                    }
2222                }
2223            } break;
2224            case IDLE_UIDS_MSG: {
2225                idleUids();
2226            } break;
2227            case LOG_STACK_STATE: {
2228                synchronized (ActivityManagerService.this) {
2229                    mStackSupervisor.logStackState();
2230                }
2231            } break;
2232            case VR_MODE_CHANGE_MSG: {
2233                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2234                final ActivityRecord r = (ActivityRecord) msg.obj;
2235                boolean vrMode;
2236                ComponentName requestedPackage;
2237                ComponentName callingPackage;
2238                int userId;
2239                synchronized (ActivityManagerService.this) {
2240                    vrMode = r.requestedVrComponent != null;
2241                    requestedPackage = r.requestedVrComponent;
2242                    userId = r.userId;
2243                    callingPackage = r.info.getComponentName();
2244                    if (mInVrMode != vrMode) {
2245                        mInVrMode = vrMode;
2246                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2247                    }
2248                }
2249                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2250            } break;
2251            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2252                final ActivityRecord r = (ActivityRecord) msg.obj;
2253                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2254                if (needsVrMode) {
2255                    VrManagerInternal vrService =
2256                            LocalServices.getService(VrManagerInternal.class);
2257                    boolean enable = msg.arg1 == 1;
2258                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2259                            r.info.getComponentName());
2260                }
2261            } break;
2262            }
2263        }
2264    };
2265
2266    static final int COLLECT_PSS_BG_MSG = 1;
2267
2268    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2269        @Override
2270        public void handleMessage(Message msg) {
2271            switch (msg.what) {
2272            case COLLECT_PSS_BG_MSG: {
2273                long start = SystemClock.uptimeMillis();
2274                MemInfoReader memInfo = null;
2275                synchronized (ActivityManagerService.this) {
2276                    if (mFullPssPending) {
2277                        mFullPssPending = false;
2278                        memInfo = new MemInfoReader();
2279                    }
2280                }
2281                if (memInfo != null) {
2282                    updateCpuStatsNow();
2283                    long nativeTotalPss = 0;
2284                    synchronized (mProcessCpuTracker) {
2285                        final int N = mProcessCpuTracker.countStats();
2286                        for (int j=0; j<N; j++) {
2287                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2288                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2289                                // This is definitely an application process; skip it.
2290                                continue;
2291                            }
2292                            synchronized (mPidsSelfLocked) {
2293                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2294                                    // This is one of our own processes; skip it.
2295                                    continue;
2296                                }
2297                            }
2298                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2299                        }
2300                    }
2301                    memInfo.readMemInfo();
2302                    synchronized (ActivityManagerService.this) {
2303                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2304                                + (SystemClock.uptimeMillis()-start) + "ms");
2305                        final long cachedKb = memInfo.getCachedSizeKb();
2306                        final long freeKb = memInfo.getFreeSizeKb();
2307                        final long zramKb = memInfo.getZramTotalSizeKb();
2308                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2309                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2310                                kernelKb*1024, nativeTotalPss*1024);
2311                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2312                                nativeTotalPss);
2313                    }
2314                }
2315
2316                int num = 0;
2317                long[] tmp = new long[2];
2318                do {
2319                    ProcessRecord proc;
2320                    int procState;
2321                    int pid;
2322                    long lastPssTime;
2323                    synchronized (ActivityManagerService.this) {
2324                        if (mPendingPssProcesses.size() <= 0) {
2325                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2326                                    "Collected PSS of " + num + " processes in "
2327                                    + (SystemClock.uptimeMillis() - start) + "ms");
2328                            mPendingPssProcesses.clear();
2329                            return;
2330                        }
2331                        proc = mPendingPssProcesses.remove(0);
2332                        procState = proc.pssProcState;
2333                        lastPssTime = proc.lastPssTime;
2334                        if (proc.thread != null && procState == proc.setProcState
2335                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2336                                        < SystemClock.uptimeMillis()) {
2337                            pid = proc.pid;
2338                        } else {
2339                            proc = null;
2340                            pid = 0;
2341                        }
2342                    }
2343                    if (proc != null) {
2344                        long pss = Debug.getPss(pid, tmp, null);
2345                        synchronized (ActivityManagerService.this) {
2346                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2347                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2348                                num++;
2349                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2350                                        SystemClock.uptimeMillis());
2351                            }
2352                        }
2353                    }
2354                } while (true);
2355            }
2356            }
2357        }
2358    };
2359
2360    public void setSystemProcess() {
2361        try {
2362            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2363            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2364            ServiceManager.addService("meminfo", new MemBinder(this));
2365            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2366            ServiceManager.addService("dbinfo", new DbBinder(this));
2367            if (MONITOR_CPU_USAGE) {
2368                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2369            }
2370            ServiceManager.addService("permission", new PermissionController(this));
2371            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2372
2373            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2374                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2375            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2376
2377            synchronized (this) {
2378                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2379                app.persistent = true;
2380                app.pid = MY_PID;
2381                app.maxAdj = ProcessList.SYSTEM_ADJ;
2382                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2383                synchronized (mPidsSelfLocked) {
2384                    mPidsSelfLocked.put(app.pid, app);
2385                }
2386                updateLruProcessLocked(app, false, null);
2387                updateOomAdjLocked();
2388            }
2389        } catch (PackageManager.NameNotFoundException e) {
2390            throw new RuntimeException(
2391                    "Unable to find android system package", e);
2392        }
2393    }
2394
2395    public void setWindowManager(WindowManagerService wm) {
2396        mWindowManager = wm;
2397        mStackSupervisor.setWindowManager(wm);
2398        mActivityStarter.setWindowManager(wm);
2399    }
2400
2401    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2402        mUsageStatsService = usageStatsManager;
2403    }
2404
2405    public void startObservingNativeCrashes() {
2406        final NativeCrashListener ncl = new NativeCrashListener(this);
2407        ncl.start();
2408    }
2409
2410    public IAppOpsService getAppOpsService() {
2411        return mAppOpsService;
2412    }
2413
2414    static class MemBinder extends Binder {
2415        ActivityManagerService mActivityManagerService;
2416        MemBinder(ActivityManagerService activityManagerService) {
2417            mActivityManagerService = activityManagerService;
2418        }
2419
2420        @Override
2421        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2422            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2423                    != PackageManager.PERMISSION_GRANTED) {
2424                pw.println("Permission Denial: can't dump meminfo from from pid="
2425                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2426                        + " without permission " + android.Manifest.permission.DUMP);
2427                return;
2428            }
2429
2430            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2431        }
2432    }
2433
2434    static class GraphicsBinder extends Binder {
2435        ActivityManagerService mActivityManagerService;
2436        GraphicsBinder(ActivityManagerService activityManagerService) {
2437            mActivityManagerService = activityManagerService;
2438        }
2439
2440        @Override
2441        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2442            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2443                    != PackageManager.PERMISSION_GRANTED) {
2444                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2445                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2446                        + " without permission " + android.Manifest.permission.DUMP);
2447                return;
2448            }
2449
2450            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2451        }
2452    }
2453
2454    static class DbBinder extends Binder {
2455        ActivityManagerService mActivityManagerService;
2456        DbBinder(ActivityManagerService activityManagerService) {
2457            mActivityManagerService = activityManagerService;
2458        }
2459
2460        @Override
2461        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2462            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2463                    != PackageManager.PERMISSION_GRANTED) {
2464                pw.println("Permission Denial: can't dump dbinfo from from pid="
2465                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2466                        + " without permission " + android.Manifest.permission.DUMP);
2467                return;
2468            }
2469
2470            mActivityManagerService.dumpDbInfo(fd, pw, args);
2471        }
2472    }
2473
2474    static class CpuBinder extends Binder {
2475        ActivityManagerService mActivityManagerService;
2476        CpuBinder(ActivityManagerService activityManagerService) {
2477            mActivityManagerService = activityManagerService;
2478        }
2479
2480        @Override
2481        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2482            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2483                    != PackageManager.PERMISSION_GRANTED) {
2484                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2485                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2486                        + " without permission " + android.Manifest.permission.DUMP);
2487                return;
2488            }
2489
2490            synchronized (mActivityManagerService.mProcessCpuTracker) {
2491                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2492                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2493                        SystemClock.uptimeMillis()));
2494            }
2495        }
2496    }
2497
2498    public static final class Lifecycle extends SystemService {
2499        private final ActivityManagerService mService;
2500
2501        public Lifecycle(Context context) {
2502            super(context);
2503            mService = new ActivityManagerService(context);
2504        }
2505
2506        @Override
2507        public void onStart() {
2508            mService.start();
2509        }
2510
2511        public ActivityManagerService getService() {
2512            return mService;
2513        }
2514    }
2515
2516    // Note: This method is invoked on the main thread but may need to attach various
2517    // handlers to other threads.  So take care to be explicit about the looper.
2518    public ActivityManagerService(Context systemContext) {
2519        mContext = systemContext;
2520        mFactoryTest = FactoryTest.getMode();
2521        mSystemThread = ActivityThread.currentActivityThread();
2522
2523        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2524
2525        mHandlerThread = new ServiceThread(TAG,
2526                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2527        mHandlerThread.start();
2528        mHandler = new MainHandler(mHandlerThread.getLooper());
2529        mUiHandler = new UiHandler();
2530
2531        /* static; one-time init here */
2532        if (sKillHandler == null) {
2533            sKillThread = new ServiceThread(TAG + ":kill",
2534                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2535            sKillThread.start();
2536            sKillHandler = new KillHandler(sKillThread.getLooper());
2537        }
2538
2539        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2540                "foreground", BROADCAST_FG_TIMEOUT, false);
2541        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2542                "background", BROADCAST_BG_TIMEOUT, true);
2543        mBroadcastQueues[0] = mFgBroadcastQueue;
2544        mBroadcastQueues[1] = mBgBroadcastQueue;
2545
2546        mServices = new ActiveServices(this);
2547        mProviderMap = new ProviderMap(this);
2548        mAppErrors = new AppErrors(mContext, this);
2549
2550        // TODO: Move creation of battery stats service outside of activity manager service.
2551        File dataDir = Environment.getDataDirectory();
2552        File systemDir = new File(dataDir, "system");
2553        systemDir.mkdirs();
2554        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2555        mBatteryStatsService.getActiveStatistics().readLocked();
2556        mBatteryStatsService.scheduleWriteToDisk();
2557        mOnBattery = DEBUG_POWER ? true
2558                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2559        mBatteryStatsService.getActiveStatistics().setCallback(this);
2560
2561        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2562
2563        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2564        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2565                new IAppOpsCallback.Stub() {
2566                    @Override public void opChanged(int op, int uid, String packageName) {
2567                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2568                            if (mAppOpsService.checkOperation(op, uid, packageName)
2569                                    != AppOpsManager.MODE_ALLOWED) {
2570                                runInBackgroundDisabled(uid);
2571                            }
2572                        }
2573                    }
2574                });
2575
2576        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2577
2578        mUserController = new UserController(this);
2579
2580        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2581            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2582
2583        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2584
2585        mConfiguration.setToDefaults();
2586        mConfiguration.setLocales(LocaleList.getDefault());
2587
2588        mConfigurationSeq = mConfiguration.seq = 1;
2589        mProcessCpuTracker.init();
2590
2591        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2592        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2593        mStackSupervisor = new ActivityStackSupervisor(this);
2594        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2595        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2596
2597        mProcessCpuThread = new Thread("CpuTracker") {
2598            @Override
2599            public void run() {
2600                while (true) {
2601                    try {
2602                        try {
2603                            synchronized(this) {
2604                                final long now = SystemClock.uptimeMillis();
2605                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2606                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2607                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2608                                //        + ", write delay=" + nextWriteDelay);
2609                                if (nextWriteDelay < nextCpuDelay) {
2610                                    nextCpuDelay = nextWriteDelay;
2611                                }
2612                                if (nextCpuDelay > 0) {
2613                                    mProcessCpuMutexFree.set(true);
2614                                    this.wait(nextCpuDelay);
2615                                }
2616                            }
2617                        } catch (InterruptedException e) {
2618                        }
2619                        updateCpuStatsNow();
2620                    } catch (Exception e) {
2621                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2622                    }
2623                }
2624            }
2625        };
2626
2627        Watchdog.getInstance().addMonitor(this);
2628        Watchdog.getInstance().addThread(mHandler);
2629    }
2630
2631    public void setSystemServiceManager(SystemServiceManager mgr) {
2632        mSystemServiceManager = mgr;
2633    }
2634
2635    public void setInstaller(Installer installer) {
2636        mInstaller = installer;
2637    }
2638
2639    private void start() {
2640        Process.removeAllProcessGroups();
2641        mProcessCpuThread.start();
2642
2643        mBatteryStatsService.publish(mContext);
2644        mAppOpsService.publish(mContext);
2645        Slog.d("AppOps", "AppOpsService published");
2646        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2647    }
2648
2649    void onUserStoppedLocked(int userId) {
2650        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2651    }
2652
2653    public void initPowerManagement() {
2654        mStackSupervisor.initPowerManagement();
2655        mBatteryStatsService.initPowerManagement();
2656        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2657        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2658        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2659        mVoiceWakeLock.setReferenceCounted(false);
2660    }
2661
2662    @Override
2663    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2664            throws RemoteException {
2665        if (code == SYSPROPS_TRANSACTION) {
2666            // We need to tell all apps about the system property change.
2667            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2668            synchronized(this) {
2669                final int NP = mProcessNames.getMap().size();
2670                for (int ip=0; ip<NP; ip++) {
2671                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2672                    final int NA = apps.size();
2673                    for (int ia=0; ia<NA; ia++) {
2674                        ProcessRecord app = apps.valueAt(ia);
2675                        if (app.thread != null) {
2676                            procs.add(app.thread.asBinder());
2677                        }
2678                    }
2679                }
2680            }
2681
2682            int N = procs.size();
2683            for (int i=0; i<N; i++) {
2684                Parcel data2 = Parcel.obtain();
2685                try {
2686                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2687                } catch (RemoteException e) {
2688                }
2689                data2.recycle();
2690            }
2691        }
2692        try {
2693            return super.onTransact(code, data, reply, flags);
2694        } catch (RuntimeException e) {
2695            // The activity manager only throws security exceptions, so let's
2696            // log all others.
2697            if (!(e instanceof SecurityException)) {
2698                Slog.wtf(TAG, "Activity Manager Crash", e);
2699            }
2700            throw e;
2701        }
2702    }
2703
2704    void updateCpuStats() {
2705        final long now = SystemClock.uptimeMillis();
2706        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2707            return;
2708        }
2709        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2710            synchronized (mProcessCpuThread) {
2711                mProcessCpuThread.notify();
2712            }
2713        }
2714    }
2715
2716    void updateCpuStatsNow() {
2717        synchronized (mProcessCpuTracker) {
2718            mProcessCpuMutexFree.set(false);
2719            final long now = SystemClock.uptimeMillis();
2720            boolean haveNewCpuStats = false;
2721
2722            if (MONITOR_CPU_USAGE &&
2723                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2724                mLastCpuTime.set(now);
2725                mProcessCpuTracker.update();
2726                if (mProcessCpuTracker.hasGoodLastStats()) {
2727                    haveNewCpuStats = true;
2728                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2729                    //Slog.i(TAG, "Total CPU usage: "
2730                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2731
2732                    // Slog the cpu usage if the property is set.
2733                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2734                        int user = mProcessCpuTracker.getLastUserTime();
2735                        int system = mProcessCpuTracker.getLastSystemTime();
2736                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2737                        int irq = mProcessCpuTracker.getLastIrqTime();
2738                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2739                        int idle = mProcessCpuTracker.getLastIdleTime();
2740
2741                        int total = user + system + iowait + irq + softIrq + idle;
2742                        if (total == 0) total = 1;
2743
2744                        EventLog.writeEvent(EventLogTags.CPU,
2745                                ((user+system+iowait+irq+softIrq) * 100) / total,
2746                                (user * 100) / total,
2747                                (system * 100) / total,
2748                                (iowait * 100) / total,
2749                                (irq * 100) / total,
2750                                (softIrq * 100) / total);
2751                    }
2752                }
2753            }
2754
2755            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2756            synchronized(bstats) {
2757                synchronized(mPidsSelfLocked) {
2758                    if (haveNewCpuStats) {
2759                        if (bstats.startAddingCpuLocked()) {
2760                            int totalUTime = 0;
2761                            int totalSTime = 0;
2762                            final int N = mProcessCpuTracker.countStats();
2763                            for (int i=0; i<N; i++) {
2764                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2765                                if (!st.working) {
2766                                    continue;
2767                                }
2768                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2769                                totalUTime += st.rel_utime;
2770                                totalSTime += st.rel_stime;
2771                                if (pr != null) {
2772                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2773                                    if (ps == null || !ps.isActive()) {
2774                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2775                                                pr.info.uid, pr.processName);
2776                                    }
2777                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2778                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2779                                } else {
2780                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2781                                    if (ps == null || !ps.isActive()) {
2782                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2783                                                bstats.mapUid(st.uid), st.name);
2784                                    }
2785                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2786                                }
2787                            }
2788                            final int userTime = mProcessCpuTracker.getLastUserTime();
2789                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2790                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2791                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2792                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2793                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2794                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2795                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2796                        }
2797                    }
2798                }
2799
2800                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2801                    mLastWriteTime = now;
2802                    mBatteryStatsService.scheduleWriteToDisk();
2803                }
2804            }
2805        }
2806    }
2807
2808    @Override
2809    public void batteryNeedsCpuUpdate() {
2810        updateCpuStatsNow();
2811    }
2812
2813    @Override
2814    public void batteryPowerChanged(boolean onBattery) {
2815        // When plugging in, update the CPU stats first before changing
2816        // the plug state.
2817        updateCpuStatsNow();
2818        synchronized (this) {
2819            synchronized(mPidsSelfLocked) {
2820                mOnBattery = DEBUG_POWER ? true : onBattery;
2821            }
2822        }
2823    }
2824
2825    @Override
2826    public void batterySendBroadcast(Intent intent) {
2827        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2828                AppOpsManager.OP_NONE, null, false, false,
2829                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2830    }
2831
2832    /**
2833     * Initialize the application bind args. These are passed to each
2834     * process when the bindApplication() IPC is sent to the process. They're
2835     * lazily setup to make sure the services are running when they're asked for.
2836     */
2837    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2838        if (mAppBindArgs == null) {
2839            mAppBindArgs = new HashMap<>();
2840
2841            // Isolated processes won't get this optimization, so that we don't
2842            // violate the rules about which services they have access to.
2843            if (!isolated) {
2844                // Setup the application init args
2845                mAppBindArgs.put("package", ServiceManager.getService("package"));
2846                mAppBindArgs.put("window", ServiceManager.getService("window"));
2847                mAppBindArgs.put(Context.ALARM_SERVICE,
2848                        ServiceManager.getService(Context.ALARM_SERVICE));
2849            }
2850        }
2851        return mAppBindArgs;
2852    }
2853
2854    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2855        if (r == null || mFocusedActivity == r) {
2856            return false;
2857        }
2858
2859        if (!r.isFocusable()) {
2860            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2861            return false;
2862        }
2863
2864        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2865
2866        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2867        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2868                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2869        mDoingSetFocusedActivity = true;
2870
2871        final ActivityRecord last = mFocusedActivity;
2872        mFocusedActivity = r;
2873        if (r.task.isApplicationTask()) {
2874            if (mCurAppTimeTracker != r.appTimeTracker) {
2875                // We are switching app tracking.  Complete the current one.
2876                if (mCurAppTimeTracker != null) {
2877                    mCurAppTimeTracker.stop();
2878                    mHandler.obtainMessage(
2879                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2880                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2881                    mCurAppTimeTracker = null;
2882                }
2883                if (r.appTimeTracker != null) {
2884                    mCurAppTimeTracker = r.appTimeTracker;
2885                    startTimeTrackingFocusedActivityLocked();
2886                }
2887            } else {
2888                startTimeTrackingFocusedActivityLocked();
2889            }
2890        } else {
2891            r.appTimeTracker = null;
2892        }
2893        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2894        // TODO: Probably not, because we don't want to resume voice on switching
2895        // back to this activity
2896        if (r.task.voiceInteractor != null) {
2897            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2898        } else {
2899            finishRunningVoiceLocked();
2900            IVoiceInteractionSession session;
2901            if (last != null && ((session = last.task.voiceSession) != null
2902                    || (session = last.voiceSession) != null)) {
2903                // We had been in a voice interaction session, but now focused has
2904                // move to something different.  Just finish the session, we can't
2905                // return to it and retain the proper state and synchronization with
2906                // the voice interaction service.
2907                finishVoiceTask(session);
2908            }
2909        }
2910        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2911            mWindowManager.setFocusedApp(r.appToken, true);
2912        }
2913        applyUpdateLockStateLocked(r);
2914        applyUpdateVrModeLocked(r);
2915        if (mFocusedActivity.userId != mLastFocusedUserId) {
2916            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2917            mHandler.obtainMessage(
2918                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2919            mLastFocusedUserId = mFocusedActivity.userId;
2920        }
2921
2922        // Log a warning if the focused app is changed during the process. This could
2923        // indicate a problem of the focus setting logic!
2924        if (mFocusedActivity != r) Slog.w(TAG,
2925                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2926        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2927
2928        EventLogTags.writeAmFocusedActivity(
2929                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2930                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2931                reason);
2932        return true;
2933    }
2934
2935    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2936        if (mFocusedActivity != goingAway) {
2937            return;
2938        }
2939
2940        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2941        if (focusedStack != null) {
2942            final ActivityRecord top = focusedStack.topActivity();
2943            if (top != null && top.userId != mLastFocusedUserId) {
2944                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2945                mHandler.sendMessage(
2946                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2947                mLastFocusedUserId = top.userId;
2948            }
2949        }
2950
2951        // Try to move focus to another activity if possible.
2952        if (setFocusedActivityLocked(
2953                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2954            return;
2955        }
2956
2957        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2958                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2959        mFocusedActivity = null;
2960        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2961    }
2962
2963    @Override
2964    public void setFocusedStack(int stackId) {
2965        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2966        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2967        final long callingId = Binder.clearCallingIdentity();
2968        try {
2969            synchronized (this) {
2970                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2971                if (stack == null) {
2972                    return;
2973                }
2974                final ActivityRecord r = stack.topRunningActivityLocked();
2975                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2976                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2977                }
2978            }
2979        } finally {
2980            Binder.restoreCallingIdentity(callingId);
2981        }
2982    }
2983
2984    @Override
2985    public void setFocusedTask(int taskId) {
2986        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2987        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2988        final long callingId = Binder.clearCallingIdentity();
2989        try {
2990            synchronized (this) {
2991                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2992                if (task == null) {
2993                    return;
2994                }
2995                final ActivityRecord r = task.topRunningActivityLocked();
2996                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2997                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2998                }
2999            }
3000        } finally {
3001            Binder.restoreCallingIdentity(callingId);
3002        }
3003    }
3004
3005    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3006    @Override
3007    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3008        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3009        synchronized (this) {
3010            if (listener != null) {
3011                mTaskStackListeners.register(listener);
3012            }
3013        }
3014    }
3015
3016    @Override
3017    public void notifyActivityDrawn(IBinder token) {
3018        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3019        synchronized (this) {
3020            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3021            if (r != null) {
3022                r.task.stack.notifyActivityDrawnLocked(r);
3023            }
3024        }
3025    }
3026
3027    final void applyUpdateLockStateLocked(ActivityRecord r) {
3028        // Modifications to the UpdateLock state are done on our handler, outside
3029        // the activity manager's locks.  The new state is determined based on the
3030        // state *now* of the relevant activity record.  The object is passed to
3031        // the handler solely for logging detail, not to be consulted/modified.
3032        final boolean nextState = r != null && r.immersive;
3033        mHandler.sendMessage(
3034                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3035    }
3036
3037    final void applyUpdateVrModeLocked(ActivityRecord r) {
3038        mHandler.sendMessage(
3039                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3040    }
3041
3042    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3043        mHandler.sendMessage(
3044                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3045    }
3046
3047    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3048        Message msg = Message.obtain();
3049        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3050        msg.obj = r.task.askedCompatMode ? null : r;
3051        mUiHandler.sendMessage(msg);
3052    }
3053
3054    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3055            String what, Object obj, ProcessRecord srcApp) {
3056        app.lastActivityTime = now;
3057
3058        if (app.activities.size() > 0) {
3059            // Don't want to touch dependent processes that are hosting activities.
3060            return index;
3061        }
3062
3063        int lrui = mLruProcesses.lastIndexOf(app);
3064        if (lrui < 0) {
3065            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3066                    + what + " " + obj + " from " + srcApp);
3067            return index;
3068        }
3069
3070        if (lrui >= index) {
3071            // Don't want to cause this to move dependent processes *back* in the
3072            // list as if they were less frequently used.
3073            return index;
3074        }
3075
3076        if (lrui >= mLruProcessActivityStart) {
3077            // Don't want to touch dependent processes that are hosting activities.
3078            return index;
3079        }
3080
3081        mLruProcesses.remove(lrui);
3082        if (index > 0) {
3083            index--;
3084        }
3085        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3086                + " in LRU list: " + app);
3087        mLruProcesses.add(index, app);
3088        return index;
3089    }
3090
3091    static void killProcessGroup(int uid, int pid) {
3092        if (sKillHandler != null) {
3093            sKillHandler.sendMessage(
3094                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3095        } else {
3096            Slog.w(TAG, "Asked to kill process group before system bringup!");
3097            Process.killProcessGroup(uid, pid);
3098        }
3099    }
3100
3101    final void removeLruProcessLocked(ProcessRecord app) {
3102        int lrui = mLruProcesses.lastIndexOf(app);
3103        if (lrui >= 0) {
3104            if (!app.killed) {
3105                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3106                Process.killProcessQuiet(app.pid);
3107                killProcessGroup(app.uid, app.pid);
3108            }
3109            if (lrui <= mLruProcessActivityStart) {
3110                mLruProcessActivityStart--;
3111            }
3112            if (lrui <= mLruProcessServiceStart) {
3113                mLruProcessServiceStart--;
3114            }
3115            mLruProcesses.remove(lrui);
3116        }
3117    }
3118
3119    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3120            ProcessRecord client) {
3121        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3122                || app.treatLikeActivity;
3123        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3124        if (!activityChange && hasActivity) {
3125            // The process has activities, so we are only allowing activity-based adjustments
3126            // to move it.  It should be kept in the front of the list with other
3127            // processes that have activities, and we don't want those to change their
3128            // order except due to activity operations.
3129            return;
3130        }
3131
3132        mLruSeq++;
3133        final long now = SystemClock.uptimeMillis();
3134        app.lastActivityTime = now;
3135
3136        // First a quick reject: if the app is already at the position we will
3137        // put it, then there is nothing to do.
3138        if (hasActivity) {
3139            final int N = mLruProcesses.size();
3140            if (N > 0 && mLruProcesses.get(N-1) == app) {
3141                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3142                return;
3143            }
3144        } else {
3145            if (mLruProcessServiceStart > 0
3146                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3147                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3148                return;
3149            }
3150        }
3151
3152        int lrui = mLruProcesses.lastIndexOf(app);
3153
3154        if (app.persistent && lrui >= 0) {
3155            // We don't care about the position of persistent processes, as long as
3156            // they are in the list.
3157            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3158            return;
3159        }
3160
3161        /* In progress: compute new position first, so we can avoid doing work
3162           if the process is not actually going to move.  Not yet working.
3163        int addIndex;
3164        int nextIndex;
3165        boolean inActivity = false, inService = false;
3166        if (hasActivity) {
3167            // Process has activities, put it at the very tipsy-top.
3168            addIndex = mLruProcesses.size();
3169            nextIndex = mLruProcessServiceStart;
3170            inActivity = true;
3171        } else if (hasService) {
3172            // Process has services, put it at the top of the service list.
3173            addIndex = mLruProcessActivityStart;
3174            nextIndex = mLruProcessServiceStart;
3175            inActivity = true;
3176            inService = true;
3177        } else  {
3178            // Process not otherwise of interest, it goes to the top of the non-service area.
3179            addIndex = mLruProcessServiceStart;
3180            if (client != null) {
3181                int clientIndex = mLruProcesses.lastIndexOf(client);
3182                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3183                        + app);
3184                if (clientIndex >= 0 && addIndex > clientIndex) {
3185                    addIndex = clientIndex;
3186                }
3187            }
3188            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3189        }
3190
3191        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3192                + mLruProcessActivityStart + "): " + app);
3193        */
3194
3195        if (lrui >= 0) {
3196            if (lrui < mLruProcessActivityStart) {
3197                mLruProcessActivityStart--;
3198            }
3199            if (lrui < mLruProcessServiceStart) {
3200                mLruProcessServiceStart--;
3201            }
3202            /*
3203            if (addIndex > lrui) {
3204                addIndex--;
3205            }
3206            if (nextIndex > lrui) {
3207                nextIndex--;
3208            }
3209            */
3210            mLruProcesses.remove(lrui);
3211        }
3212
3213        /*
3214        mLruProcesses.add(addIndex, app);
3215        if (inActivity) {
3216            mLruProcessActivityStart++;
3217        }
3218        if (inService) {
3219            mLruProcessActivityStart++;
3220        }
3221        */
3222
3223        int nextIndex;
3224        if (hasActivity) {
3225            final int N = mLruProcesses.size();
3226            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3227                // Process doesn't have activities, but has clients with
3228                // activities...  move it up, but one below the top (the top
3229                // should always have a real activity).
3230                if (DEBUG_LRU) Slog.d(TAG_LRU,
3231                        "Adding to second-top of LRU activity list: " + app);
3232                mLruProcesses.add(N - 1, app);
3233                // To keep it from spamming the LRU list (by making a bunch of clients),
3234                // we will push down any other entries owned by the app.
3235                final int uid = app.info.uid;
3236                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3237                    ProcessRecord subProc = mLruProcesses.get(i);
3238                    if (subProc.info.uid == uid) {
3239                        // We want to push this one down the list.  If the process after
3240                        // it is for the same uid, however, don't do so, because we don't
3241                        // want them internally to be re-ordered.
3242                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3243                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3244                                    "Pushing uid " + uid + " swapping at " + i + ": "
3245                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3246                            ProcessRecord tmp = mLruProcesses.get(i);
3247                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3248                            mLruProcesses.set(i - 1, tmp);
3249                            i--;
3250                        }
3251                    } else {
3252                        // A gap, we can stop here.
3253                        break;
3254                    }
3255                }
3256            } else {
3257                // Process has activities, put it at the very tipsy-top.
3258                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3259                mLruProcesses.add(app);
3260            }
3261            nextIndex = mLruProcessServiceStart;
3262        } else if (hasService) {
3263            // Process has services, put it at the top of the service list.
3264            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3265            mLruProcesses.add(mLruProcessActivityStart, app);
3266            nextIndex = mLruProcessServiceStart;
3267            mLruProcessActivityStart++;
3268        } else  {
3269            // Process not otherwise of interest, it goes to the top of the non-service area.
3270            int index = mLruProcessServiceStart;
3271            if (client != null) {
3272                // If there is a client, don't allow the process to be moved up higher
3273                // in the list than that client.
3274                int clientIndex = mLruProcesses.lastIndexOf(client);
3275                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3276                        + " when updating " + app);
3277                if (clientIndex <= lrui) {
3278                    // Don't allow the client index restriction to push it down farther in the
3279                    // list than it already is.
3280                    clientIndex = lrui;
3281                }
3282                if (clientIndex >= 0 && index > clientIndex) {
3283                    index = clientIndex;
3284                }
3285            }
3286            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3287            mLruProcesses.add(index, app);
3288            nextIndex = index-1;
3289            mLruProcessActivityStart++;
3290            mLruProcessServiceStart++;
3291        }
3292
3293        // If the app is currently using a content provider or service,
3294        // bump those processes as well.
3295        for (int j=app.connections.size()-1; j>=0; j--) {
3296            ConnectionRecord cr = app.connections.valueAt(j);
3297            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3298                    && cr.binding.service.app != null
3299                    && cr.binding.service.app.lruSeq != mLruSeq
3300                    && !cr.binding.service.app.persistent) {
3301                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3302                        "service connection", cr, app);
3303            }
3304        }
3305        for (int j=app.conProviders.size()-1; j>=0; j--) {
3306            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3307            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3308                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3309                        "provider reference", cpr, app);
3310            }
3311        }
3312    }
3313
3314    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3315        if (uid == Process.SYSTEM_UID) {
3316            // The system gets to run in any process.  If there are multiple
3317            // processes with the same uid, just pick the first (this
3318            // should never happen).
3319            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3320            if (procs == null) return null;
3321            final int procCount = procs.size();
3322            for (int i = 0; i < procCount; i++) {
3323                final int procUid = procs.keyAt(i);
3324                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3325                    // Don't use an app process or different user process for system component.
3326                    continue;
3327                }
3328                return procs.valueAt(i);
3329            }
3330        }
3331        ProcessRecord proc = mProcessNames.get(processName, uid);
3332        if (false && proc != null && !keepIfLarge
3333                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3334                && proc.lastCachedPss >= 4000) {
3335            // Turn this condition on to cause killing to happen regularly, for testing.
3336            if (proc.baseProcessTracker != null) {
3337                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3338            }
3339            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3340        } else if (proc != null && !keepIfLarge
3341                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3342                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3343            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3344            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3345                if (proc.baseProcessTracker != null) {
3346                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3347                }
3348                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3349            }
3350        }
3351        return proc;
3352    }
3353
3354    void notifyPackageUse(String packageName, int reason) {
3355        IPackageManager pm = AppGlobals.getPackageManager();
3356        try {
3357            pm.notifyPackageUse(packageName, reason);
3358        } catch (RemoteException e) {
3359        }
3360    }
3361
3362    boolean isNextTransitionForward() {
3363        int transit = mWindowManager.getPendingAppTransition();
3364        return transit == TRANSIT_ACTIVITY_OPEN
3365                || transit == TRANSIT_TASK_OPEN
3366                || transit == TRANSIT_TASK_TO_FRONT;
3367    }
3368
3369    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3370            String processName, String abiOverride, int uid, Runnable crashHandler) {
3371        synchronized(this) {
3372            ApplicationInfo info = new ApplicationInfo();
3373            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3374            // For isolated processes, the former contains the parent's uid and the latter the
3375            // actual uid of the isolated process.
3376            // In the special case introduced by this method (which is, starting an isolated
3377            // process directly from the SystemServer without an actual parent app process) the
3378            // closest thing to a parent's uid is SYSTEM_UID.
3379            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3380            // the |isolated| logic in the ProcessRecord constructor.
3381            info.uid = Process.SYSTEM_UID;
3382            info.processName = processName;
3383            info.className = entryPoint;
3384            info.packageName = "android";
3385            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3386                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3387                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3388                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3389                    crashHandler);
3390            return proc != null ? proc.pid : 0;
3391        }
3392    }
3393
3394    final ProcessRecord startProcessLocked(String processName,
3395            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3396            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3397            boolean isolated, boolean keepIfLarge) {
3398        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3399                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3400                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3401                null /* crashHandler */);
3402    }
3403
3404    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3405            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3406            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3407            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3408        long startTime = SystemClock.elapsedRealtime();
3409        ProcessRecord app;
3410        if (!isolated) {
3411            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3412            checkTime(startTime, "startProcess: after getProcessRecord");
3413
3414            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3415                // If we are in the background, then check to see if this process
3416                // is bad.  If so, we will just silently fail.
3417                if (mAppErrors.isBadProcessLocked(info)) {
3418                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3419                            + "/" + info.processName);
3420                    return null;
3421                }
3422            } else {
3423                // When the user is explicitly starting a process, then clear its
3424                // crash count so that we won't make it bad until they see at
3425                // least one crash dialog again, and make the process good again
3426                // if it had been bad.
3427                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3428                        + "/" + info.processName);
3429                mAppErrors.resetProcessCrashTimeLocked(info);
3430                if (mAppErrors.isBadProcessLocked(info)) {
3431                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3432                            UserHandle.getUserId(info.uid), info.uid,
3433                            info.processName);
3434                    mAppErrors.clearBadProcessLocked(info);
3435                    if (app != null) {
3436                        app.bad = false;
3437                    }
3438                }
3439            }
3440        } else {
3441            // If this is an isolated process, it can't re-use an existing process.
3442            app = null;
3443        }
3444
3445        // app launch boost for big.little configurations
3446        // use cpusets to migrate freshly launched tasks to big cores
3447        synchronized(ActivityManagerService.this) {
3448            nativeMigrateToBoost();
3449            mIsBoosted = true;
3450            mBoostStartTime = SystemClock.uptimeMillis();
3451            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3452            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3453        }
3454
3455        // We don't have to do anything more if:
3456        // (1) There is an existing application record; and
3457        // (2) The caller doesn't think it is dead, OR there is no thread
3458        //     object attached to it so we know it couldn't have crashed; and
3459        // (3) There is a pid assigned to it, so it is either starting or
3460        //     already running.
3461        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3462                + " app=" + app + " knownToBeDead=" + knownToBeDead
3463                + " thread=" + (app != null ? app.thread : null)
3464                + " pid=" + (app != null ? app.pid : -1));
3465        if (app != null && app.pid > 0) {
3466            if (!knownToBeDead || app.thread == null) {
3467                // We already have the app running, or are waiting for it to
3468                // come up (we have a pid but not yet its thread), so keep it.
3469                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3470                // If this is a new package in the process, add the package to the list
3471                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3472                checkTime(startTime, "startProcess: done, added package to proc");
3473                return app;
3474            }
3475
3476            // An application record is attached to a previous process,
3477            // clean it up now.
3478            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3479            checkTime(startTime, "startProcess: bad proc running, killing");
3480            killProcessGroup(app.uid, app.pid);
3481            handleAppDiedLocked(app, true, true);
3482            checkTime(startTime, "startProcess: done killing old proc");
3483        }
3484
3485        String hostingNameStr = hostingName != null
3486                ? hostingName.flattenToShortString() : null;
3487
3488        if (app == null) {
3489            checkTime(startTime, "startProcess: creating new process record");
3490            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3491            if (app == null) {
3492                Slog.w(TAG, "Failed making new process record for "
3493                        + processName + "/" + info.uid + " isolated=" + isolated);
3494                return null;
3495            }
3496            app.crashHandler = crashHandler;
3497            checkTime(startTime, "startProcess: done creating new process record");
3498        } else {
3499            // If this is a new package in the process, add the package to the list
3500            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3501            checkTime(startTime, "startProcess: added package to existing proc");
3502        }
3503
3504        // If the system is not ready yet, then hold off on starting this
3505        // process until it is.
3506        if (!mProcessesReady
3507                && !isAllowedWhileBooting(info)
3508                && !allowWhileBooting) {
3509            if (!mProcessesOnHold.contains(app)) {
3510                mProcessesOnHold.add(app);
3511            }
3512            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3513                    "System not ready, putting on hold: " + app);
3514            checkTime(startTime, "startProcess: returning with proc on hold");
3515            return app;
3516        }
3517
3518        checkTime(startTime, "startProcess: stepping in to startProcess");
3519        startProcessLocked(
3520                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3521        checkTime(startTime, "startProcess: done starting proc!");
3522        return (app.pid != 0) ? app : null;
3523    }
3524
3525    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3526        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3527    }
3528
3529    private final void startProcessLocked(ProcessRecord app,
3530            String hostingType, String hostingNameStr) {
3531        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3532                null /* entryPoint */, null /* entryPointArgs */);
3533    }
3534
3535    private final void startProcessLocked(ProcessRecord app, String hostingType,
3536            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3537        long startTime = SystemClock.elapsedRealtime();
3538        if (app.pid > 0 && app.pid != MY_PID) {
3539            checkTime(startTime, "startProcess: removing from pids map");
3540            synchronized (mPidsSelfLocked) {
3541                mPidsSelfLocked.remove(app.pid);
3542                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3543            }
3544            checkTime(startTime, "startProcess: done removing from pids map");
3545            app.setPid(0);
3546        }
3547
3548        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3549                "startProcessLocked removing on hold: " + app);
3550        mProcessesOnHold.remove(app);
3551
3552        checkTime(startTime, "startProcess: starting to update cpu stats");
3553        updateCpuStats();
3554        checkTime(startTime, "startProcess: done updating cpu stats");
3555
3556        try {
3557            try {
3558                final int userId = UserHandle.getUserId(app.uid);
3559                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3560            } catch (RemoteException e) {
3561                throw e.rethrowAsRuntimeException();
3562            }
3563
3564            int uid = app.uid;
3565            int[] gids = null;
3566            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3567            if (!app.isolated) {
3568                int[] permGids = null;
3569                try {
3570                    checkTime(startTime, "startProcess: getting gids from package manager");
3571                    final IPackageManager pm = AppGlobals.getPackageManager();
3572                    permGids = pm.getPackageGids(app.info.packageName,
3573                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3574                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3575                            MountServiceInternal.class);
3576                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3577                            app.info.packageName);
3578                } catch (RemoteException e) {
3579                    throw e.rethrowAsRuntimeException();
3580                }
3581
3582                /*
3583                 * Add shared application and profile GIDs so applications can share some
3584                 * resources like shared libraries and access user-wide resources
3585                 */
3586                if (ArrayUtils.isEmpty(permGids)) {
3587                    gids = new int[2];
3588                } else {
3589                    gids = new int[permGids.length + 2];
3590                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3591                }
3592                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3593                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3594            }
3595            checkTime(startTime, "startProcess: building args");
3596            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3597                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3598                        && mTopComponent != null
3599                        && app.processName.equals(mTopComponent.getPackageName())) {
3600                    uid = 0;
3601                }
3602                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3603                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3604                    uid = 0;
3605                }
3606            }
3607            int debugFlags = 0;
3608            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3609                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3610                // Also turn on CheckJNI for debuggable apps. It's quite
3611                // awkward to turn on otherwise.
3612                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3613            }
3614            // Run the app in safe mode if its manifest requests so or the
3615            // system is booted in safe mode.
3616            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3617                mSafeMode == true) {
3618                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3619            }
3620            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3621                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3622            }
3623            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3624            if ("true".equals(genDebugInfoProperty)) {
3625                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3626            }
3627            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3628                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3629            }
3630            if ("1".equals(SystemProperties.get("debug.assert"))) {
3631                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3632            }
3633            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3634                // Enable all debug flags required by the native debugger.
3635                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3636                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3637                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3638                mNativeDebuggingApp = null;
3639            }
3640
3641            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3642            if (requiredAbi == null) {
3643                requiredAbi = Build.SUPPORTED_ABIS[0];
3644            }
3645
3646            String instructionSet = null;
3647            if (app.info.primaryCpuAbi != null) {
3648                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3649            }
3650
3651            app.gids = gids;
3652            app.requiredAbi = requiredAbi;
3653            app.instructionSet = instructionSet;
3654
3655            // Start the process.  It will either succeed and return a result containing
3656            // the PID of the new process, or else throw a RuntimeException.
3657            boolean isActivityProcess = (entryPoint == null);
3658            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3659            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3660                    app.processName);
3661            checkTime(startTime, "startProcess: asking zygote to start proc");
3662            Process.ProcessStartResult startResult = Process.start(entryPoint,
3663                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3664                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3665                    app.info.dataDir, entryPointArgs);
3666            checkTime(startTime, "startProcess: returned from zygote!");
3667            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3668
3669            if (app.isolated) {
3670                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3671            }
3672            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3673            checkTime(startTime, "startProcess: done updating battery stats");
3674
3675            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3676                    UserHandle.getUserId(uid), startResult.pid, uid,
3677                    app.processName, hostingType,
3678                    hostingNameStr != null ? hostingNameStr : "");
3679
3680            try {
3681                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3682                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3683            } catch (RemoteException ex) {
3684                // Ignore
3685            }
3686
3687            if (app.persistent) {
3688                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3689            }
3690
3691            checkTime(startTime, "startProcess: building log message");
3692            StringBuilder buf = mStringBuilder;
3693            buf.setLength(0);
3694            buf.append("Start proc ");
3695            buf.append(startResult.pid);
3696            buf.append(':');
3697            buf.append(app.processName);
3698            buf.append('/');
3699            UserHandle.formatUid(buf, uid);
3700            if (!isActivityProcess) {
3701                buf.append(" [");
3702                buf.append(entryPoint);
3703                buf.append("]");
3704            }
3705            buf.append(" for ");
3706            buf.append(hostingType);
3707            if (hostingNameStr != null) {
3708                buf.append(" ");
3709                buf.append(hostingNameStr);
3710            }
3711            Slog.i(TAG, buf.toString());
3712            app.setPid(startResult.pid);
3713            app.usingWrapper = startResult.usingWrapper;
3714            app.removed = false;
3715            app.killed = false;
3716            app.killedByAm = false;
3717            checkTime(startTime, "startProcess: starting to update pids map");
3718            synchronized (mPidsSelfLocked) {
3719                this.mPidsSelfLocked.put(startResult.pid, app);
3720                if (isActivityProcess) {
3721                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3722                    msg.obj = app;
3723                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3724                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3725                }
3726            }
3727            checkTime(startTime, "startProcess: done updating pids map");
3728        } catch (RuntimeException e) {
3729            // XXX do better error recovery.
3730            app.setPid(0);
3731            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3732            if (app.isolated) {
3733                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3734            }
3735            Slog.e(TAG, "Failure starting process " + app.processName, e);
3736        }
3737    }
3738
3739    void updateUsageStats(ActivityRecord component, boolean resumed) {
3740        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3741                "updateUsageStats: comp=" + component + "res=" + resumed);
3742        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3743        if (resumed) {
3744            if (mUsageStatsService != null) {
3745                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3746                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3747            }
3748            synchronized (stats) {
3749                stats.noteActivityResumedLocked(component.app.uid);
3750            }
3751        } else {
3752            if (mUsageStatsService != null) {
3753                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3754                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3755            }
3756            synchronized (stats) {
3757                stats.noteActivityPausedLocked(component.app.uid);
3758            }
3759        }
3760    }
3761
3762    Intent getHomeIntent() {
3763        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3764        intent.setComponent(mTopComponent);
3765        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3766        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3767            intent.addCategory(Intent.CATEGORY_HOME);
3768        }
3769        return intent;
3770    }
3771
3772    boolean startHomeActivityLocked(int userId, String reason) {
3773        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3774                && mTopAction == null) {
3775            // We are running in factory test mode, but unable to find
3776            // the factory test app, so just sit around displaying the
3777            // error message and don't try to start anything.
3778            return false;
3779        }
3780        Intent intent = getHomeIntent();
3781        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3782        if (aInfo != null) {
3783            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3784            // Don't do this if the home app is currently being
3785            // instrumented.
3786            aInfo = new ActivityInfo(aInfo);
3787            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3788            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3789                    aInfo.applicationInfo.uid, true);
3790            if (app == null || app.instrumentationClass == null) {
3791                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3792                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3793            }
3794        }
3795
3796        return true;
3797    }
3798
3799    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3800        ActivityInfo ai = null;
3801        ComponentName comp = intent.getComponent();
3802        try {
3803            if (comp != null) {
3804                // Factory test.
3805                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3806            } else {
3807                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3808                        intent,
3809                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3810                        flags, userId);
3811
3812                if (info != null) {
3813                    ai = info.activityInfo;
3814                }
3815            }
3816        } catch (RemoteException e) {
3817            // ignore
3818        }
3819
3820        return ai;
3821    }
3822
3823    /**
3824     * Starts the "new version setup screen" if appropriate.
3825     */
3826    void startSetupActivityLocked() {
3827        // Only do this once per boot.
3828        if (mCheckedForSetup) {
3829            return;
3830        }
3831
3832        // We will show this screen if the current one is a different
3833        // version than the last one shown, and we are not running in
3834        // low-level factory test mode.
3835        final ContentResolver resolver = mContext.getContentResolver();
3836        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3837                Settings.Global.getInt(resolver,
3838                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3839            mCheckedForSetup = true;
3840
3841            // See if we should be showing the platform update setup UI.
3842            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3843            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3844                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3845            if (!ris.isEmpty()) {
3846                final ResolveInfo ri = ris.get(0);
3847                String vers = ri.activityInfo.metaData != null
3848                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3849                        : null;
3850                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3851                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3852                            Intent.METADATA_SETUP_VERSION);
3853                }
3854                String lastVers = Settings.Secure.getString(
3855                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3856                if (vers != null && !vers.equals(lastVers)) {
3857                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3858                    intent.setComponent(new ComponentName(
3859                            ri.activityInfo.packageName, ri.activityInfo.name));
3860                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3861                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3862                            null, 0, 0, 0, null, false, false, null, null, null);
3863                }
3864            }
3865        }
3866    }
3867
3868    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3869        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3870    }
3871
3872    void enforceNotIsolatedCaller(String caller) {
3873        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3874            throw new SecurityException("Isolated process not allowed to call " + caller);
3875        }
3876    }
3877
3878    void enforceShellRestriction(String restriction, int userHandle) {
3879        if (Binder.getCallingUid() == Process.SHELL_UID) {
3880            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3881                throw new SecurityException("Shell does not have permission to access user "
3882                        + userHandle);
3883            }
3884        }
3885    }
3886
3887    @Override
3888    public int getFrontActivityScreenCompatMode() {
3889        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3890        synchronized (this) {
3891            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3892        }
3893    }
3894
3895    @Override
3896    public void setFrontActivityScreenCompatMode(int mode) {
3897        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3898                "setFrontActivityScreenCompatMode");
3899        synchronized (this) {
3900            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3901        }
3902    }
3903
3904    @Override
3905    public int getPackageScreenCompatMode(String packageName) {
3906        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3907        synchronized (this) {
3908            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3909        }
3910    }
3911
3912    @Override
3913    public void setPackageScreenCompatMode(String packageName, int mode) {
3914        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3915                "setPackageScreenCompatMode");
3916        synchronized (this) {
3917            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3918        }
3919    }
3920
3921    @Override
3922    public boolean getPackageAskScreenCompat(String packageName) {
3923        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3924        synchronized (this) {
3925            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3926        }
3927    }
3928
3929    @Override
3930    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3931        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3932                "setPackageAskScreenCompat");
3933        synchronized (this) {
3934            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3935        }
3936    }
3937
3938    private boolean hasUsageStatsPermission(String callingPackage) {
3939        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3940                Binder.getCallingUid(), callingPackage);
3941        if (mode == AppOpsManager.MODE_DEFAULT) {
3942            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3943                    == PackageManager.PERMISSION_GRANTED;
3944        }
3945        return mode == AppOpsManager.MODE_ALLOWED;
3946    }
3947
3948    @Override
3949    public int getPackageProcessState(String packageName, String callingPackage) {
3950        if (!hasUsageStatsPermission(callingPackage)) {
3951            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3952                    "getPackageProcessState");
3953        }
3954
3955        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3956        synchronized (this) {
3957            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3958                final ProcessRecord proc = mLruProcesses.get(i);
3959                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3960                        || procState > proc.setProcState) {
3961                    boolean found = false;
3962                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3963                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3964                            procState = proc.setProcState;
3965                            found = true;
3966                        }
3967                    }
3968                    if (proc.pkgDeps != null && !found) {
3969                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3970                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3971                                procState = proc.setProcState;
3972                                break;
3973                            }
3974                        }
3975                    }
3976                }
3977            }
3978        }
3979        return procState;
3980    }
3981
3982    @Override
3983    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3984        synchronized (this) {
3985            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3986            if (app == null) {
3987                return false;
3988            }
3989            if (app.trimMemoryLevel < level && app.thread != null &&
3990                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3991                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3992                try {
3993                    app.thread.scheduleTrimMemory(level);
3994                    app.trimMemoryLevel = level;
3995                    return true;
3996                } catch (RemoteException e) {
3997                    // Fallthrough to failure case.
3998                }
3999            }
4000        }
4001        return false;
4002    }
4003
4004    private void dispatchProcessesChanged() {
4005        int N;
4006        synchronized (this) {
4007            N = mPendingProcessChanges.size();
4008            if (mActiveProcessChanges.length < N) {
4009                mActiveProcessChanges = new ProcessChangeItem[N];
4010            }
4011            mPendingProcessChanges.toArray(mActiveProcessChanges);
4012            mPendingProcessChanges.clear();
4013            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4014                    "*** Delivering " + N + " process changes");
4015        }
4016
4017        int i = mProcessObservers.beginBroadcast();
4018        while (i > 0) {
4019            i--;
4020            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4021            if (observer != null) {
4022                try {
4023                    for (int j=0; j<N; j++) {
4024                        ProcessChangeItem item = mActiveProcessChanges[j];
4025                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4026                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4027                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4028                                    + item.uid + ": " + item.foregroundActivities);
4029                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4030                                    item.foregroundActivities);
4031                        }
4032                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4033                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4034                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4035                                    + ": " + item.processState);
4036                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4037                        }
4038                    }
4039                } catch (RemoteException e) {
4040                }
4041            }
4042        }
4043        mProcessObservers.finishBroadcast();
4044
4045        synchronized (this) {
4046            for (int j=0; j<N; j++) {
4047                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4048            }
4049        }
4050    }
4051
4052    private void dispatchProcessDied(int pid, int uid) {
4053        int i = mProcessObservers.beginBroadcast();
4054        while (i > 0) {
4055            i--;
4056            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4057            if (observer != null) {
4058                try {
4059                    observer.onProcessDied(pid, uid);
4060                } catch (RemoteException e) {
4061                }
4062            }
4063        }
4064        mProcessObservers.finishBroadcast();
4065    }
4066
4067    private void dispatchUidsChanged() {
4068        int N;
4069        synchronized (this) {
4070            N = mPendingUidChanges.size();
4071            if (mActiveUidChanges.length < N) {
4072                mActiveUidChanges = new UidRecord.ChangeItem[N];
4073            }
4074            for (int i=0; i<N; i++) {
4075                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4076                mActiveUidChanges[i] = change;
4077                if (change.uidRecord != null) {
4078                    change.uidRecord.pendingChange = null;
4079                    change.uidRecord = null;
4080                }
4081            }
4082            mPendingUidChanges.clear();
4083            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4084                    "*** Delivering " + N + " uid changes");
4085        }
4086
4087        if (mLocalPowerManager != null) {
4088            for (int j=0; j<N; j++) {
4089                UidRecord.ChangeItem item = mActiveUidChanges[j];
4090                if (item.change == UidRecord.CHANGE_GONE
4091                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4092                    mLocalPowerManager.uidGone(item.uid);
4093                } else {
4094                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4095                }
4096            }
4097        }
4098
4099        int i = mUidObservers.beginBroadcast();
4100        while (i > 0) {
4101            i--;
4102            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4103            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4104            if (observer != null) {
4105                try {
4106                    for (int j=0; j<N; j++) {
4107                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4108                        final int change = item.change;
4109                        UidRecord validateUid = null;
4110                        if (VALIDATE_UID_STATES && i == 0) {
4111                            validateUid = mValidateUids.get(item.uid);
4112                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4113                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4114                                validateUid = new UidRecord(item.uid);
4115                                mValidateUids.put(item.uid, validateUid);
4116                            }
4117                        }
4118                        if (change == UidRecord.CHANGE_IDLE
4119                                || change == UidRecord.CHANGE_GONE_IDLE) {
4120                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4121                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4122                                        "UID idle uid=" + item.uid);
4123                                observer.onUidIdle(item.uid);
4124                            }
4125                            if (VALIDATE_UID_STATES && i == 0) {
4126                                if (validateUid != null) {
4127                                    validateUid.idle = true;
4128                                }
4129                            }
4130                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4131                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4132                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4133                                        "UID active uid=" + item.uid);
4134                                observer.onUidActive(item.uid);
4135                            }
4136                            if (VALIDATE_UID_STATES && i == 0) {
4137                                validateUid.idle = false;
4138                            }
4139                        }
4140                        if (change == UidRecord.CHANGE_GONE
4141                                || change == UidRecord.CHANGE_GONE_IDLE) {
4142                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4143                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4144                                        "UID gone uid=" + item.uid);
4145                                observer.onUidGone(item.uid);
4146                            }
4147                            if (VALIDATE_UID_STATES && i == 0) {
4148                                if (validateUid != null) {
4149                                    mValidateUids.remove(item.uid);
4150                                }
4151                            }
4152                        } else {
4153                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4154                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4155                                        "UID CHANGED uid=" + item.uid
4156                                                + ": " + item.processState);
4157                                observer.onUidStateChanged(item.uid, item.processState);
4158                            }
4159                            if (VALIDATE_UID_STATES && i == 0) {
4160                                validateUid.curProcState = validateUid.setProcState
4161                                        = item.processState;
4162                            }
4163                        }
4164                    }
4165                } catch (RemoteException e) {
4166                }
4167            }
4168        }
4169        mUidObservers.finishBroadcast();
4170
4171        synchronized (this) {
4172            for (int j=0; j<N; j++) {
4173                mAvailUidChanges.add(mActiveUidChanges[j]);
4174            }
4175        }
4176    }
4177
4178    @Override
4179    public final int startActivity(IApplicationThread caller, String callingPackage,
4180            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4181            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4182        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4183                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4184                UserHandle.getCallingUserId());
4185    }
4186
4187    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4188        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4189        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4190                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4191                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4192
4193        // TODO: Switch to user app stacks here.
4194        String mimeType = intent.getType();
4195        final Uri data = intent.getData();
4196        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4197            mimeType = getProviderMimeType(data, userId);
4198        }
4199        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4200
4201        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4202        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4203                null, 0, 0, null, null, null, null, false, userId, container, null);
4204    }
4205
4206    @Override
4207    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4208            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4209            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4210        enforceNotIsolatedCaller("startActivity");
4211        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4212                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4213        // TODO: Switch to user app stacks here.
4214        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4215                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4216                profilerInfo, null, null, bOptions, false, userId, null, null);
4217    }
4218
4219    @Override
4220    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4221            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4222            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4223            int userId) {
4224
4225        // This is very dangerous -- it allows you to perform a start activity (including
4226        // permission grants) as any app that may launch one of your own activities.  So
4227        // we will only allow this to be done from activities that are part of the core framework,
4228        // and then only when they are running as the system.
4229        final ActivityRecord sourceRecord;
4230        final int targetUid;
4231        final String targetPackage;
4232        synchronized (this) {
4233            if (resultTo == null) {
4234                throw new SecurityException("Must be called from an activity");
4235            }
4236            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4237            if (sourceRecord == null) {
4238                throw new SecurityException("Called with bad activity token: " + resultTo);
4239            }
4240            if (!sourceRecord.info.packageName.equals("android")) {
4241                throw new SecurityException(
4242                        "Must be called from an activity that is declared in the android package");
4243            }
4244            if (sourceRecord.app == null) {
4245                throw new SecurityException("Called without a process attached to activity");
4246            }
4247            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4248                // This is still okay, as long as this activity is running under the
4249                // uid of the original calling activity.
4250                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4251                    throw new SecurityException(
4252                            "Calling activity in uid " + sourceRecord.app.uid
4253                                    + " must be system uid or original calling uid "
4254                                    + sourceRecord.launchedFromUid);
4255                }
4256            }
4257            if (ignoreTargetSecurity) {
4258                if (intent.getComponent() == null) {
4259                    throw new SecurityException(
4260                            "Component must be specified with ignoreTargetSecurity");
4261                }
4262                if (intent.getSelector() != null) {
4263                    throw new SecurityException(
4264                            "Selector not allowed with ignoreTargetSecurity");
4265                }
4266            }
4267            targetUid = sourceRecord.launchedFromUid;
4268            targetPackage = sourceRecord.launchedFromPackage;
4269        }
4270
4271        if (userId == UserHandle.USER_NULL) {
4272            userId = UserHandle.getUserId(sourceRecord.app.uid);
4273        }
4274
4275        // TODO: Switch to user app stacks here.
4276        try {
4277            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4278                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4279                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4280            return ret;
4281        } catch (SecurityException e) {
4282            // XXX need to figure out how to propagate to original app.
4283            // A SecurityException here is generally actually a fault of the original
4284            // calling activity (such as a fairly granting permissions), so propagate it
4285            // back to them.
4286            /*
4287            StringBuilder msg = new StringBuilder();
4288            msg.append("While launching");
4289            msg.append(intent.toString());
4290            msg.append(": ");
4291            msg.append(e.getMessage());
4292            */
4293            throw e;
4294        }
4295    }
4296
4297    @Override
4298    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4299            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4300            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4301        enforceNotIsolatedCaller("startActivityAndWait");
4302        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4303                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4304        WaitResult res = new WaitResult();
4305        // TODO: Switch to user app stacks here.
4306        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4307                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4308                bOptions, false, userId, null, null);
4309        return res;
4310    }
4311
4312    @Override
4313    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4314            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4315            int startFlags, Configuration config, Bundle bOptions, int userId) {
4316        enforceNotIsolatedCaller("startActivityWithConfig");
4317        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4318                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4319        // TODO: Switch to user app stacks here.
4320        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4321                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4322                null, null, config, bOptions, false, userId, null, null);
4323        return ret;
4324    }
4325
4326    @Override
4327    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4328            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4329            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4330            throws TransactionTooLargeException {
4331        enforceNotIsolatedCaller("startActivityIntentSender");
4332        // Refuse possible leaked file descriptors
4333        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4334            throw new IllegalArgumentException("File descriptors passed in Intent");
4335        }
4336
4337        IIntentSender sender = intent.getTarget();
4338        if (!(sender instanceof PendingIntentRecord)) {
4339            throw new IllegalArgumentException("Bad PendingIntent object");
4340        }
4341
4342        PendingIntentRecord pir = (PendingIntentRecord)sender;
4343
4344        synchronized (this) {
4345            // If this is coming from the currently resumed activity, it is
4346            // effectively saying that app switches are allowed at this point.
4347            final ActivityStack stack = getFocusedStack();
4348            if (stack.mResumedActivity != null &&
4349                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4350                mAppSwitchesAllowedTime = 0;
4351            }
4352        }
4353        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4354                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4355        return ret;
4356    }
4357
4358    @Override
4359    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4360            Intent intent, String resolvedType, IVoiceInteractionSession session,
4361            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4362            Bundle bOptions, int userId) {
4363        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4364                != PackageManager.PERMISSION_GRANTED) {
4365            String msg = "Permission Denial: startVoiceActivity() from pid="
4366                    + Binder.getCallingPid()
4367                    + ", uid=" + Binder.getCallingUid()
4368                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4369            Slog.w(TAG, msg);
4370            throw new SecurityException(msg);
4371        }
4372        if (session == null || interactor == null) {
4373            throw new NullPointerException("null session or interactor");
4374        }
4375        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4376                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4377        // TODO: Switch to user app stacks here.
4378        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4379                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4380                null, bOptions, false, userId, null, null);
4381    }
4382
4383    @Override
4384    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4385            throws RemoteException {
4386        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4387        synchronized (this) {
4388            ActivityRecord activity = getFocusedStack().topActivity();
4389            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4390                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4391            }
4392            if (mRunningVoice != null || activity.task.voiceSession != null
4393                    || activity.voiceSession != null) {
4394                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4395                return;
4396            }
4397            if (activity.pendingVoiceInteractionStart) {
4398                Slog.w(TAG, "Pending start of voice interaction already.");
4399                return;
4400            }
4401            activity.pendingVoiceInteractionStart = true;
4402        }
4403        LocalServices.getService(VoiceInteractionManagerInternal.class)
4404                .startLocalVoiceInteraction(callingActivity, options);
4405    }
4406
4407    @Override
4408    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4409        LocalServices.getService(VoiceInteractionManagerInternal.class)
4410                .stopLocalVoiceInteraction(callingActivity);
4411    }
4412
4413    @Override
4414    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4415        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4416                .supportsLocalVoiceInteraction();
4417    }
4418
4419    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4420            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4421        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4422        if (activityToCallback == null) return;
4423        activityToCallback.setVoiceSessionLocked(voiceSession);
4424
4425        // Inform the activity
4426        try {
4427            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4428                    voiceInteractor);
4429            long token = Binder.clearCallingIdentity();
4430            try {
4431                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4432            } finally {
4433                Binder.restoreCallingIdentity(token);
4434            }
4435            // TODO: VI Should we cache the activity so that it's easier to find later
4436            // rather than scan through all the stacks and activities?
4437        } catch (RemoteException re) {
4438            activityToCallback.clearVoiceSessionLocked();
4439            // TODO: VI Should this terminate the voice session?
4440        }
4441    }
4442
4443    @Override
4444    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4445        synchronized (this) {
4446            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4447                if (keepAwake) {
4448                    mVoiceWakeLock.acquire();
4449                } else {
4450                    mVoiceWakeLock.release();
4451                }
4452            }
4453        }
4454    }
4455
4456    @Override
4457    public boolean startNextMatchingActivity(IBinder callingActivity,
4458            Intent intent, Bundle bOptions) {
4459        // Refuse possible leaked file descriptors
4460        if (intent != null && intent.hasFileDescriptors() == true) {
4461            throw new IllegalArgumentException("File descriptors passed in Intent");
4462        }
4463        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4464
4465        synchronized (this) {
4466            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4467            if (r == null) {
4468                ActivityOptions.abort(options);
4469                return false;
4470            }
4471            if (r.app == null || r.app.thread == null) {
4472                // The caller is not running...  d'oh!
4473                ActivityOptions.abort(options);
4474                return false;
4475            }
4476            intent = new Intent(intent);
4477            // The caller is not allowed to change the data.
4478            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4479            // And we are resetting to find the next component...
4480            intent.setComponent(null);
4481
4482            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4483
4484            ActivityInfo aInfo = null;
4485            try {
4486                List<ResolveInfo> resolves =
4487                    AppGlobals.getPackageManager().queryIntentActivities(
4488                            intent, r.resolvedType,
4489                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4490                            UserHandle.getCallingUserId()).getList();
4491
4492                // Look for the original activity in the list...
4493                final int N = resolves != null ? resolves.size() : 0;
4494                for (int i=0; i<N; i++) {
4495                    ResolveInfo rInfo = resolves.get(i);
4496                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4497                            && rInfo.activityInfo.name.equals(r.info.name)) {
4498                        // We found the current one...  the next matching is
4499                        // after it.
4500                        i++;
4501                        if (i<N) {
4502                            aInfo = resolves.get(i).activityInfo;
4503                        }
4504                        if (debug) {
4505                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4506                                    + "/" + r.info.name);
4507                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4508                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4509                        }
4510                        break;
4511                    }
4512                }
4513            } catch (RemoteException e) {
4514            }
4515
4516            if (aInfo == null) {
4517                // Nobody who is next!
4518                ActivityOptions.abort(options);
4519                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4520                return false;
4521            }
4522
4523            intent.setComponent(new ComponentName(
4524                    aInfo.applicationInfo.packageName, aInfo.name));
4525            intent.setFlags(intent.getFlags()&~(
4526                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4527                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4528                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4529                    Intent.FLAG_ACTIVITY_NEW_TASK));
4530
4531            // Okay now we need to start the new activity, replacing the
4532            // currently running activity.  This is a little tricky because
4533            // we want to start the new one as if the current one is finished,
4534            // but not finish the current one first so that there is no flicker.
4535            // And thus...
4536            final boolean wasFinishing = r.finishing;
4537            r.finishing = true;
4538
4539            // Propagate reply information over to the new activity.
4540            final ActivityRecord resultTo = r.resultTo;
4541            final String resultWho = r.resultWho;
4542            final int requestCode = r.requestCode;
4543            r.resultTo = null;
4544            if (resultTo != null) {
4545                resultTo.removeResultsLocked(r, resultWho, requestCode);
4546            }
4547
4548            final long origId = Binder.clearCallingIdentity();
4549            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4550                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4551                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4552                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4553                    false, false, null, null, null);
4554            Binder.restoreCallingIdentity(origId);
4555
4556            r.finishing = wasFinishing;
4557            if (res != ActivityManager.START_SUCCESS) {
4558                return false;
4559            }
4560            return true;
4561        }
4562    }
4563
4564    @Override
4565    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4566        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4567            String msg = "Permission Denial: startActivityFromRecents called without " +
4568                    START_TASKS_FROM_RECENTS;
4569            Slog.w(TAG, msg);
4570            throw new SecurityException(msg);
4571        }
4572        final long origId = Binder.clearCallingIdentity();
4573        try {
4574            synchronized (this) {
4575                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4576            }
4577        } finally {
4578            Binder.restoreCallingIdentity(origId);
4579        }
4580    }
4581
4582    final int startActivityInPackage(int uid, String callingPackage,
4583            Intent intent, String resolvedType, IBinder resultTo,
4584            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4585            IActivityContainer container, TaskRecord inTask) {
4586
4587        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4588                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4589
4590        // TODO: Switch to user app stacks here.
4591        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4592                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4593                null, null, null, bOptions, false, userId, container, inTask);
4594        return ret;
4595    }
4596
4597    @Override
4598    public final int startActivities(IApplicationThread caller, String callingPackage,
4599            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4600            int userId) {
4601        enforceNotIsolatedCaller("startActivities");
4602        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4603                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4604        // TODO: Switch to user app stacks here.
4605        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4606                resolvedTypes, resultTo, bOptions, userId);
4607        return ret;
4608    }
4609
4610    final int startActivitiesInPackage(int uid, String callingPackage,
4611            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4612            Bundle bOptions, int userId) {
4613
4614        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4615                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4616        // TODO: Switch to user app stacks here.
4617        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4618                resultTo, bOptions, userId);
4619        return ret;
4620    }
4621
4622    @Override
4623    public void reportActivityFullyDrawn(IBinder token) {
4624        synchronized (this) {
4625            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4626            if (r == null) {
4627                return;
4628            }
4629            r.reportFullyDrawnLocked();
4630        }
4631    }
4632
4633    @Override
4634    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4635        synchronized (this) {
4636            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4637            if (r == null) {
4638                return;
4639            }
4640            TaskRecord task = r.task;
4641            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4642                // Fixed screen orientation isn't supported when activities aren't in full screen
4643                // mode.
4644                return;
4645            }
4646            final long origId = Binder.clearCallingIdentity();
4647            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4648            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4649                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4650            if (config != null) {
4651                r.frozenBeforeDestroy = true;
4652                if (!updateConfigurationLocked(config, r, false)) {
4653                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4654                }
4655            }
4656            Binder.restoreCallingIdentity(origId);
4657        }
4658    }
4659
4660    @Override
4661    public int getRequestedOrientation(IBinder token) {
4662        synchronized (this) {
4663            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4664            if (r == null) {
4665                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4666            }
4667            return mWindowManager.getAppOrientation(r.appToken);
4668        }
4669    }
4670
4671    /**
4672     * This is the internal entry point for handling Activity.finish().
4673     *
4674     * @param token The Binder token referencing the Activity we want to finish.
4675     * @param resultCode Result code, if any, from this Activity.
4676     * @param resultData Result data (Intent), if any, from this Activity.
4677     * @param finishTask Whether to finish the task associated with this Activity.
4678     *
4679     * @return Returns true if the activity successfully finished, or false if it is still running.
4680     */
4681    @Override
4682    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4683            int finishTask) {
4684        // Refuse possible leaked file descriptors
4685        if (resultData != null && resultData.hasFileDescriptors() == true) {
4686            throw new IllegalArgumentException("File descriptors passed in Intent");
4687        }
4688
4689        synchronized(this) {
4690            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4691            if (r == null) {
4692                return true;
4693            }
4694            // Keep track of the root activity of the task before we finish it
4695            TaskRecord tr = r.task;
4696            ActivityRecord rootR = tr.getRootActivity();
4697            if (rootR == null) {
4698                Slog.w(TAG, "Finishing task with all activities already finished");
4699            }
4700            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4701            // finish.
4702            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4703                    mStackSupervisor.isLastLockedTask(tr)) {
4704                Slog.i(TAG, "Not finishing task in lock task mode");
4705                mStackSupervisor.showLockTaskToast();
4706                return false;
4707            }
4708            if (mController != null) {
4709                // Find the first activity that is not finishing.
4710                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4711                if (next != null) {
4712                    // ask watcher if this is allowed
4713                    boolean resumeOK = true;
4714                    try {
4715                        resumeOK = mController.activityResuming(next.packageName);
4716                    } catch (RemoteException e) {
4717                        mController = null;
4718                        Watchdog.getInstance().setActivityController(null);
4719                    }
4720
4721                    if (!resumeOK) {
4722                        Slog.i(TAG, "Not finishing activity because controller resumed");
4723                        return false;
4724                    }
4725                }
4726            }
4727            final long origId = Binder.clearCallingIdentity();
4728            try {
4729                boolean res;
4730                final boolean finishWithRootActivity =
4731                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4732                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4733                        || (finishWithRootActivity && r == rootR)) {
4734                    // If requested, remove the task that is associated to this activity only if it
4735                    // was the root activity in the task. The result code and data is ignored
4736                    // because we don't support returning them across task boundaries. Also, to
4737                    // keep backwards compatibility we remove the task from recents when finishing
4738                    // task with root activity.
4739                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4740                    if (!res) {
4741                        Slog.i(TAG, "Removing task failed to finish activity");
4742                    }
4743                } else {
4744                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4745                            resultData, "app-request", true);
4746                    if (!res) {
4747                        Slog.i(TAG, "Failed to finish by app-request");
4748                    }
4749                }
4750                return res;
4751            } finally {
4752                Binder.restoreCallingIdentity(origId);
4753            }
4754        }
4755    }
4756
4757    @Override
4758    public final void finishHeavyWeightApp() {
4759        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4760                != PackageManager.PERMISSION_GRANTED) {
4761            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4762                    + Binder.getCallingPid()
4763                    + ", uid=" + Binder.getCallingUid()
4764                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4765            Slog.w(TAG, msg);
4766            throw new SecurityException(msg);
4767        }
4768
4769        synchronized(this) {
4770            if (mHeavyWeightProcess == null) {
4771                return;
4772            }
4773
4774            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4775            for (int i = 0; i < activities.size(); i++) {
4776                ActivityRecord r = activities.get(i);
4777                if (!r.finishing && r.isInStackLocked()) {
4778                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4779                            null, "finish-heavy", true);
4780                }
4781            }
4782
4783            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4784                    mHeavyWeightProcess.userId, 0));
4785            mHeavyWeightProcess = null;
4786        }
4787    }
4788
4789    @Override
4790    public void crashApplication(int uid, int initialPid, String packageName,
4791            String message) {
4792        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4793                != PackageManager.PERMISSION_GRANTED) {
4794            String msg = "Permission Denial: crashApplication() from pid="
4795                    + Binder.getCallingPid()
4796                    + ", uid=" + Binder.getCallingUid()
4797                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4798            Slog.w(TAG, msg);
4799            throw new SecurityException(msg);
4800        }
4801
4802        synchronized(this) {
4803            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4804        }
4805    }
4806
4807    @Override
4808    public final void finishSubActivity(IBinder token, String resultWho,
4809            int requestCode) {
4810        synchronized(this) {
4811            final long origId = Binder.clearCallingIdentity();
4812            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4813            if (r != null) {
4814                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4815            }
4816            Binder.restoreCallingIdentity(origId);
4817        }
4818    }
4819
4820    @Override
4821    public boolean finishActivityAffinity(IBinder token) {
4822        synchronized(this) {
4823            final long origId = Binder.clearCallingIdentity();
4824            try {
4825                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4826                if (r == null) {
4827                    return false;
4828                }
4829
4830                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4831                // can finish.
4832                final TaskRecord task = r.task;
4833                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4834                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4835                    mStackSupervisor.showLockTaskToast();
4836                    return false;
4837                }
4838                return task.stack.finishActivityAffinityLocked(r);
4839            } finally {
4840                Binder.restoreCallingIdentity(origId);
4841            }
4842        }
4843    }
4844
4845    @Override
4846    public void finishVoiceTask(IVoiceInteractionSession session) {
4847        synchronized (this) {
4848            final long origId = Binder.clearCallingIdentity();
4849            try {
4850                // TODO: VI Consider treating local voice interactions and voice tasks
4851                // differently here
4852                mStackSupervisor.finishVoiceTask(session);
4853            } finally {
4854                Binder.restoreCallingIdentity(origId);
4855            }
4856        }
4857
4858    }
4859
4860    @Override
4861    public boolean releaseActivityInstance(IBinder token) {
4862        synchronized(this) {
4863            final long origId = Binder.clearCallingIdentity();
4864            try {
4865                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4866                if (r == null) {
4867                    return false;
4868                }
4869                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4870            } finally {
4871                Binder.restoreCallingIdentity(origId);
4872            }
4873        }
4874    }
4875
4876    @Override
4877    public void releaseSomeActivities(IApplicationThread appInt) {
4878        synchronized(this) {
4879            final long origId = Binder.clearCallingIdentity();
4880            try {
4881                ProcessRecord app = getRecordForAppLocked(appInt);
4882                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4883            } finally {
4884                Binder.restoreCallingIdentity(origId);
4885            }
4886        }
4887    }
4888
4889    @Override
4890    public boolean willActivityBeVisible(IBinder token) {
4891        synchronized(this) {
4892            ActivityStack stack = ActivityRecord.getStackLocked(token);
4893            if (stack != null) {
4894                return stack.willActivityBeVisibleLocked(token);
4895            }
4896            return false;
4897        }
4898    }
4899
4900    @Override
4901    public void overridePendingTransition(IBinder token, String packageName,
4902            int enterAnim, int exitAnim) {
4903        synchronized(this) {
4904            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4905            if (self == null) {
4906                return;
4907            }
4908
4909            final long origId = Binder.clearCallingIdentity();
4910
4911            if (self.state == ActivityState.RESUMED
4912                    || self.state == ActivityState.PAUSING) {
4913                mWindowManager.overridePendingAppTransition(packageName,
4914                        enterAnim, exitAnim, null);
4915            }
4916
4917            Binder.restoreCallingIdentity(origId);
4918        }
4919    }
4920
4921    /**
4922     * Main function for removing an existing process from the activity manager
4923     * as a result of that process going away.  Clears out all connections
4924     * to the process.
4925     */
4926    private final void handleAppDiedLocked(ProcessRecord app,
4927            boolean restarting, boolean allowRestart) {
4928        int pid = app.pid;
4929        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4930        if (!kept && !restarting) {
4931            removeLruProcessLocked(app);
4932            if (pid > 0) {
4933                ProcessList.remove(pid);
4934            }
4935        }
4936
4937        if (mProfileProc == app) {
4938            clearProfilerLocked();
4939        }
4940
4941        // Remove this application's activities from active lists.
4942        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4943
4944        app.activities.clear();
4945
4946        if (app.instrumentationClass != null) {
4947            Slog.w(TAG, "Crash of app " + app.processName
4948                  + " running instrumentation " + app.instrumentationClass);
4949            Bundle info = new Bundle();
4950            info.putString("shortMsg", "Process crashed.");
4951            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4952        }
4953
4954        if (!restarting && hasVisibleActivities
4955                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4956            // If there was nothing to resume, and we are not already restarting this process, but
4957            // there is a visible activity that is hosted by the process...  then make sure all
4958            // visible activities are running, taking care of restarting this process.
4959            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4960        }
4961    }
4962
4963    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4964        IBinder threadBinder = thread.asBinder();
4965        // Find the application record.
4966        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4967            ProcessRecord rec = mLruProcesses.get(i);
4968            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4969                return i;
4970            }
4971        }
4972        return -1;
4973    }
4974
4975    final ProcessRecord getRecordForAppLocked(
4976            IApplicationThread thread) {
4977        if (thread == null) {
4978            return null;
4979        }
4980
4981        int appIndex = getLRURecordIndexForAppLocked(thread);
4982        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4983    }
4984
4985    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4986        // If there are no longer any background processes running,
4987        // and the app that died was not running instrumentation,
4988        // then tell everyone we are now low on memory.
4989        boolean haveBg = false;
4990        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4991            ProcessRecord rec = mLruProcesses.get(i);
4992            if (rec.thread != null
4993                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4994                haveBg = true;
4995                break;
4996            }
4997        }
4998
4999        if (!haveBg) {
5000            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5001            if (doReport) {
5002                long now = SystemClock.uptimeMillis();
5003                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5004                    doReport = false;
5005                } else {
5006                    mLastMemUsageReportTime = now;
5007                }
5008            }
5009            final ArrayList<ProcessMemInfo> memInfos
5010                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5011            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5012            long now = SystemClock.uptimeMillis();
5013            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5014                ProcessRecord rec = mLruProcesses.get(i);
5015                if (rec == dyingProc || rec.thread == null) {
5016                    continue;
5017                }
5018                if (doReport) {
5019                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5020                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5021                }
5022                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5023                    // The low memory report is overriding any current
5024                    // state for a GC request.  Make sure to do
5025                    // heavy/important/visible/foreground processes first.
5026                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5027                        rec.lastRequestedGc = 0;
5028                    } else {
5029                        rec.lastRequestedGc = rec.lastLowMemory;
5030                    }
5031                    rec.reportLowMemory = true;
5032                    rec.lastLowMemory = now;
5033                    mProcessesToGc.remove(rec);
5034                    addProcessToGcListLocked(rec);
5035                }
5036            }
5037            if (doReport) {
5038                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5039                mHandler.sendMessage(msg);
5040            }
5041            scheduleAppGcsLocked();
5042        }
5043    }
5044
5045    final void appDiedLocked(ProcessRecord app) {
5046       appDiedLocked(app, app.pid, app.thread, false);
5047    }
5048
5049    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5050            boolean fromBinderDied) {
5051        // First check if this ProcessRecord is actually active for the pid.
5052        synchronized (mPidsSelfLocked) {
5053            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5054            if (curProc != app) {
5055                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5056                return;
5057            }
5058        }
5059
5060        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5061        synchronized (stats) {
5062            stats.noteProcessDiedLocked(app.info.uid, pid);
5063        }
5064
5065        if (!app.killed) {
5066            if (!fromBinderDied) {
5067                Process.killProcessQuiet(pid);
5068            }
5069            killProcessGroup(app.uid, pid);
5070            app.killed = true;
5071        }
5072
5073        // Clean up already done if the process has been re-started.
5074        if (app.pid == pid && app.thread != null &&
5075                app.thread.asBinder() == thread.asBinder()) {
5076            boolean doLowMem = app.instrumentationClass == null;
5077            boolean doOomAdj = doLowMem;
5078            if (!app.killedByAm) {
5079                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5080                        + ") has died");
5081                mAllowLowerMemLevel = true;
5082            } else {
5083                // Note that we always want to do oom adj to update our state with the
5084                // new number of procs.
5085                mAllowLowerMemLevel = false;
5086                doLowMem = false;
5087            }
5088            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5089            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5090                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5091            handleAppDiedLocked(app, false, true);
5092
5093            if (doOomAdj) {
5094                updateOomAdjLocked();
5095            }
5096            if (doLowMem) {
5097                doLowMemReportIfNeededLocked(app);
5098            }
5099        } else if (app.pid != pid) {
5100            // A new process has already been started.
5101            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5102                    + ") has died and restarted (pid " + app.pid + ").");
5103            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5104        } else if (DEBUG_PROCESSES) {
5105            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5106                    + thread.asBinder());
5107        }
5108    }
5109
5110    /**
5111     * If a stack trace dump file is configured, dump process stack traces.
5112     * @param clearTraces causes the dump file to be erased prior to the new
5113     *    traces being written, if true; when false, the new traces will be
5114     *    appended to any existing file content.
5115     * @param firstPids of dalvik VM processes to dump stack traces for first
5116     * @param lastPids of dalvik VM processes to dump stack traces for last
5117     * @param nativeProcs optional list of native process names to dump stack crawls
5118     * @return file containing stack traces, or null if no dump file is configured
5119     */
5120    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5121            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5122        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5123        if (tracesPath == null || tracesPath.length() == 0) {
5124            return null;
5125        }
5126
5127        File tracesFile = new File(tracesPath);
5128        try {
5129            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5130            tracesFile.createNewFile();
5131            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5132        } catch (IOException e) {
5133            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5134            return null;
5135        }
5136
5137        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5138        return tracesFile;
5139    }
5140
5141    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5142            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5143        // Use a FileObserver to detect when traces finish writing.
5144        // The order of traces is considered important to maintain for legibility.
5145        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5146            @Override
5147            public synchronized void onEvent(int event, String path) { notify(); }
5148        };
5149
5150        try {
5151            observer.startWatching();
5152
5153            // First collect all of the stacks of the most important pids.
5154            if (firstPids != null) {
5155                try {
5156                    int num = firstPids.size();
5157                    for (int i = 0; i < num; i++) {
5158                        synchronized (observer) {
5159                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5160                                    + firstPids.get(i));
5161                            final long sime = SystemClock.elapsedRealtime();
5162                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5163                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5164                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5165                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5166                        }
5167                    }
5168                } catch (InterruptedException e) {
5169                    Slog.wtf(TAG, e);
5170                }
5171            }
5172
5173            // Next collect the stacks of the native pids
5174            if (nativeProcs != null) {
5175                int[] pids = Process.getPidsForCommands(nativeProcs);
5176                if (pids != null) {
5177                    for (int pid : pids) {
5178                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5179                        final long sime = SystemClock.elapsedRealtime();
5180                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5181                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5182                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5183                    }
5184                }
5185            }
5186
5187            // Lastly, measure CPU usage.
5188            if (processCpuTracker != null) {
5189                processCpuTracker.init();
5190                System.gc();
5191                processCpuTracker.update();
5192                try {
5193                    synchronized (processCpuTracker) {
5194                        processCpuTracker.wait(500); // measure over 1/2 second.
5195                    }
5196                } catch (InterruptedException e) {
5197                }
5198                processCpuTracker.update();
5199
5200                // We'll take the stack crawls of just the top apps using CPU.
5201                final int N = processCpuTracker.countWorkingStats();
5202                int numProcs = 0;
5203                for (int i=0; i<N && numProcs<5; i++) {
5204                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5205                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5206                        numProcs++;
5207                        try {
5208                            synchronized (observer) {
5209                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5210                                        + stats.pid);
5211                                final long stime = SystemClock.elapsedRealtime();
5212                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5213                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5214                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5215                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5216                            }
5217                        } catch (InterruptedException e) {
5218                            Slog.wtf(TAG, e);
5219                        }
5220                    } else if (DEBUG_ANR) {
5221                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5222                                + stats.pid);
5223                    }
5224                }
5225            }
5226        } finally {
5227            observer.stopWatching();
5228        }
5229    }
5230
5231    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5232        if (true || IS_USER_BUILD) {
5233            return;
5234        }
5235        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5236        if (tracesPath == null || tracesPath.length() == 0) {
5237            return;
5238        }
5239
5240        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5241        StrictMode.allowThreadDiskWrites();
5242        try {
5243            final File tracesFile = new File(tracesPath);
5244            final File tracesDir = tracesFile.getParentFile();
5245            final File tracesTmp = new File(tracesDir, "__tmp__");
5246            try {
5247                if (tracesFile.exists()) {
5248                    tracesTmp.delete();
5249                    tracesFile.renameTo(tracesTmp);
5250                }
5251                StringBuilder sb = new StringBuilder();
5252                Time tobj = new Time();
5253                tobj.set(System.currentTimeMillis());
5254                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5255                sb.append(": ");
5256                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5257                sb.append(" since ");
5258                sb.append(msg);
5259                FileOutputStream fos = new FileOutputStream(tracesFile);
5260                fos.write(sb.toString().getBytes());
5261                if (app == null) {
5262                    fos.write("\n*** No application process!".getBytes());
5263                }
5264                fos.close();
5265                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5266            } catch (IOException e) {
5267                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5268                return;
5269            }
5270
5271            if (app != null) {
5272                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5273                firstPids.add(app.pid);
5274                dumpStackTraces(tracesPath, firstPids, null, null, null);
5275            }
5276
5277            File lastTracesFile = null;
5278            File curTracesFile = null;
5279            for (int i=9; i>=0; i--) {
5280                String name = String.format(Locale.US, "slow%02d.txt", i);
5281                curTracesFile = new File(tracesDir, name);
5282                if (curTracesFile.exists()) {
5283                    if (lastTracesFile != null) {
5284                        curTracesFile.renameTo(lastTracesFile);
5285                    } else {
5286                        curTracesFile.delete();
5287                    }
5288                }
5289                lastTracesFile = curTracesFile;
5290            }
5291            tracesFile.renameTo(curTracesFile);
5292            if (tracesTmp.exists()) {
5293                tracesTmp.renameTo(tracesFile);
5294            }
5295        } finally {
5296            StrictMode.setThreadPolicy(oldPolicy);
5297        }
5298    }
5299
5300    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5301        if (!mLaunchWarningShown) {
5302            mLaunchWarningShown = true;
5303            mUiHandler.post(new Runnable() {
5304                @Override
5305                public void run() {
5306                    synchronized (ActivityManagerService.this) {
5307                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5308                        d.show();
5309                        mUiHandler.postDelayed(new Runnable() {
5310                            @Override
5311                            public void run() {
5312                                synchronized (ActivityManagerService.this) {
5313                                    d.dismiss();
5314                                    mLaunchWarningShown = false;
5315                                }
5316                            }
5317                        }, 4000);
5318                    }
5319                }
5320            });
5321        }
5322    }
5323
5324    @Override
5325    public boolean clearApplicationUserData(final String packageName,
5326            final IPackageDataObserver observer, int userId) {
5327        enforceNotIsolatedCaller("clearApplicationUserData");
5328        int uid = Binder.getCallingUid();
5329        int pid = Binder.getCallingPid();
5330        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5331                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5332
5333        final DevicePolicyManagerInternal dpmi = LocalServices
5334                .getService(DevicePolicyManagerInternal.class);
5335        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5336            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5337        }
5338
5339        long callingId = Binder.clearCallingIdentity();
5340        try {
5341            IPackageManager pm = AppGlobals.getPackageManager();
5342            int pkgUid = -1;
5343            synchronized(this) {
5344                try {
5345                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5346                } catch (RemoteException e) {
5347                }
5348                if (pkgUid == -1) {
5349                    Slog.w(TAG, "Invalid packageName: " + packageName);
5350                    if (observer != null) {
5351                        try {
5352                            observer.onRemoveCompleted(packageName, false);
5353                        } catch (RemoteException e) {
5354                            Slog.i(TAG, "Observer no longer exists.");
5355                        }
5356                    }
5357                    return false;
5358                }
5359                if (uid == pkgUid || checkComponentPermission(
5360                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5361                        pid, uid, -1, true)
5362                        == PackageManager.PERMISSION_GRANTED) {
5363                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5364                } else {
5365                    throw new SecurityException("PID " + pid + " does not have permission "
5366                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5367                                    + " of package " + packageName);
5368                }
5369
5370                // Remove all tasks match the cleared application package and user
5371                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5372                    final TaskRecord tr = mRecentTasks.get(i);
5373                    final String taskPackageName =
5374                            tr.getBaseIntent().getComponent().getPackageName();
5375                    if (tr.userId != userId) continue;
5376                    if (!taskPackageName.equals(packageName)) continue;
5377                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5378                }
5379            }
5380
5381            try {
5382                // Clear application user data
5383                pm.clearApplicationUserData(packageName, observer, userId);
5384
5385                synchronized(this) {
5386                    // Remove all permissions granted from/to this package
5387                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5388                }
5389
5390                // Remove all zen rules created by this package; revoke it's zen access.
5391                INotificationManager inm = NotificationManager.getService();
5392                inm.removeAutomaticZenRules(packageName);
5393                inm.setNotificationPolicyAccessGranted(packageName, false);
5394
5395                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5396                        Uri.fromParts("package", packageName, null));
5397                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5398                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5399                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5400                        null, null, 0, null, null, null, null, false, false, userId);
5401            } catch (RemoteException e) {
5402            }
5403        } finally {
5404            Binder.restoreCallingIdentity(callingId);
5405        }
5406        return true;
5407    }
5408
5409    @Override
5410    public void killBackgroundProcesses(final String packageName, int userId) {
5411        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5412                != PackageManager.PERMISSION_GRANTED &&
5413                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5414                        != PackageManager.PERMISSION_GRANTED) {
5415            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5416                    + Binder.getCallingPid()
5417                    + ", uid=" + Binder.getCallingUid()
5418                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5419            Slog.w(TAG, msg);
5420            throw new SecurityException(msg);
5421        }
5422
5423        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5424                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5425        long callingId = Binder.clearCallingIdentity();
5426        try {
5427            IPackageManager pm = AppGlobals.getPackageManager();
5428            synchronized(this) {
5429                int appId = -1;
5430                try {
5431                    appId = UserHandle.getAppId(
5432                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5433                } catch (RemoteException e) {
5434                }
5435                if (appId == -1) {
5436                    Slog.w(TAG, "Invalid packageName: " + packageName);
5437                    return;
5438                }
5439                killPackageProcessesLocked(packageName, appId, userId,
5440                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5441            }
5442        } finally {
5443            Binder.restoreCallingIdentity(callingId);
5444        }
5445    }
5446
5447    @Override
5448    public void killAllBackgroundProcesses() {
5449        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5450                != PackageManager.PERMISSION_GRANTED) {
5451            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5452                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5453                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5454            Slog.w(TAG, msg);
5455            throw new SecurityException(msg);
5456        }
5457
5458        final long callingId = Binder.clearCallingIdentity();
5459        try {
5460            synchronized (this) {
5461                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5462                final int NP = mProcessNames.getMap().size();
5463                for (int ip = 0; ip < NP; ip++) {
5464                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5465                    final int NA = apps.size();
5466                    for (int ia = 0; ia < NA; ia++) {
5467                        final ProcessRecord app = apps.valueAt(ia);
5468                        if (app.persistent) {
5469                            // We don't kill persistent processes.
5470                            continue;
5471                        }
5472                        if (app.removed) {
5473                            procs.add(app);
5474                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5475                            app.removed = true;
5476                            procs.add(app);
5477                        }
5478                    }
5479                }
5480
5481                final int N = procs.size();
5482                for (int i = 0; i < N; i++) {
5483                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5484                }
5485
5486                mAllowLowerMemLevel = true;
5487
5488                updateOomAdjLocked();
5489                doLowMemReportIfNeededLocked(null);
5490            }
5491        } finally {
5492            Binder.restoreCallingIdentity(callingId);
5493        }
5494    }
5495
5496    /**
5497     * Kills all background processes, except those matching any of the
5498     * specified properties.
5499     *
5500     * @param minTargetSdk the target SDK version at or above which to preserve
5501     *                     processes, or {@code -1} to ignore the target SDK
5502     * @param maxProcState the process state at or below which to preserve
5503     *                     processes, or {@code -1} to ignore the process state
5504     */
5505    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5506        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5507                != PackageManager.PERMISSION_GRANTED) {
5508            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5509                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5510                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5511            Slog.w(TAG, msg);
5512            throw new SecurityException(msg);
5513        }
5514
5515        final long callingId = Binder.clearCallingIdentity();
5516        try {
5517            synchronized (this) {
5518                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5519                final int NP = mProcessNames.getMap().size();
5520                for (int ip = 0; ip < NP; ip++) {
5521                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5522                    final int NA = apps.size();
5523                    for (int ia = 0; ia < NA; ia++) {
5524                        final ProcessRecord app = apps.valueAt(ia);
5525                        if (app.removed) {
5526                            procs.add(app);
5527                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5528                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5529                            app.removed = true;
5530                            procs.add(app);
5531                        }
5532                    }
5533                }
5534
5535                final int N = procs.size();
5536                for (int i = 0; i < N; i++) {
5537                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5538                }
5539            }
5540        } finally {
5541            Binder.restoreCallingIdentity(callingId);
5542        }
5543    }
5544
5545    @Override
5546    public void forceStopPackage(final String packageName, int userId) {
5547        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5548                != PackageManager.PERMISSION_GRANTED) {
5549            String msg = "Permission Denial: forceStopPackage() from pid="
5550                    + Binder.getCallingPid()
5551                    + ", uid=" + Binder.getCallingUid()
5552                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5553            Slog.w(TAG, msg);
5554            throw new SecurityException(msg);
5555        }
5556        final int callingPid = Binder.getCallingPid();
5557        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5558                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5559        long callingId = Binder.clearCallingIdentity();
5560        try {
5561            IPackageManager pm = AppGlobals.getPackageManager();
5562            synchronized(this) {
5563                int[] users = userId == UserHandle.USER_ALL
5564                        ? mUserController.getUsers() : new int[] { userId };
5565                for (int user : users) {
5566                    int pkgUid = -1;
5567                    try {
5568                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5569                                user);
5570                    } catch (RemoteException e) {
5571                    }
5572                    if (pkgUid == -1) {
5573                        Slog.w(TAG, "Invalid packageName: " + packageName);
5574                        continue;
5575                    }
5576                    try {
5577                        pm.setPackageStoppedState(packageName, true, user);
5578                    } catch (RemoteException e) {
5579                    } catch (IllegalArgumentException e) {
5580                        Slog.w(TAG, "Failed trying to unstop package "
5581                                + packageName + ": " + e);
5582                    }
5583                    if (mUserController.isUserRunningLocked(user, 0)) {
5584                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5585                    }
5586                }
5587            }
5588        } finally {
5589            Binder.restoreCallingIdentity(callingId);
5590        }
5591    }
5592
5593    @Override
5594    public void addPackageDependency(String packageName) {
5595        synchronized (this) {
5596            int callingPid = Binder.getCallingPid();
5597            if (callingPid == Process.myPid()) {
5598                //  Yeah, um, no.
5599                return;
5600            }
5601            ProcessRecord proc;
5602            synchronized (mPidsSelfLocked) {
5603                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5604            }
5605            if (proc != null) {
5606                if (proc.pkgDeps == null) {
5607                    proc.pkgDeps = new ArraySet<String>(1);
5608                }
5609                proc.pkgDeps.add(packageName);
5610            }
5611        }
5612    }
5613
5614    /*
5615     * The pkg name and app id have to be specified.
5616     */
5617    @Override
5618    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5619        if (pkg == null) {
5620            return;
5621        }
5622        // Make sure the uid is valid.
5623        if (appid < 0) {
5624            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5625            return;
5626        }
5627        int callerUid = Binder.getCallingUid();
5628        // Only the system server can kill an application
5629        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5630            // Post an aysnc message to kill the application
5631            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5632            msg.arg1 = appid;
5633            msg.arg2 = 0;
5634            Bundle bundle = new Bundle();
5635            bundle.putString("pkg", pkg);
5636            bundle.putString("reason", reason);
5637            msg.obj = bundle;
5638            mHandler.sendMessage(msg);
5639        } else {
5640            throw new SecurityException(callerUid + " cannot kill pkg: " +
5641                    pkg);
5642        }
5643    }
5644
5645    @Override
5646    public void closeSystemDialogs(String reason) {
5647        enforceNotIsolatedCaller("closeSystemDialogs");
5648
5649        final int pid = Binder.getCallingPid();
5650        final int uid = Binder.getCallingUid();
5651        final long origId = Binder.clearCallingIdentity();
5652        try {
5653            synchronized (this) {
5654                // Only allow this from foreground processes, so that background
5655                // applications can't abuse it to prevent system UI from being shown.
5656                if (uid >= Process.FIRST_APPLICATION_UID) {
5657                    ProcessRecord proc;
5658                    synchronized (mPidsSelfLocked) {
5659                        proc = mPidsSelfLocked.get(pid);
5660                    }
5661                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5662                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5663                                + " from background process " + proc);
5664                        return;
5665                    }
5666                }
5667                closeSystemDialogsLocked(reason);
5668            }
5669        } finally {
5670            Binder.restoreCallingIdentity(origId);
5671        }
5672    }
5673
5674    void closeSystemDialogsLocked(String reason) {
5675        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5676        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5677                | Intent.FLAG_RECEIVER_FOREGROUND);
5678        if (reason != null) {
5679            intent.putExtra("reason", reason);
5680        }
5681        mWindowManager.closeSystemDialogs(reason);
5682
5683        mStackSupervisor.closeSystemDialogsLocked();
5684
5685        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5686                AppOpsManager.OP_NONE, null, false, false,
5687                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5688    }
5689
5690    @Override
5691    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5692        enforceNotIsolatedCaller("getProcessMemoryInfo");
5693        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5694        for (int i=pids.length-1; i>=0; i--) {
5695            ProcessRecord proc;
5696            int oomAdj;
5697            synchronized (this) {
5698                synchronized (mPidsSelfLocked) {
5699                    proc = mPidsSelfLocked.get(pids[i]);
5700                    oomAdj = proc != null ? proc.setAdj : 0;
5701                }
5702            }
5703            infos[i] = new Debug.MemoryInfo();
5704            Debug.getMemoryInfo(pids[i], infos[i]);
5705            if (proc != null) {
5706                synchronized (this) {
5707                    if (proc.thread != null && proc.setAdj == oomAdj) {
5708                        // Record this for posterity if the process has been stable.
5709                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5710                                infos[i].getTotalUss(), false, proc.pkgList);
5711                    }
5712                }
5713            }
5714        }
5715        return infos;
5716    }
5717
5718    @Override
5719    public long[] getProcessPss(int[] pids) {
5720        enforceNotIsolatedCaller("getProcessPss");
5721        long[] pss = new long[pids.length];
5722        for (int i=pids.length-1; i>=0; i--) {
5723            ProcessRecord proc;
5724            int oomAdj;
5725            synchronized (this) {
5726                synchronized (mPidsSelfLocked) {
5727                    proc = mPidsSelfLocked.get(pids[i]);
5728                    oomAdj = proc != null ? proc.setAdj : 0;
5729                }
5730            }
5731            long[] tmpUss = new long[1];
5732            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5733            if (proc != null) {
5734                synchronized (this) {
5735                    if (proc.thread != null && proc.setAdj == oomAdj) {
5736                        // Record this for posterity if the process has been stable.
5737                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5738                    }
5739                }
5740            }
5741        }
5742        return pss;
5743    }
5744
5745    @Override
5746    public void killApplicationProcess(String processName, int uid) {
5747        if (processName == null) {
5748            return;
5749        }
5750
5751        int callerUid = Binder.getCallingUid();
5752        // Only the system server can kill an application
5753        if (callerUid == Process.SYSTEM_UID) {
5754            synchronized (this) {
5755                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5756                if (app != null && app.thread != null) {
5757                    try {
5758                        app.thread.scheduleSuicide();
5759                    } catch (RemoteException e) {
5760                        // If the other end already died, then our work here is done.
5761                    }
5762                } else {
5763                    Slog.w(TAG, "Process/uid not found attempting kill of "
5764                            + processName + " / " + uid);
5765                }
5766            }
5767        } else {
5768            throw new SecurityException(callerUid + " cannot kill app process: " +
5769                    processName);
5770        }
5771    }
5772
5773    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5774        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5775                false, true, false, false, UserHandle.getUserId(uid), reason);
5776        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5777                Uri.fromParts("package", packageName, null));
5778        if (!mProcessesReady) {
5779            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5780                    | Intent.FLAG_RECEIVER_FOREGROUND);
5781        }
5782        intent.putExtra(Intent.EXTRA_UID, uid);
5783        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5784        broadcastIntentLocked(null, null, intent,
5785                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5786                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5787    }
5788
5789
5790    private final boolean killPackageProcessesLocked(String packageName, int appId,
5791            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5792            boolean doit, boolean evenPersistent, String reason) {
5793        ArrayList<ProcessRecord> procs = new ArrayList<>();
5794
5795        // Remove all processes this package may have touched: all with the
5796        // same UID (except for the system or root user), and all whose name
5797        // matches the package name.
5798        final int NP = mProcessNames.getMap().size();
5799        for (int ip=0; ip<NP; ip++) {
5800            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5801            final int NA = apps.size();
5802            for (int ia=0; ia<NA; ia++) {
5803                ProcessRecord app = apps.valueAt(ia);
5804                if (app.persistent && !evenPersistent) {
5805                    // we don't kill persistent processes
5806                    continue;
5807                }
5808                if (app.removed) {
5809                    if (doit) {
5810                        procs.add(app);
5811                    }
5812                    continue;
5813                }
5814
5815                // Skip process if it doesn't meet our oom adj requirement.
5816                if (app.setAdj < minOomAdj) {
5817                    continue;
5818                }
5819
5820                // If no package is specified, we call all processes under the
5821                // give user id.
5822                if (packageName == null) {
5823                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5824                        continue;
5825                    }
5826                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5827                        continue;
5828                    }
5829                // Package has been specified, we want to hit all processes
5830                // that match it.  We need to qualify this by the processes
5831                // that are running under the specified app and user ID.
5832                } else {
5833                    final boolean isDep = app.pkgDeps != null
5834                            && app.pkgDeps.contains(packageName);
5835                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5836                        continue;
5837                    }
5838                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5839                        continue;
5840                    }
5841                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5842                        continue;
5843                    }
5844                }
5845
5846                // Process has passed all conditions, kill it!
5847                if (!doit) {
5848                    return true;
5849                }
5850                app.removed = true;
5851                procs.add(app);
5852            }
5853        }
5854
5855        int N = procs.size();
5856        for (int i=0; i<N; i++) {
5857            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5858        }
5859        updateOomAdjLocked();
5860        return N > 0;
5861    }
5862
5863    private void cleanupDisabledPackageComponentsLocked(
5864            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5865
5866        Set<String> disabledClasses = null;
5867        boolean packageDisabled = false;
5868        IPackageManager pm = AppGlobals.getPackageManager();
5869
5870        if (changedClasses == null) {
5871            // Nothing changed...
5872            return;
5873        }
5874
5875        // Determine enable/disable state of the package and its components.
5876        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5877        for (int i = changedClasses.length - 1; i >= 0; i--) {
5878            final String changedClass = changedClasses[i];
5879
5880            if (changedClass.equals(packageName)) {
5881                try {
5882                    // Entire package setting changed
5883                    enabled = pm.getApplicationEnabledSetting(packageName,
5884                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5885                } catch (Exception e) {
5886                    // No such package/component; probably racing with uninstall.  In any
5887                    // event it means we have nothing further to do here.
5888                    return;
5889                }
5890                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5891                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5892                if (packageDisabled) {
5893                    // Entire package is disabled.
5894                    // No need to continue to check component states.
5895                    disabledClasses = null;
5896                    break;
5897                }
5898            } else {
5899                try {
5900                    enabled = pm.getComponentEnabledSetting(
5901                            new ComponentName(packageName, changedClass),
5902                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5903                } catch (Exception e) {
5904                    // As above, probably racing with uninstall.
5905                    return;
5906                }
5907                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5908                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5909                    if (disabledClasses == null) {
5910                        disabledClasses = new ArraySet<>(changedClasses.length);
5911                    }
5912                    disabledClasses.add(changedClass);
5913                }
5914            }
5915        }
5916
5917        if (!packageDisabled && disabledClasses == null) {
5918            // Nothing to do here...
5919            return;
5920        }
5921
5922        // Clean-up disabled activities.
5923        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5924                packageName, disabledClasses, true, false, userId) && mBooted) {
5925            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5926            mStackSupervisor.scheduleIdleLocked();
5927        }
5928
5929        // Clean-up disabled tasks
5930        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5931
5932        // Clean-up disabled services.
5933        mServices.bringDownDisabledPackageServicesLocked(
5934                packageName, disabledClasses, userId, false, killProcess, true);
5935
5936        // Clean-up disabled providers.
5937        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5938        mProviderMap.collectPackageProvidersLocked(
5939                packageName, disabledClasses, true, false, userId, providers);
5940        for (int i = providers.size() - 1; i >= 0; i--) {
5941            removeDyingProviderLocked(null, providers.get(i), true);
5942        }
5943
5944        // Clean-up disabled broadcast receivers.
5945        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5946            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5947                    packageName, disabledClasses, userId, true);
5948        }
5949
5950    }
5951
5952    final boolean clearBroadcastQueueForUserLocked(int userId) {
5953        boolean didSomething = false;
5954        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5955            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5956                    null, null, userId, true);
5957        }
5958        return didSomething;
5959    }
5960
5961    final boolean forceStopPackageLocked(String packageName, int appId,
5962            boolean callerWillRestart, boolean purgeCache, boolean doit,
5963            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5964        int i;
5965
5966        if (userId == UserHandle.USER_ALL && packageName == null) {
5967            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5968        }
5969
5970        if (appId < 0 && packageName != null) {
5971            try {
5972                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5973                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5974            } catch (RemoteException e) {
5975            }
5976        }
5977
5978        if (doit) {
5979            if (packageName != null) {
5980                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5981                        + " user=" + userId + ": " + reason);
5982            } else {
5983                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5984            }
5985
5986            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5987        }
5988
5989        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5990                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5991                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5992
5993        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5994                packageName, null, doit, evenPersistent, userId)) {
5995            if (!doit) {
5996                return true;
5997            }
5998            didSomething = true;
5999        }
6000
6001        if (mServices.bringDownDisabledPackageServicesLocked(
6002                packageName, null, userId, evenPersistent, true, doit)) {
6003            if (!doit) {
6004                return true;
6005            }
6006            didSomething = true;
6007        }
6008
6009        if (packageName == null) {
6010            // Remove all sticky broadcasts from this user.
6011            mStickyBroadcasts.remove(userId);
6012        }
6013
6014        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6015        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6016                userId, providers)) {
6017            if (!doit) {
6018                return true;
6019            }
6020            didSomething = true;
6021        }
6022        for (i = providers.size() - 1; i >= 0; i--) {
6023            removeDyingProviderLocked(null, providers.get(i), true);
6024        }
6025
6026        // Remove transient permissions granted from/to this package/user
6027        removeUriPermissionsForPackageLocked(packageName, userId, false);
6028
6029        if (doit) {
6030            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6031                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6032                        packageName, null, userId, doit);
6033            }
6034        }
6035
6036        if (packageName == null || uninstalling) {
6037            // Remove pending intents.  For now we only do this when force
6038            // stopping users, because we have some problems when doing this
6039            // for packages -- app widgets are not currently cleaned up for
6040            // such packages, so they can be left with bad pending intents.
6041            if (mIntentSenderRecords.size() > 0) {
6042                Iterator<WeakReference<PendingIntentRecord>> it
6043                        = mIntentSenderRecords.values().iterator();
6044                while (it.hasNext()) {
6045                    WeakReference<PendingIntentRecord> wpir = it.next();
6046                    if (wpir == null) {
6047                        it.remove();
6048                        continue;
6049                    }
6050                    PendingIntentRecord pir = wpir.get();
6051                    if (pir == null) {
6052                        it.remove();
6053                        continue;
6054                    }
6055                    if (packageName == null) {
6056                        // Stopping user, remove all objects for the user.
6057                        if (pir.key.userId != userId) {
6058                            // Not the same user, skip it.
6059                            continue;
6060                        }
6061                    } else {
6062                        if (UserHandle.getAppId(pir.uid) != appId) {
6063                            // Different app id, skip it.
6064                            continue;
6065                        }
6066                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6067                            // Different user, skip it.
6068                            continue;
6069                        }
6070                        if (!pir.key.packageName.equals(packageName)) {
6071                            // Different package, skip it.
6072                            continue;
6073                        }
6074                    }
6075                    if (!doit) {
6076                        return true;
6077                    }
6078                    didSomething = true;
6079                    it.remove();
6080                    pir.canceled = true;
6081                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6082                        pir.key.activity.pendingResults.remove(pir.ref);
6083                    }
6084                }
6085            }
6086        }
6087
6088        if (doit) {
6089            if (purgeCache && packageName != null) {
6090                AttributeCache ac = AttributeCache.instance();
6091                if (ac != null) {
6092                    ac.removePackage(packageName);
6093                }
6094            }
6095            if (mBooted) {
6096                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6097                mStackSupervisor.scheduleIdleLocked();
6098            }
6099        }
6100
6101        return didSomething;
6102    }
6103
6104    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6105        ProcessRecord old = mProcessNames.remove(name, uid);
6106        if (old != null) {
6107            old.uidRecord.numProcs--;
6108            if (old.uidRecord.numProcs == 0) {
6109                // No more processes using this uid, tell clients it is gone.
6110                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6111                        "No more processes in " + old.uidRecord);
6112                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6113                mActiveUids.remove(uid);
6114                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6115            }
6116            old.uidRecord = null;
6117        }
6118        mIsolatedProcesses.remove(uid);
6119        return old;
6120    }
6121
6122    private final void addProcessNameLocked(ProcessRecord proc) {
6123        // We shouldn't already have a process under this name, but just in case we
6124        // need to clean up whatever may be there now.
6125        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6126        if (old == proc && proc.persistent) {
6127            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6128            Slog.w(TAG, "Re-adding persistent process " + proc);
6129        } else if (old != null) {
6130            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6131        }
6132        UidRecord uidRec = mActiveUids.get(proc.uid);
6133        if (uidRec == null) {
6134            uidRec = new UidRecord(proc.uid);
6135            // This is the first appearance of the uid, report it now!
6136            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6137                    "Creating new process uid: " + uidRec);
6138            mActiveUids.put(proc.uid, uidRec);
6139            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6140            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6141        }
6142        proc.uidRecord = uidRec;
6143        uidRec.numProcs++;
6144        mProcessNames.put(proc.processName, proc.uid, proc);
6145        if (proc.isolated) {
6146            mIsolatedProcesses.put(proc.uid, proc);
6147        }
6148    }
6149
6150    boolean removeProcessLocked(ProcessRecord app,
6151            boolean callerWillRestart, boolean allowRestart, String reason) {
6152        final String name = app.processName;
6153        final int uid = app.uid;
6154        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6155            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6156
6157        removeProcessNameLocked(name, uid);
6158        if (mHeavyWeightProcess == app) {
6159            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6160                    mHeavyWeightProcess.userId, 0));
6161            mHeavyWeightProcess = null;
6162        }
6163        boolean needRestart = false;
6164        if (app.pid > 0 && app.pid != MY_PID) {
6165            int pid = app.pid;
6166            synchronized (mPidsSelfLocked) {
6167                mPidsSelfLocked.remove(pid);
6168                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6169            }
6170            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6171            if (app.isolated) {
6172                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6173            }
6174            boolean willRestart = false;
6175            if (app.persistent && !app.isolated) {
6176                if (!callerWillRestart) {
6177                    willRestart = true;
6178                } else {
6179                    needRestart = true;
6180                }
6181            }
6182            app.kill(reason, true);
6183            handleAppDiedLocked(app, willRestart, allowRestart);
6184            if (willRestart) {
6185                removeLruProcessLocked(app);
6186                addAppLocked(app.info, false, null /* ABI override */);
6187            }
6188        } else {
6189            mRemovedProcesses.add(app);
6190        }
6191
6192        return needRestart;
6193    }
6194
6195    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6196        cleanupAppInLaunchingProvidersLocked(app, true);
6197        removeProcessLocked(app, false, true, "timeout publishing content providers");
6198    }
6199
6200    private final void processStartTimedOutLocked(ProcessRecord app) {
6201        final int pid = app.pid;
6202        boolean gone = false;
6203        synchronized (mPidsSelfLocked) {
6204            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6205            if (knownApp != null && knownApp.thread == null) {
6206                mPidsSelfLocked.remove(pid);
6207                gone = true;
6208            }
6209        }
6210
6211        if (gone) {
6212            Slog.w(TAG, "Process " + app + " failed to attach");
6213            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6214                    pid, app.uid, app.processName);
6215            removeProcessNameLocked(app.processName, app.uid);
6216            if (mHeavyWeightProcess == app) {
6217                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6218                        mHeavyWeightProcess.userId, 0));
6219                mHeavyWeightProcess = null;
6220            }
6221            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6222            if (app.isolated) {
6223                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6224            }
6225            // Take care of any launching providers waiting for this process.
6226            cleanupAppInLaunchingProvidersLocked(app, true);
6227            // Take care of any services that are waiting for the process.
6228            mServices.processStartTimedOutLocked(app);
6229            app.kill("start timeout", true);
6230            removeLruProcessLocked(app);
6231            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6232                Slog.w(TAG, "Unattached app died before backup, skipping");
6233                try {
6234                    IBackupManager bm = IBackupManager.Stub.asInterface(
6235                            ServiceManager.getService(Context.BACKUP_SERVICE));
6236                    bm.agentDisconnected(app.info.packageName);
6237                } catch (RemoteException e) {
6238                    // Can't happen; the backup manager is local
6239                }
6240            }
6241            if (isPendingBroadcastProcessLocked(pid)) {
6242                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6243                skipPendingBroadcastLocked(pid);
6244            }
6245        } else {
6246            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6247        }
6248    }
6249
6250    private final boolean attachApplicationLocked(IApplicationThread thread,
6251            int pid) {
6252
6253        // Find the application record that is being attached...  either via
6254        // the pid if we are running in multiple processes, or just pull the
6255        // next app record if we are emulating process with anonymous threads.
6256        ProcessRecord app;
6257        if (pid != MY_PID && pid >= 0) {
6258            synchronized (mPidsSelfLocked) {
6259                app = mPidsSelfLocked.get(pid);
6260            }
6261        } else {
6262            app = null;
6263        }
6264
6265        if (app == null) {
6266            Slog.w(TAG, "No pending application record for pid " + pid
6267                    + " (IApplicationThread " + thread + "); dropping process");
6268            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6269            if (pid > 0 && pid != MY_PID) {
6270                Process.killProcessQuiet(pid);
6271                //TODO: killProcessGroup(app.info.uid, pid);
6272            } else {
6273                try {
6274                    thread.scheduleExit();
6275                } catch (Exception e) {
6276                    // Ignore exceptions.
6277                }
6278            }
6279            return false;
6280        }
6281
6282        // If this application record is still attached to a previous
6283        // process, clean it up now.
6284        if (app.thread != null) {
6285            handleAppDiedLocked(app, true, true);
6286        }
6287
6288        // Tell the process all about itself.
6289
6290        if (DEBUG_ALL) Slog.v(
6291                TAG, "Binding process pid " + pid + " to record " + app);
6292
6293        final String processName = app.processName;
6294        try {
6295            AppDeathRecipient adr = new AppDeathRecipient(
6296                    app, pid, thread);
6297            thread.asBinder().linkToDeath(adr, 0);
6298            app.deathRecipient = adr;
6299        } catch (RemoteException e) {
6300            app.resetPackageList(mProcessStats);
6301            startProcessLocked(app, "link fail", processName);
6302            return false;
6303        }
6304
6305        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6306
6307        app.makeActive(thread, mProcessStats);
6308        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6309        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6310        app.forcingToForeground = null;
6311        updateProcessForegroundLocked(app, false, false);
6312        app.hasShownUi = false;
6313        app.debugging = false;
6314        app.cached = false;
6315        app.killedByAm = false;
6316        app.unlocked = mContext.getSystemService(UserManager.class).isUserUnlocked(app.userId);
6317
6318        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6319
6320        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6321        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6322
6323        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6324            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6325            msg.obj = app;
6326            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6327        }
6328
6329        if (!normalMode) {
6330            Slog.i(TAG, "Launching preboot mode app: " + app);
6331        }
6332
6333        if (DEBUG_ALL) Slog.v(
6334            TAG, "New app record " + app
6335            + " thread=" + thread.asBinder() + " pid=" + pid);
6336        try {
6337            int testMode = IApplicationThread.DEBUG_OFF;
6338            if (mDebugApp != null && mDebugApp.equals(processName)) {
6339                testMode = mWaitForDebugger
6340                    ? IApplicationThread.DEBUG_WAIT
6341                    : IApplicationThread.DEBUG_ON;
6342                app.debugging = true;
6343                if (mDebugTransient) {
6344                    mDebugApp = mOrigDebugApp;
6345                    mWaitForDebugger = mOrigWaitForDebugger;
6346                }
6347            }
6348            String profileFile = app.instrumentationProfileFile;
6349            ParcelFileDescriptor profileFd = null;
6350            int samplingInterval = 0;
6351            boolean profileAutoStop = false;
6352            if (mProfileApp != null && mProfileApp.equals(processName)) {
6353                mProfileProc = app;
6354                profileFile = mProfileFile;
6355                profileFd = mProfileFd;
6356                samplingInterval = mSamplingInterval;
6357                profileAutoStop = mAutoStopProfiler;
6358            }
6359            boolean enableTrackAllocation = false;
6360            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6361                enableTrackAllocation = true;
6362                mTrackAllocationApp = null;
6363            }
6364
6365            // If the app is being launched for restore or full backup, set it up specially
6366            boolean isRestrictedBackupMode = false;
6367            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6368                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6369                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6370                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6371                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6372            }
6373
6374            if (app.instrumentationClass != null) {
6375                notifyPackageUse(app.instrumentationClass.getPackageName(),
6376                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6377            }
6378            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6379                    + processName + " with config " + mConfiguration);
6380            ApplicationInfo appInfo = app.instrumentationInfo != null
6381                    ? app.instrumentationInfo : app.info;
6382            app.compat = compatibilityInfoForPackageLocked(appInfo);
6383            if (profileFd != null) {
6384                profileFd = profileFd.dup();
6385            }
6386            ProfilerInfo profilerInfo = profileFile == null ? null
6387                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6388            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6389                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6390                    app.instrumentationUiAutomationConnection, testMode,
6391                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6392                    isRestrictedBackupMode || !normalMode, app.persistent,
6393                    new Configuration(mConfiguration), app.compat,
6394                    getCommonServicesLocked(app.isolated),
6395                    mCoreSettingsObserver.getCoreSettingsLocked());
6396            updateLruProcessLocked(app, false, null);
6397            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6398        } catch (Exception e) {
6399            // todo: Yikes!  What should we do?  For now we will try to
6400            // start another process, but that could easily get us in
6401            // an infinite loop of restarting processes...
6402            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6403
6404            app.resetPackageList(mProcessStats);
6405            app.unlinkDeathRecipient();
6406            startProcessLocked(app, "bind fail", processName);
6407            return false;
6408        }
6409
6410        // Remove this record from the list of starting applications.
6411        mPersistentStartingProcesses.remove(app);
6412        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6413                "Attach application locked removing on hold: " + app);
6414        mProcessesOnHold.remove(app);
6415
6416        boolean badApp = false;
6417        boolean didSomething = false;
6418
6419        // See if the top visible activity is waiting to run in this process...
6420        if (normalMode) {
6421            try {
6422                if (mStackSupervisor.attachApplicationLocked(app)) {
6423                    didSomething = true;
6424                }
6425            } catch (Exception e) {
6426                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6427                badApp = true;
6428            }
6429        }
6430
6431        // Find any services that should be running in this process...
6432        if (!badApp) {
6433            try {
6434                didSomething |= mServices.attachApplicationLocked(app, processName);
6435            } catch (Exception e) {
6436                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6437                badApp = true;
6438            }
6439        }
6440
6441        // Check if a next-broadcast receiver is in this process...
6442        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6443            try {
6444                didSomething |= sendPendingBroadcastsLocked(app);
6445            } catch (Exception e) {
6446                // If the app died trying to launch the receiver we declare it 'bad'
6447                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6448                badApp = true;
6449            }
6450        }
6451
6452        // Check whether the next backup agent is in this process...
6453        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6454            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6455                    "New app is backup target, launching agent for " + app);
6456            notifyPackageUse(mBackupTarget.appInfo.packageName,
6457                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6458            try {
6459                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6460                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6461                        mBackupTarget.backupMode);
6462            } catch (Exception e) {
6463                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6464                badApp = true;
6465            }
6466        }
6467
6468        if (badApp) {
6469            app.kill("error during init", true);
6470            handleAppDiedLocked(app, false, true);
6471            return false;
6472        }
6473
6474        if (!didSomething) {
6475            updateOomAdjLocked();
6476        }
6477
6478        return true;
6479    }
6480
6481    @Override
6482    public final void attachApplication(IApplicationThread thread) {
6483        synchronized (this) {
6484            int callingPid = Binder.getCallingPid();
6485            final long origId = Binder.clearCallingIdentity();
6486            attachApplicationLocked(thread, callingPid);
6487            Binder.restoreCallingIdentity(origId);
6488        }
6489    }
6490
6491    @Override
6492    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6493        final long origId = Binder.clearCallingIdentity();
6494        synchronized (this) {
6495            ActivityStack stack = ActivityRecord.getStackLocked(token);
6496            if (stack != null) {
6497                ActivityRecord r =
6498                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6499                if (stopProfiling) {
6500                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6501                        try {
6502                            mProfileFd.close();
6503                        } catch (IOException e) {
6504                        }
6505                        clearProfilerLocked();
6506                    }
6507                }
6508            }
6509        }
6510        Binder.restoreCallingIdentity(origId);
6511    }
6512
6513    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6514        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6515                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6516    }
6517
6518    void enableScreenAfterBoot() {
6519        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6520                SystemClock.uptimeMillis());
6521        mWindowManager.enableScreenAfterBoot();
6522
6523        synchronized (this) {
6524            updateEventDispatchingLocked();
6525        }
6526    }
6527
6528    @Override
6529    public void showBootMessage(final CharSequence msg, final boolean always) {
6530        if (Binder.getCallingUid() != Process.myUid()) {
6531            // These days only the core system can call this, so apps can't get in
6532            // the way of what we show about running them.
6533        }
6534        mWindowManager.showBootMessage(msg, always);
6535    }
6536
6537    @Override
6538    public void keyguardWaitingForActivityDrawn() {
6539        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6540        final long token = Binder.clearCallingIdentity();
6541        try {
6542            synchronized (this) {
6543                if (DEBUG_LOCKSCREEN) logLockScreen("");
6544                mWindowManager.keyguardWaitingForActivityDrawn();
6545                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6546                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6547                    updateSleepIfNeededLocked();
6548                }
6549            }
6550        } finally {
6551            Binder.restoreCallingIdentity(token);
6552        }
6553    }
6554
6555    @Override
6556    public void keyguardGoingAway(int flags) {
6557        enforceNotIsolatedCaller("keyguardGoingAway");
6558        final long token = Binder.clearCallingIdentity();
6559        try {
6560            synchronized (this) {
6561                if (DEBUG_LOCKSCREEN) logLockScreen("");
6562                mWindowManager.keyguardGoingAway(flags);
6563                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6564                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6565                    updateSleepIfNeededLocked();
6566
6567                    // Some stack visibility might change (e.g. docked stack)
6568                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6569                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6570                }
6571            }
6572        } finally {
6573            Binder.restoreCallingIdentity(token);
6574        }
6575    }
6576
6577    final void finishBooting() {
6578        synchronized (this) {
6579            if (!mBootAnimationComplete) {
6580                mCallFinishBooting = true;
6581                return;
6582            }
6583            mCallFinishBooting = false;
6584        }
6585
6586        ArraySet<String> completedIsas = new ArraySet<String>();
6587        for (String abi : Build.SUPPORTED_ABIS) {
6588            Process.establishZygoteConnectionForAbi(abi);
6589            final String instructionSet = VMRuntime.getInstructionSet(abi);
6590            if (!completedIsas.contains(instructionSet)) {
6591                try {
6592                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6593                } catch (InstallerException e) {
6594                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6595                }
6596                completedIsas.add(instructionSet);
6597            }
6598        }
6599
6600        IntentFilter pkgFilter = new IntentFilter();
6601        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6602        pkgFilter.addDataScheme("package");
6603        mContext.registerReceiver(new BroadcastReceiver() {
6604            @Override
6605            public void onReceive(Context context, Intent intent) {
6606                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6607                if (pkgs != null) {
6608                    for (String pkg : pkgs) {
6609                        synchronized (ActivityManagerService.this) {
6610                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6611                                    0, "query restart")) {
6612                                setResultCode(Activity.RESULT_OK);
6613                                return;
6614                            }
6615                        }
6616                    }
6617                }
6618            }
6619        }, pkgFilter);
6620
6621        IntentFilter dumpheapFilter = new IntentFilter();
6622        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6623        mContext.registerReceiver(new BroadcastReceiver() {
6624            @Override
6625            public void onReceive(Context context, Intent intent) {
6626                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6627                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6628                } else {
6629                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6630                }
6631            }
6632        }, dumpheapFilter);
6633
6634        // Let system services know.
6635        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6636
6637        synchronized (this) {
6638            // Ensure that any processes we had put on hold are now started
6639            // up.
6640            final int NP = mProcessesOnHold.size();
6641            if (NP > 0) {
6642                ArrayList<ProcessRecord> procs =
6643                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6644                for (int ip=0; ip<NP; ip++) {
6645                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6646                            + procs.get(ip));
6647                    startProcessLocked(procs.get(ip), "on-hold", null);
6648                }
6649            }
6650
6651            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6652                // Start looking for apps that are abusing wake locks.
6653                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6654                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6655                // Tell anyone interested that we are done booting!
6656                SystemProperties.set("sys.boot_completed", "1");
6657
6658                // And trigger dev.bootcomplete if we are not showing encryption progress
6659                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6660                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6661                    SystemProperties.set("dev.bootcomplete", "1");
6662                }
6663                mUserController.sendBootCompletedLocked(
6664                        new IIntentReceiver.Stub() {
6665                            @Override
6666                            public void performReceive(Intent intent, int resultCode,
6667                                    String data, Bundle extras, boolean ordered,
6668                                    boolean sticky, int sendingUser) {
6669                                synchronized (ActivityManagerService.this) {
6670                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6671                                            true, false);
6672                                }
6673                            }
6674                        });
6675                scheduleStartProfilesLocked();
6676            }
6677        }
6678    }
6679
6680    @Override
6681    public void bootAnimationComplete() {
6682        final boolean callFinishBooting;
6683        synchronized (this) {
6684            callFinishBooting = mCallFinishBooting;
6685            mBootAnimationComplete = true;
6686        }
6687        if (callFinishBooting) {
6688            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6689            finishBooting();
6690            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6691        }
6692    }
6693
6694    final void ensureBootCompleted() {
6695        boolean booting;
6696        boolean enableScreen;
6697        synchronized (this) {
6698            booting = mBooting;
6699            mBooting = false;
6700            enableScreen = !mBooted;
6701            mBooted = true;
6702        }
6703
6704        if (booting) {
6705            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6706            finishBooting();
6707            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6708        }
6709
6710        if (enableScreen) {
6711            enableScreenAfterBoot();
6712        }
6713    }
6714
6715    @Override
6716    public final void activityResumed(IBinder token) {
6717        final long origId = Binder.clearCallingIdentity();
6718        synchronized(this) {
6719            ActivityStack stack = ActivityRecord.getStackLocked(token);
6720            if (stack != null) {
6721                stack.activityResumedLocked(token);
6722            }
6723        }
6724        Binder.restoreCallingIdentity(origId);
6725    }
6726
6727    @Override
6728    public final void activityPaused(IBinder token) {
6729        final long origId = Binder.clearCallingIdentity();
6730        synchronized(this) {
6731            ActivityStack stack = ActivityRecord.getStackLocked(token);
6732            if (stack != null) {
6733                stack.activityPausedLocked(token, false);
6734            }
6735        }
6736        Binder.restoreCallingIdentity(origId);
6737    }
6738
6739    @Override
6740    public final void activityStopped(IBinder token, Bundle icicle,
6741            PersistableBundle persistentState, CharSequence description) {
6742        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6743
6744        // Refuse possible leaked file descriptors
6745        if (icicle != null && icicle.hasFileDescriptors()) {
6746            throw new IllegalArgumentException("File descriptors passed in Bundle");
6747        }
6748
6749        final long origId = Binder.clearCallingIdentity();
6750
6751        synchronized (this) {
6752            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6753            if (r != null) {
6754                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6755            }
6756        }
6757
6758        trimApplications();
6759
6760        Binder.restoreCallingIdentity(origId);
6761    }
6762
6763    @Override
6764    public final void activityDestroyed(IBinder token) {
6765        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6766        synchronized (this) {
6767            ActivityStack stack = ActivityRecord.getStackLocked(token);
6768            if (stack != null) {
6769                stack.activityDestroyedLocked(token, "activityDestroyed");
6770            }
6771        }
6772    }
6773
6774    @Override
6775    public final void activityRelaunched(IBinder token) {
6776        final long origId = Binder.clearCallingIdentity();
6777        synchronized (this) {
6778            mStackSupervisor.activityRelaunchedLocked(token);
6779        }
6780        Binder.restoreCallingIdentity(origId);
6781    }
6782
6783    @Override
6784    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6785            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6786        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6787                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6788        synchronized (this) {
6789            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6790            if (record == null) {
6791                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6792                        + "found for: " + token);
6793            }
6794            record.setSizeConfigurations(horizontalSizeConfiguration,
6795                    verticalSizeConfigurations, smallestSizeConfigurations);
6796        }
6797    }
6798
6799    @Override
6800    public final void backgroundResourcesReleased(IBinder token) {
6801        final long origId = Binder.clearCallingIdentity();
6802        try {
6803            synchronized (this) {
6804                ActivityStack stack = ActivityRecord.getStackLocked(token);
6805                if (stack != null) {
6806                    stack.backgroundResourcesReleased();
6807                }
6808            }
6809        } finally {
6810            Binder.restoreCallingIdentity(origId);
6811        }
6812    }
6813
6814    @Override
6815    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6816        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6817    }
6818
6819    @Override
6820    public final void notifyEnterAnimationComplete(IBinder token) {
6821        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6822    }
6823
6824    @Override
6825    public String getCallingPackage(IBinder token) {
6826        synchronized (this) {
6827            ActivityRecord r = getCallingRecordLocked(token);
6828            return r != null ? r.info.packageName : null;
6829        }
6830    }
6831
6832    @Override
6833    public ComponentName getCallingActivity(IBinder token) {
6834        synchronized (this) {
6835            ActivityRecord r = getCallingRecordLocked(token);
6836            return r != null ? r.intent.getComponent() : null;
6837        }
6838    }
6839
6840    private ActivityRecord getCallingRecordLocked(IBinder token) {
6841        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6842        if (r == null) {
6843            return null;
6844        }
6845        return r.resultTo;
6846    }
6847
6848    @Override
6849    public ComponentName getActivityClassForToken(IBinder token) {
6850        synchronized(this) {
6851            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6852            if (r == null) {
6853                return null;
6854            }
6855            return r.intent.getComponent();
6856        }
6857    }
6858
6859    @Override
6860    public String getPackageForToken(IBinder token) {
6861        synchronized(this) {
6862            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6863            if (r == null) {
6864                return null;
6865            }
6866            return r.packageName;
6867        }
6868    }
6869
6870    @Override
6871    public boolean isRootVoiceInteraction(IBinder token) {
6872        synchronized(this) {
6873            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6874            if (r == null) {
6875                return false;
6876            }
6877            return r.rootVoiceInteraction;
6878        }
6879    }
6880
6881    @Override
6882    public IIntentSender getIntentSender(int type,
6883            String packageName, IBinder token, String resultWho,
6884            int requestCode, Intent[] intents, String[] resolvedTypes,
6885            int flags, Bundle bOptions, int userId) {
6886        enforceNotIsolatedCaller("getIntentSender");
6887        // Refuse possible leaked file descriptors
6888        if (intents != null) {
6889            if (intents.length < 1) {
6890                throw new IllegalArgumentException("Intents array length must be >= 1");
6891            }
6892            for (int i=0; i<intents.length; i++) {
6893                Intent intent = intents[i];
6894                if (intent != null) {
6895                    if (intent.hasFileDescriptors()) {
6896                        throw new IllegalArgumentException("File descriptors passed in Intent");
6897                    }
6898                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6899                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6900                        throw new IllegalArgumentException(
6901                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6902                    }
6903                    intents[i] = new Intent(intent);
6904                }
6905            }
6906            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6907                throw new IllegalArgumentException(
6908                        "Intent array length does not match resolvedTypes length");
6909            }
6910        }
6911        if (bOptions != null) {
6912            if (bOptions.hasFileDescriptors()) {
6913                throw new IllegalArgumentException("File descriptors passed in options");
6914            }
6915        }
6916
6917        synchronized(this) {
6918            int callingUid = Binder.getCallingUid();
6919            int origUserId = userId;
6920            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6921                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6922                    ALLOW_NON_FULL, "getIntentSender", null);
6923            if (origUserId == UserHandle.USER_CURRENT) {
6924                // We don't want to evaluate this until the pending intent is
6925                // actually executed.  However, we do want to always do the
6926                // security checking for it above.
6927                userId = UserHandle.USER_CURRENT;
6928            }
6929            try {
6930                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6931                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6932                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6933                    if (!UserHandle.isSameApp(callingUid, uid)) {
6934                        String msg = "Permission Denial: getIntentSender() from pid="
6935                            + Binder.getCallingPid()
6936                            + ", uid=" + Binder.getCallingUid()
6937                            + ", (need uid=" + uid + ")"
6938                            + " is not allowed to send as package " + packageName;
6939                        Slog.w(TAG, msg);
6940                        throw new SecurityException(msg);
6941                    }
6942                }
6943
6944                return getIntentSenderLocked(type, packageName, callingUid, userId,
6945                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6946
6947            } catch (RemoteException e) {
6948                throw new SecurityException(e);
6949            }
6950        }
6951    }
6952
6953    IIntentSender getIntentSenderLocked(int type, String packageName,
6954            int callingUid, int userId, IBinder token, String resultWho,
6955            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6956            Bundle bOptions) {
6957        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6958        ActivityRecord activity = null;
6959        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6960            activity = ActivityRecord.isInStackLocked(token);
6961            if (activity == null) {
6962                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6963                return null;
6964            }
6965            if (activity.finishing) {
6966                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6967                return null;
6968            }
6969        }
6970
6971        // We're going to be splicing together extras before sending, so we're
6972        // okay poking into any contained extras.
6973        if (intents != null) {
6974            for (int i = 0; i < intents.length; i++) {
6975                intents[i].setDefusable(true);
6976            }
6977        }
6978        Bundle.setDefusable(bOptions, true);
6979
6980        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6981        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6982        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6983        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6984                |PendingIntent.FLAG_UPDATE_CURRENT);
6985
6986        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6987                type, packageName, activity, resultWho,
6988                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6989        WeakReference<PendingIntentRecord> ref;
6990        ref = mIntentSenderRecords.get(key);
6991        PendingIntentRecord rec = ref != null ? ref.get() : null;
6992        if (rec != null) {
6993            if (!cancelCurrent) {
6994                if (updateCurrent) {
6995                    if (rec.key.requestIntent != null) {
6996                        rec.key.requestIntent.replaceExtras(intents != null ?
6997                                intents[intents.length - 1] : null);
6998                    }
6999                    if (intents != null) {
7000                        intents[intents.length-1] = rec.key.requestIntent;
7001                        rec.key.allIntents = intents;
7002                        rec.key.allResolvedTypes = resolvedTypes;
7003                    } else {
7004                        rec.key.allIntents = null;
7005                        rec.key.allResolvedTypes = null;
7006                    }
7007                }
7008                return rec;
7009            }
7010            rec.canceled = true;
7011            mIntentSenderRecords.remove(key);
7012        }
7013        if (noCreate) {
7014            return rec;
7015        }
7016        rec = new PendingIntentRecord(this, key, callingUid);
7017        mIntentSenderRecords.put(key, rec.ref);
7018        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7019            if (activity.pendingResults == null) {
7020                activity.pendingResults
7021                        = new HashSet<WeakReference<PendingIntentRecord>>();
7022            }
7023            activity.pendingResults.add(rec.ref);
7024        }
7025        return rec;
7026    }
7027
7028    @Override
7029    public void cancelIntentSender(IIntentSender sender) {
7030        if (!(sender instanceof PendingIntentRecord)) {
7031            return;
7032        }
7033        synchronized(this) {
7034            PendingIntentRecord rec = (PendingIntentRecord)sender;
7035            try {
7036                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7037                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7038                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7039                    String msg = "Permission Denial: cancelIntentSender() from pid="
7040                        + Binder.getCallingPid()
7041                        + ", uid=" + Binder.getCallingUid()
7042                        + " is not allowed to cancel packges "
7043                        + rec.key.packageName;
7044                    Slog.w(TAG, msg);
7045                    throw new SecurityException(msg);
7046                }
7047            } catch (RemoteException e) {
7048                throw new SecurityException(e);
7049            }
7050            cancelIntentSenderLocked(rec, true);
7051        }
7052    }
7053
7054    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7055        rec.canceled = true;
7056        mIntentSenderRecords.remove(rec.key);
7057        if (cleanActivity && rec.key.activity != null) {
7058            rec.key.activity.pendingResults.remove(rec.ref);
7059        }
7060    }
7061
7062    @Override
7063    public String getPackageForIntentSender(IIntentSender pendingResult) {
7064        if (!(pendingResult instanceof PendingIntentRecord)) {
7065            return null;
7066        }
7067        try {
7068            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7069            return res.key.packageName;
7070        } catch (ClassCastException e) {
7071        }
7072        return null;
7073    }
7074
7075    @Override
7076    public int getUidForIntentSender(IIntentSender sender) {
7077        if (sender instanceof PendingIntentRecord) {
7078            try {
7079                PendingIntentRecord res = (PendingIntentRecord)sender;
7080                return res.uid;
7081            } catch (ClassCastException e) {
7082            }
7083        }
7084        return -1;
7085    }
7086
7087    @Override
7088    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7089        if (!(pendingResult instanceof PendingIntentRecord)) {
7090            return false;
7091        }
7092        try {
7093            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7094            if (res.key.allIntents == null) {
7095                return false;
7096            }
7097            for (int i=0; i<res.key.allIntents.length; i++) {
7098                Intent intent = res.key.allIntents[i];
7099                if (intent.getPackage() != null && intent.getComponent() != null) {
7100                    return false;
7101                }
7102            }
7103            return true;
7104        } catch (ClassCastException e) {
7105        }
7106        return false;
7107    }
7108
7109    @Override
7110    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7111        if (!(pendingResult instanceof PendingIntentRecord)) {
7112            return false;
7113        }
7114        try {
7115            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7116            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7117                return true;
7118            }
7119            return false;
7120        } catch (ClassCastException e) {
7121        }
7122        return false;
7123    }
7124
7125    @Override
7126    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7127        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7128                "getIntentForIntentSender()");
7129        if (!(pendingResult instanceof PendingIntentRecord)) {
7130            return null;
7131        }
7132        try {
7133            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7134            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7135        } catch (ClassCastException e) {
7136        }
7137        return null;
7138    }
7139
7140    @Override
7141    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7142        if (!(pendingResult instanceof PendingIntentRecord)) {
7143            return null;
7144        }
7145        try {
7146            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7147            synchronized (this) {
7148                return getTagForIntentSenderLocked(res, prefix);
7149            }
7150        } catch (ClassCastException e) {
7151        }
7152        return null;
7153    }
7154
7155    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7156        final Intent intent = res.key.requestIntent;
7157        if (intent != null) {
7158            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7159                    || res.lastTagPrefix.equals(prefix))) {
7160                return res.lastTag;
7161            }
7162            res.lastTagPrefix = prefix;
7163            final StringBuilder sb = new StringBuilder(128);
7164            if (prefix != null) {
7165                sb.append(prefix);
7166            }
7167            if (intent.getAction() != null) {
7168                sb.append(intent.getAction());
7169            } else if (intent.getComponent() != null) {
7170                intent.getComponent().appendShortString(sb);
7171            } else {
7172                sb.append("?");
7173            }
7174            return res.lastTag = sb.toString();
7175        }
7176        return null;
7177    }
7178
7179    @Override
7180    public void setProcessLimit(int max) {
7181        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7182                "setProcessLimit()");
7183        synchronized (this) {
7184            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7185            mProcessLimitOverride = max;
7186        }
7187        trimApplications();
7188    }
7189
7190    @Override
7191    public int getProcessLimit() {
7192        synchronized (this) {
7193            return mProcessLimitOverride;
7194        }
7195    }
7196
7197    void foregroundTokenDied(ForegroundToken token) {
7198        synchronized (ActivityManagerService.this) {
7199            synchronized (mPidsSelfLocked) {
7200                ForegroundToken cur
7201                    = mForegroundProcesses.get(token.pid);
7202                if (cur != token) {
7203                    return;
7204                }
7205                mForegroundProcesses.remove(token.pid);
7206                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7207                if (pr == null) {
7208                    return;
7209                }
7210                pr.forcingToForeground = null;
7211                updateProcessForegroundLocked(pr, false, false);
7212            }
7213            updateOomAdjLocked();
7214        }
7215    }
7216
7217    @Override
7218    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7219        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7220                "setProcessForeground()");
7221        synchronized(this) {
7222            boolean changed = false;
7223
7224            synchronized (mPidsSelfLocked) {
7225                ProcessRecord pr = mPidsSelfLocked.get(pid);
7226                if (pr == null && isForeground) {
7227                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7228                    return;
7229                }
7230                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7231                if (oldToken != null) {
7232                    oldToken.token.unlinkToDeath(oldToken, 0);
7233                    mForegroundProcesses.remove(pid);
7234                    if (pr != null) {
7235                        pr.forcingToForeground = null;
7236                    }
7237                    changed = true;
7238                }
7239                if (isForeground && token != null) {
7240                    ForegroundToken newToken = new ForegroundToken() {
7241                        @Override
7242                        public void binderDied() {
7243                            foregroundTokenDied(this);
7244                        }
7245                    };
7246                    newToken.pid = pid;
7247                    newToken.token = token;
7248                    try {
7249                        token.linkToDeath(newToken, 0);
7250                        mForegroundProcesses.put(pid, newToken);
7251                        pr.forcingToForeground = token;
7252                        changed = true;
7253                    } catch (RemoteException e) {
7254                        // If the process died while doing this, we will later
7255                        // do the cleanup with the process death link.
7256                    }
7257                }
7258            }
7259
7260            if (changed) {
7261                updateOomAdjLocked();
7262            }
7263        }
7264    }
7265
7266    @Override
7267    public boolean isAppForeground(int uid) throws RemoteException {
7268        synchronized (this) {
7269            UidRecord uidRec = mActiveUids.get(uid);
7270            if (uidRec == null || uidRec.idle) {
7271                return false;
7272            }
7273            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7274        }
7275    }
7276
7277    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7278    // be guarded by permission checking.
7279    int getUidState(int uid) {
7280        synchronized (this) {
7281            UidRecord uidRec = mActiveUids.get(uid);
7282            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7283        }
7284    }
7285
7286    @Override
7287    public boolean isInMultiWindowMode(IBinder token) {
7288        final long origId = Binder.clearCallingIdentity();
7289        try {
7290            synchronized(this) {
7291                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7292                if (r == null) {
7293                    return false;
7294                }
7295                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7296                return !r.task.mFullscreen;
7297            }
7298        } finally {
7299            Binder.restoreCallingIdentity(origId);
7300        }
7301    }
7302
7303    @Override
7304    public boolean isInPictureInPictureMode(IBinder token) {
7305        final long origId = Binder.clearCallingIdentity();
7306        try {
7307            synchronized(this) {
7308                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7309                if (stack == null) {
7310                    return false;
7311                }
7312                return stack.mStackId == PINNED_STACK_ID;
7313            }
7314        } finally {
7315            Binder.restoreCallingIdentity(origId);
7316        }
7317    }
7318
7319    @Override
7320    public void enterPictureInPictureMode(IBinder token) {
7321        final long origId = Binder.clearCallingIdentity();
7322        try {
7323            synchronized(this) {
7324                if (!mSupportsPictureInPicture) {
7325                    throw new IllegalStateException("enterPictureInPictureMode: "
7326                            + "Device doesn't support picture-in-picture mode.");
7327                }
7328
7329                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7330
7331                if (r == null) {
7332                    throw new IllegalStateException("enterPictureInPictureMode: "
7333                            + "Can't find activity for token=" + token);
7334                }
7335
7336                if (!r.supportsPictureInPicture()) {
7337                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7338                            + "Picture-In-Picture not supported for r=" + r);
7339                }
7340
7341                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7342                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7343                        ? mDefaultPinnedStackBounds : null;
7344
7345                mStackSupervisor.moveActivityToPinnedStackLocked(
7346                        r, "enterPictureInPictureMode", bounds);
7347            }
7348        } finally {
7349            Binder.restoreCallingIdentity(origId);
7350        }
7351    }
7352
7353    // =========================================================
7354    // PROCESS INFO
7355    // =========================================================
7356
7357    static class ProcessInfoService extends IProcessInfoService.Stub {
7358        final ActivityManagerService mActivityManagerService;
7359        ProcessInfoService(ActivityManagerService activityManagerService) {
7360            mActivityManagerService = activityManagerService;
7361        }
7362
7363        @Override
7364        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7365            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7366                    /*in*/ pids, /*out*/ states, null);
7367        }
7368
7369        @Override
7370        public void getProcessStatesAndOomScoresFromPids(
7371                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7372            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7373                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7374        }
7375    }
7376
7377    /**
7378     * For each PID in the given input array, write the current process state
7379     * for that process into the states array, or -1 to indicate that no
7380     * process with the given PID exists. If scores array is provided, write
7381     * the oom score for the process into the scores array, with INVALID_ADJ
7382     * indicating the PID doesn't exist.
7383     */
7384    public void getProcessStatesAndOomScoresForPIDs(
7385            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7386        if (scores != null) {
7387            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7388                    "getProcessStatesAndOomScoresForPIDs()");
7389        }
7390
7391        if (pids == null) {
7392            throw new NullPointerException("pids");
7393        } else if (states == null) {
7394            throw new NullPointerException("states");
7395        } else if (pids.length != states.length) {
7396            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7397        } else if (scores != null && pids.length != scores.length) {
7398            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7399        }
7400
7401        synchronized (mPidsSelfLocked) {
7402            for (int i = 0; i < pids.length; i++) {
7403                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7404                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7405                        pr.curProcState;
7406                if (scores != null) {
7407                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7408                }
7409            }
7410        }
7411    }
7412
7413    // =========================================================
7414    // PERMISSIONS
7415    // =========================================================
7416
7417    static class PermissionController extends IPermissionController.Stub {
7418        ActivityManagerService mActivityManagerService;
7419        PermissionController(ActivityManagerService activityManagerService) {
7420            mActivityManagerService = activityManagerService;
7421        }
7422
7423        @Override
7424        public boolean checkPermission(String permission, int pid, int uid) {
7425            return mActivityManagerService.checkPermission(permission, pid,
7426                    uid) == PackageManager.PERMISSION_GRANTED;
7427        }
7428
7429        @Override
7430        public String[] getPackagesForUid(int uid) {
7431            return mActivityManagerService.mContext.getPackageManager()
7432                    .getPackagesForUid(uid);
7433        }
7434
7435        @Override
7436        public boolean isRuntimePermission(String permission) {
7437            try {
7438                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7439                        .getPermissionInfo(permission, 0);
7440                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7441            } catch (NameNotFoundException nnfe) {
7442                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7443            }
7444            return false;
7445        }
7446    }
7447
7448    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7449        @Override
7450        public int checkComponentPermission(String permission, int pid, int uid,
7451                int owningUid, boolean exported) {
7452            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7453                    owningUid, exported);
7454        }
7455
7456        @Override
7457        public Object getAMSLock() {
7458            return ActivityManagerService.this;
7459        }
7460    }
7461
7462    /**
7463     * This can be called with or without the global lock held.
7464     */
7465    int checkComponentPermission(String permission, int pid, int uid,
7466            int owningUid, boolean exported) {
7467        if (pid == MY_PID) {
7468            return PackageManager.PERMISSION_GRANTED;
7469        }
7470        return ActivityManager.checkComponentPermission(permission, uid,
7471                owningUid, exported);
7472    }
7473
7474    /**
7475     * As the only public entry point for permissions checking, this method
7476     * can enforce the semantic that requesting a check on a null global
7477     * permission is automatically denied.  (Internally a null permission
7478     * string is used when calling {@link #checkComponentPermission} in cases
7479     * when only uid-based security is needed.)
7480     *
7481     * This can be called with or without the global lock held.
7482     */
7483    @Override
7484    public int checkPermission(String permission, int pid, int uid) {
7485        if (permission == null) {
7486            return PackageManager.PERMISSION_DENIED;
7487        }
7488        return checkComponentPermission(permission, pid, uid, -1, true);
7489    }
7490
7491    @Override
7492    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7493        if (permission == null) {
7494            return PackageManager.PERMISSION_DENIED;
7495        }
7496
7497        // We might be performing an operation on behalf of an indirect binder
7498        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7499        // client identity accordingly before proceeding.
7500        Identity tlsIdentity = sCallerIdentity.get();
7501        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7502            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7503                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7504            uid = tlsIdentity.uid;
7505            pid = tlsIdentity.pid;
7506        }
7507
7508        return checkComponentPermission(permission, pid, uid, -1, true);
7509    }
7510
7511    /**
7512     * Binder IPC calls go through the public entry point.
7513     * This can be called with or without the global lock held.
7514     */
7515    int checkCallingPermission(String permission) {
7516        return checkPermission(permission,
7517                Binder.getCallingPid(),
7518                UserHandle.getAppId(Binder.getCallingUid()));
7519    }
7520
7521    /**
7522     * This can be called with or without the global lock held.
7523     */
7524    void enforceCallingPermission(String permission, String func) {
7525        if (checkCallingPermission(permission)
7526                == PackageManager.PERMISSION_GRANTED) {
7527            return;
7528        }
7529
7530        String msg = "Permission Denial: " + func + " from pid="
7531                + Binder.getCallingPid()
7532                + ", uid=" + Binder.getCallingUid()
7533                + " requires " + permission;
7534        Slog.w(TAG, msg);
7535        throw new SecurityException(msg);
7536    }
7537
7538    /**
7539     * Determine if UID is holding permissions required to access {@link Uri} in
7540     * the given {@link ProviderInfo}. Final permission checking is always done
7541     * in {@link ContentProvider}.
7542     */
7543    private final boolean checkHoldingPermissionsLocked(
7544            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7545        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7546                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7547        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7548            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7549                    != PERMISSION_GRANTED) {
7550                return false;
7551            }
7552        }
7553        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7554    }
7555
7556    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7557            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7558        if (pi.applicationInfo.uid == uid) {
7559            return true;
7560        } else if (!pi.exported) {
7561            return false;
7562        }
7563
7564        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7565        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7566        try {
7567            // check if target holds top-level <provider> permissions
7568            if (!readMet && pi.readPermission != null && considerUidPermissions
7569                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7570                readMet = true;
7571            }
7572            if (!writeMet && pi.writePermission != null && considerUidPermissions
7573                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7574                writeMet = true;
7575            }
7576
7577            // track if unprotected read/write is allowed; any denied
7578            // <path-permission> below removes this ability
7579            boolean allowDefaultRead = pi.readPermission == null;
7580            boolean allowDefaultWrite = pi.writePermission == null;
7581
7582            // check if target holds any <path-permission> that match uri
7583            final PathPermission[] pps = pi.pathPermissions;
7584            if (pps != null) {
7585                final String path = grantUri.uri.getPath();
7586                int i = pps.length;
7587                while (i > 0 && (!readMet || !writeMet)) {
7588                    i--;
7589                    PathPermission pp = pps[i];
7590                    if (pp.match(path)) {
7591                        if (!readMet) {
7592                            final String pprperm = pp.getReadPermission();
7593                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7594                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7595                                    + ": match=" + pp.match(path)
7596                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7597                            if (pprperm != null) {
7598                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7599                                        == PERMISSION_GRANTED) {
7600                                    readMet = true;
7601                                } else {
7602                                    allowDefaultRead = false;
7603                                }
7604                            }
7605                        }
7606                        if (!writeMet) {
7607                            final String ppwperm = pp.getWritePermission();
7608                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7609                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7610                                    + ": match=" + pp.match(path)
7611                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7612                            if (ppwperm != null) {
7613                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7614                                        == PERMISSION_GRANTED) {
7615                                    writeMet = true;
7616                                } else {
7617                                    allowDefaultWrite = false;
7618                                }
7619                            }
7620                        }
7621                    }
7622                }
7623            }
7624
7625            // grant unprotected <provider> read/write, if not blocked by
7626            // <path-permission> above
7627            if (allowDefaultRead) readMet = true;
7628            if (allowDefaultWrite) writeMet = true;
7629
7630        } catch (RemoteException e) {
7631            return false;
7632        }
7633
7634        return readMet && writeMet;
7635    }
7636
7637    public int getAppStartMode(int uid, String packageName) {
7638        synchronized (this) {
7639            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7640        }
7641    }
7642
7643    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7644            boolean allowWhenForeground) {
7645        UidRecord uidRec = mActiveUids.get(uid);
7646        if (!mLenientBackgroundCheck) {
7647            if (!allowWhenForeground || uidRec == null
7648                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7649                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7650                        packageName) != AppOpsManager.MODE_ALLOWED) {
7651                    return ActivityManager.APP_START_MODE_DELAYED;
7652                }
7653            }
7654
7655        } else if (uidRec == null || uidRec.idle) {
7656            if (callingPid >= 0) {
7657                ProcessRecord proc;
7658                synchronized (mPidsSelfLocked) {
7659                    proc = mPidsSelfLocked.get(callingPid);
7660                }
7661                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7662                    // Whoever is instigating this is in the foreground, so we will allow it
7663                    // to go through.
7664                    return ActivityManager.APP_START_MODE_NORMAL;
7665                }
7666            }
7667            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7668                    != AppOpsManager.MODE_ALLOWED) {
7669                return ActivityManager.APP_START_MODE_DELAYED;
7670            }
7671        }
7672        return ActivityManager.APP_START_MODE_NORMAL;
7673    }
7674
7675    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7676        ProviderInfo pi = null;
7677        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7678        if (cpr != null) {
7679            pi = cpr.info;
7680        } else {
7681            try {
7682                pi = AppGlobals.getPackageManager().resolveContentProvider(
7683                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7684            } catch (RemoteException ex) {
7685            }
7686        }
7687        return pi;
7688    }
7689
7690    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7691        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7692        if (targetUris != null) {
7693            return targetUris.get(grantUri);
7694        }
7695        return null;
7696    }
7697
7698    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7699            String targetPkg, int targetUid, GrantUri grantUri) {
7700        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7701        if (targetUris == null) {
7702            targetUris = Maps.newArrayMap();
7703            mGrantedUriPermissions.put(targetUid, targetUris);
7704        }
7705
7706        UriPermission perm = targetUris.get(grantUri);
7707        if (perm == null) {
7708            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7709            targetUris.put(grantUri, perm);
7710        }
7711
7712        return perm;
7713    }
7714
7715    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7716            final int modeFlags) {
7717        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7718        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7719                : UriPermission.STRENGTH_OWNED;
7720
7721        // Root gets to do everything.
7722        if (uid == 0) {
7723            return true;
7724        }
7725
7726        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7727        if (perms == null) return false;
7728
7729        // First look for exact match
7730        final UriPermission exactPerm = perms.get(grantUri);
7731        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7732            return true;
7733        }
7734
7735        // No exact match, look for prefixes
7736        final int N = perms.size();
7737        for (int i = 0; i < N; i++) {
7738            final UriPermission perm = perms.valueAt(i);
7739            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7740                    && perm.getStrength(modeFlags) >= minStrength) {
7741                return true;
7742            }
7743        }
7744
7745        return false;
7746    }
7747
7748    /**
7749     * @param uri This uri must NOT contain an embedded userId.
7750     * @param userId The userId in which the uri is to be resolved.
7751     */
7752    @Override
7753    public int checkUriPermission(Uri uri, int pid, int uid,
7754            final int modeFlags, int userId, IBinder callerToken) {
7755        enforceNotIsolatedCaller("checkUriPermission");
7756
7757        // Another redirected-binder-call permissions check as in
7758        // {@link checkPermissionWithToken}.
7759        Identity tlsIdentity = sCallerIdentity.get();
7760        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7761            uid = tlsIdentity.uid;
7762            pid = tlsIdentity.pid;
7763        }
7764
7765        // Our own process gets to do everything.
7766        if (pid == MY_PID) {
7767            return PackageManager.PERMISSION_GRANTED;
7768        }
7769        synchronized (this) {
7770            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7771                    ? PackageManager.PERMISSION_GRANTED
7772                    : PackageManager.PERMISSION_DENIED;
7773        }
7774    }
7775
7776    /**
7777     * Check if the targetPkg can be granted permission to access uri by
7778     * the callingUid using the given modeFlags.  Throws a security exception
7779     * if callingUid is not allowed to do this.  Returns the uid of the target
7780     * if the URI permission grant should be performed; returns -1 if it is not
7781     * needed (for example targetPkg already has permission to access the URI).
7782     * If you already know the uid of the target, you can supply it in
7783     * lastTargetUid else set that to -1.
7784     */
7785    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7786            final int modeFlags, int lastTargetUid) {
7787        if (!Intent.isAccessUriMode(modeFlags)) {
7788            return -1;
7789        }
7790
7791        if (targetPkg != null) {
7792            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7793                    "Checking grant " + targetPkg + " permission to " + grantUri);
7794        }
7795
7796        final IPackageManager pm = AppGlobals.getPackageManager();
7797
7798        // If this is not a content: uri, we can't do anything with it.
7799        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7800            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7801                    "Can't grant URI permission for non-content URI: " + grantUri);
7802            return -1;
7803        }
7804
7805        final String authority = grantUri.uri.getAuthority();
7806        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7807        if (pi == null) {
7808            Slog.w(TAG, "No content provider found for permission check: " +
7809                    grantUri.uri.toSafeString());
7810            return -1;
7811        }
7812
7813        int targetUid = lastTargetUid;
7814        if (targetUid < 0 && targetPkg != null) {
7815            try {
7816                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7817                        UserHandle.getUserId(callingUid));
7818                if (targetUid < 0) {
7819                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7820                            "Can't grant URI permission no uid for: " + targetPkg);
7821                    return -1;
7822                }
7823            } catch (RemoteException ex) {
7824                return -1;
7825            }
7826        }
7827
7828        if (targetUid >= 0) {
7829            // First...  does the target actually need this permission?
7830            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7831                // No need to grant the target this permission.
7832                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7833                        "Target " + targetPkg + " already has full permission to " + grantUri);
7834                return -1;
7835            }
7836        } else {
7837            // First...  there is no target package, so can anyone access it?
7838            boolean allowed = pi.exported;
7839            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7840                if (pi.readPermission != null) {
7841                    allowed = false;
7842                }
7843            }
7844            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7845                if (pi.writePermission != null) {
7846                    allowed = false;
7847                }
7848            }
7849            if (allowed) {
7850                return -1;
7851            }
7852        }
7853
7854        /* There is a special cross user grant if:
7855         * - The target is on another user.
7856         * - Apps on the current user can access the uri without any uid permissions.
7857         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7858         * grant uri permissions.
7859         */
7860        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7861                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7862                modeFlags, false /*without considering the uid permissions*/);
7863
7864        // Second...  is the provider allowing granting of URI permissions?
7865        if (!specialCrossUserGrant) {
7866            if (!pi.grantUriPermissions) {
7867                throw new SecurityException("Provider " + pi.packageName
7868                        + "/" + pi.name
7869                        + " does not allow granting of Uri permissions (uri "
7870                        + grantUri + ")");
7871            }
7872            if (pi.uriPermissionPatterns != null) {
7873                final int N = pi.uriPermissionPatterns.length;
7874                boolean allowed = false;
7875                for (int i=0; i<N; i++) {
7876                    if (pi.uriPermissionPatterns[i] != null
7877                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7878                        allowed = true;
7879                        break;
7880                    }
7881                }
7882                if (!allowed) {
7883                    throw new SecurityException("Provider " + pi.packageName
7884                            + "/" + pi.name
7885                            + " does not allow granting of permission to path of Uri "
7886                            + grantUri);
7887                }
7888            }
7889        }
7890
7891        // Third...  does the caller itself have permission to access
7892        // this uri?
7893        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7894            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7895                // Require they hold a strong enough Uri permission
7896                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7897                    throw new SecurityException("Uid " + callingUid
7898                            + " does not have permission to uri " + grantUri);
7899                }
7900            }
7901        }
7902        return targetUid;
7903    }
7904
7905    /**
7906     * @param uri This uri must NOT contain an embedded userId.
7907     * @param userId The userId in which the uri is to be resolved.
7908     */
7909    @Override
7910    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7911            final int modeFlags, int userId) {
7912        enforceNotIsolatedCaller("checkGrantUriPermission");
7913        synchronized(this) {
7914            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7915                    new GrantUri(userId, uri, false), modeFlags, -1);
7916        }
7917    }
7918
7919    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7920            final int modeFlags, UriPermissionOwner owner) {
7921        if (!Intent.isAccessUriMode(modeFlags)) {
7922            return;
7923        }
7924
7925        // So here we are: the caller has the assumed permission
7926        // to the uri, and the target doesn't.  Let's now give this to
7927        // the target.
7928
7929        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7930                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7931
7932        final String authority = grantUri.uri.getAuthority();
7933        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7934        if (pi == null) {
7935            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7936            return;
7937        }
7938
7939        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7940            grantUri.prefix = true;
7941        }
7942        final UriPermission perm = findOrCreateUriPermissionLocked(
7943                pi.packageName, targetPkg, targetUid, grantUri);
7944        perm.grantModes(modeFlags, owner);
7945    }
7946
7947    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7948            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7949        if (targetPkg == null) {
7950            throw new NullPointerException("targetPkg");
7951        }
7952        int targetUid;
7953        final IPackageManager pm = AppGlobals.getPackageManager();
7954        try {
7955            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7956        } catch (RemoteException ex) {
7957            return;
7958        }
7959
7960        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7961                targetUid);
7962        if (targetUid < 0) {
7963            return;
7964        }
7965
7966        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7967                owner);
7968    }
7969
7970    static class NeededUriGrants extends ArrayList<GrantUri> {
7971        final String targetPkg;
7972        final int targetUid;
7973        final int flags;
7974
7975        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7976            this.targetPkg = targetPkg;
7977            this.targetUid = targetUid;
7978            this.flags = flags;
7979        }
7980    }
7981
7982    /**
7983     * Like checkGrantUriPermissionLocked, but takes an Intent.
7984     */
7985    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7986            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7987        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7988                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7989                + " clip=" + (intent != null ? intent.getClipData() : null)
7990                + " from " + intent + "; flags=0x"
7991                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7992
7993        if (targetPkg == null) {
7994            throw new NullPointerException("targetPkg");
7995        }
7996
7997        if (intent == null) {
7998            return null;
7999        }
8000        Uri data = intent.getData();
8001        ClipData clip = intent.getClipData();
8002        if (data == null && clip == null) {
8003            return null;
8004        }
8005        // Default userId for uris in the intent (if they don't specify it themselves)
8006        int contentUserHint = intent.getContentUserHint();
8007        if (contentUserHint == UserHandle.USER_CURRENT) {
8008            contentUserHint = UserHandle.getUserId(callingUid);
8009        }
8010        final IPackageManager pm = AppGlobals.getPackageManager();
8011        int targetUid;
8012        if (needed != null) {
8013            targetUid = needed.targetUid;
8014        } else {
8015            try {
8016                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8017                        targetUserId);
8018            } catch (RemoteException ex) {
8019                return null;
8020            }
8021            if (targetUid < 0) {
8022                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8023                        "Can't grant URI permission no uid for: " + targetPkg
8024                        + " on user " + targetUserId);
8025                return null;
8026            }
8027        }
8028        if (data != null) {
8029            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8030            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8031                    targetUid);
8032            if (targetUid > 0) {
8033                if (needed == null) {
8034                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8035                }
8036                needed.add(grantUri);
8037            }
8038        }
8039        if (clip != null) {
8040            for (int i=0; i<clip.getItemCount(); i++) {
8041                Uri uri = clip.getItemAt(i).getUri();
8042                if (uri != null) {
8043                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8044                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8045                            targetUid);
8046                    if (targetUid > 0) {
8047                        if (needed == null) {
8048                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8049                        }
8050                        needed.add(grantUri);
8051                    }
8052                } else {
8053                    Intent clipIntent = clip.getItemAt(i).getIntent();
8054                    if (clipIntent != null) {
8055                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8056                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8057                        if (newNeeded != null) {
8058                            needed = newNeeded;
8059                        }
8060                    }
8061                }
8062            }
8063        }
8064
8065        return needed;
8066    }
8067
8068    /**
8069     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8070     */
8071    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8072            UriPermissionOwner owner) {
8073        if (needed != null) {
8074            for (int i=0; i<needed.size(); i++) {
8075                GrantUri grantUri = needed.get(i);
8076                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8077                        grantUri, needed.flags, owner);
8078            }
8079        }
8080    }
8081
8082    void grantUriPermissionFromIntentLocked(int callingUid,
8083            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8084        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8085                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8086        if (needed == null) {
8087            return;
8088        }
8089
8090        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8091    }
8092
8093    /**
8094     * @param uri This uri must NOT contain an embedded userId.
8095     * @param userId The userId in which the uri is to be resolved.
8096     */
8097    @Override
8098    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8099            final int modeFlags, int userId) {
8100        enforceNotIsolatedCaller("grantUriPermission");
8101        GrantUri grantUri = new GrantUri(userId, uri, false);
8102        synchronized(this) {
8103            final ProcessRecord r = getRecordForAppLocked(caller);
8104            if (r == null) {
8105                throw new SecurityException("Unable to find app for caller "
8106                        + caller
8107                        + " when granting permission to uri " + grantUri);
8108            }
8109            if (targetPkg == null) {
8110                throw new IllegalArgumentException("null target");
8111            }
8112            if (grantUri == null) {
8113                throw new IllegalArgumentException("null uri");
8114            }
8115
8116            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8117                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8118                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8119                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8120
8121            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8122                    UserHandle.getUserId(r.uid));
8123        }
8124    }
8125
8126    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8127        if (perm.modeFlags == 0) {
8128            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8129                    perm.targetUid);
8130            if (perms != null) {
8131                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8132                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8133
8134                perms.remove(perm.uri);
8135                if (perms.isEmpty()) {
8136                    mGrantedUriPermissions.remove(perm.targetUid);
8137                }
8138            }
8139        }
8140    }
8141
8142    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8143        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8144                "Revoking all granted permissions to " + grantUri);
8145
8146        final IPackageManager pm = AppGlobals.getPackageManager();
8147        final String authority = grantUri.uri.getAuthority();
8148        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8149        if (pi == null) {
8150            Slog.w(TAG, "No content provider found for permission revoke: "
8151                    + grantUri.toSafeString());
8152            return;
8153        }
8154
8155        // Does the caller have this permission on the URI?
8156        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8157            // If they don't have direct access to the URI, then revoke any
8158            // ownerless URI permissions that have been granted to them.
8159            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8160            if (perms != null) {
8161                boolean persistChanged = false;
8162                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8163                    final UriPermission perm = it.next();
8164                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8165                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8166                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8167                                "Revoking non-owned " + perm.targetUid
8168                                + " permission to " + perm.uri);
8169                        persistChanged |= perm.revokeModes(
8170                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8171                        if (perm.modeFlags == 0) {
8172                            it.remove();
8173                        }
8174                    }
8175                }
8176                if (perms.isEmpty()) {
8177                    mGrantedUriPermissions.remove(callingUid);
8178                }
8179                if (persistChanged) {
8180                    schedulePersistUriGrants();
8181                }
8182            }
8183            return;
8184        }
8185
8186        boolean persistChanged = false;
8187
8188        // Go through all of the permissions and remove any that match.
8189        int N = mGrantedUriPermissions.size();
8190        for (int i = 0; i < N; i++) {
8191            final int targetUid = mGrantedUriPermissions.keyAt(i);
8192            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8193
8194            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8195                final UriPermission perm = it.next();
8196                if (perm.uri.sourceUserId == grantUri.sourceUserId
8197                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8198                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8199                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8200                    persistChanged |= perm.revokeModes(
8201                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8202                    if (perm.modeFlags == 0) {
8203                        it.remove();
8204                    }
8205                }
8206            }
8207
8208            if (perms.isEmpty()) {
8209                mGrantedUriPermissions.remove(targetUid);
8210                N--;
8211                i--;
8212            }
8213        }
8214
8215        if (persistChanged) {
8216            schedulePersistUriGrants();
8217        }
8218    }
8219
8220    /**
8221     * @param uri This uri must NOT contain an embedded userId.
8222     * @param userId The userId in which the uri is to be resolved.
8223     */
8224    @Override
8225    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8226            int userId) {
8227        enforceNotIsolatedCaller("revokeUriPermission");
8228        synchronized(this) {
8229            final ProcessRecord r = getRecordForAppLocked(caller);
8230            if (r == null) {
8231                throw new SecurityException("Unable to find app for caller "
8232                        + caller
8233                        + " when revoking permission to uri " + uri);
8234            }
8235            if (uri == null) {
8236                Slog.w(TAG, "revokeUriPermission: null uri");
8237                return;
8238            }
8239
8240            if (!Intent.isAccessUriMode(modeFlags)) {
8241                return;
8242            }
8243
8244            final String authority = uri.getAuthority();
8245            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8246            if (pi == null) {
8247                Slog.w(TAG, "No content provider found for permission revoke: "
8248                        + uri.toSafeString());
8249                return;
8250            }
8251
8252            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8253        }
8254    }
8255
8256    /**
8257     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8258     * given package.
8259     *
8260     * @param packageName Package name to match, or {@code null} to apply to all
8261     *            packages.
8262     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8263     *            to all users.
8264     * @param persistable If persistable grants should be removed.
8265     */
8266    private void removeUriPermissionsForPackageLocked(
8267            String packageName, int userHandle, boolean persistable) {
8268        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8269            throw new IllegalArgumentException("Must narrow by either package or user");
8270        }
8271
8272        boolean persistChanged = false;
8273
8274        int N = mGrantedUriPermissions.size();
8275        for (int i = 0; i < N; i++) {
8276            final int targetUid = mGrantedUriPermissions.keyAt(i);
8277            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8278
8279            // Only inspect grants matching user
8280            if (userHandle == UserHandle.USER_ALL
8281                    || userHandle == UserHandle.getUserId(targetUid)) {
8282                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8283                    final UriPermission perm = it.next();
8284
8285                    // Only inspect grants matching package
8286                    if (packageName == null || perm.sourcePkg.equals(packageName)
8287                            || perm.targetPkg.equals(packageName)) {
8288                        persistChanged |= perm.revokeModes(persistable
8289                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8290
8291                        // Only remove when no modes remain; any persisted grants
8292                        // will keep this alive.
8293                        if (perm.modeFlags == 0) {
8294                            it.remove();
8295                        }
8296                    }
8297                }
8298
8299                if (perms.isEmpty()) {
8300                    mGrantedUriPermissions.remove(targetUid);
8301                    N--;
8302                    i--;
8303                }
8304            }
8305        }
8306
8307        if (persistChanged) {
8308            schedulePersistUriGrants();
8309        }
8310    }
8311
8312    @Override
8313    public IBinder newUriPermissionOwner(String name) {
8314        enforceNotIsolatedCaller("newUriPermissionOwner");
8315        synchronized(this) {
8316            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8317            return owner.getExternalTokenLocked();
8318        }
8319    }
8320
8321    @Override
8322    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8323        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8324        synchronized(this) {
8325            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8326            if (r == null) {
8327                throw new IllegalArgumentException("Activity does not exist; token="
8328                        + activityToken);
8329            }
8330            return r.getUriPermissionsLocked().getExternalTokenLocked();
8331        }
8332    }
8333    /**
8334     * @param uri This uri must NOT contain an embedded userId.
8335     * @param sourceUserId The userId in which the uri is to be resolved.
8336     * @param targetUserId The userId of the app that receives the grant.
8337     */
8338    @Override
8339    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8340            final int modeFlags, int sourceUserId, int targetUserId) {
8341        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8342                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8343                "grantUriPermissionFromOwner", null);
8344        synchronized(this) {
8345            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8346            if (owner == null) {
8347                throw new IllegalArgumentException("Unknown owner: " + token);
8348            }
8349            if (fromUid != Binder.getCallingUid()) {
8350                if (Binder.getCallingUid() != Process.myUid()) {
8351                    // Only system code can grant URI permissions on behalf
8352                    // of other users.
8353                    throw new SecurityException("nice try");
8354                }
8355            }
8356            if (targetPkg == null) {
8357                throw new IllegalArgumentException("null target");
8358            }
8359            if (uri == null) {
8360                throw new IllegalArgumentException("null uri");
8361            }
8362
8363            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8364                    modeFlags, owner, targetUserId);
8365        }
8366    }
8367
8368    /**
8369     * @param uri This uri must NOT contain an embedded userId.
8370     * @param userId The userId in which the uri is to be resolved.
8371     */
8372    @Override
8373    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8374        synchronized(this) {
8375            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8376            if (owner == null) {
8377                throw new IllegalArgumentException("Unknown owner: " + token);
8378            }
8379
8380            if (uri == null) {
8381                owner.removeUriPermissionsLocked(mode);
8382            } else {
8383                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8384            }
8385        }
8386    }
8387
8388    private void schedulePersistUriGrants() {
8389        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8390            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8391                    10 * DateUtils.SECOND_IN_MILLIS);
8392        }
8393    }
8394
8395    private void writeGrantedUriPermissions() {
8396        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8397
8398        // Snapshot permissions so we can persist without lock
8399        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8400        synchronized (this) {
8401            final int size = mGrantedUriPermissions.size();
8402            for (int i = 0; i < size; i++) {
8403                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8404                for (UriPermission perm : perms.values()) {
8405                    if (perm.persistedModeFlags != 0) {
8406                        persist.add(perm.snapshot());
8407                    }
8408                }
8409            }
8410        }
8411
8412        FileOutputStream fos = null;
8413        try {
8414            fos = mGrantFile.startWrite();
8415
8416            XmlSerializer out = new FastXmlSerializer();
8417            out.setOutput(fos, StandardCharsets.UTF_8.name());
8418            out.startDocument(null, true);
8419            out.startTag(null, TAG_URI_GRANTS);
8420            for (UriPermission.Snapshot perm : persist) {
8421                out.startTag(null, TAG_URI_GRANT);
8422                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8423                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8424                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8425                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8426                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8427                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8428                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8429                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8430                out.endTag(null, TAG_URI_GRANT);
8431            }
8432            out.endTag(null, TAG_URI_GRANTS);
8433            out.endDocument();
8434
8435            mGrantFile.finishWrite(fos);
8436        } catch (IOException e) {
8437            if (fos != null) {
8438                mGrantFile.failWrite(fos);
8439            }
8440        }
8441    }
8442
8443    private void readGrantedUriPermissionsLocked() {
8444        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8445
8446        final long now = System.currentTimeMillis();
8447
8448        FileInputStream fis = null;
8449        try {
8450            fis = mGrantFile.openRead();
8451            final XmlPullParser in = Xml.newPullParser();
8452            in.setInput(fis, StandardCharsets.UTF_8.name());
8453
8454            int type;
8455            while ((type = in.next()) != END_DOCUMENT) {
8456                final String tag = in.getName();
8457                if (type == START_TAG) {
8458                    if (TAG_URI_GRANT.equals(tag)) {
8459                        final int sourceUserId;
8460                        final int targetUserId;
8461                        final int userHandle = readIntAttribute(in,
8462                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8463                        if (userHandle != UserHandle.USER_NULL) {
8464                            // For backwards compatibility.
8465                            sourceUserId = userHandle;
8466                            targetUserId = userHandle;
8467                        } else {
8468                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8469                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8470                        }
8471                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8472                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8473                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8474                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8475                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8476                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8477
8478                        // Sanity check that provider still belongs to source package
8479                        final ProviderInfo pi = getProviderInfoLocked(
8480                                uri.getAuthority(), sourceUserId);
8481                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8482                            int targetUid = -1;
8483                            try {
8484                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8485                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8486                            } catch (RemoteException e) {
8487                            }
8488                            if (targetUid != -1) {
8489                                final UriPermission perm = findOrCreateUriPermissionLocked(
8490                                        sourcePkg, targetPkg, targetUid,
8491                                        new GrantUri(sourceUserId, uri, prefix));
8492                                perm.initPersistedModes(modeFlags, createdTime);
8493                            }
8494                        } else {
8495                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8496                                    + " but instead found " + pi);
8497                        }
8498                    }
8499                }
8500            }
8501        } catch (FileNotFoundException e) {
8502            // Missing grants is okay
8503        } catch (IOException e) {
8504            Slog.wtf(TAG, "Failed reading Uri grants", e);
8505        } catch (XmlPullParserException e) {
8506            Slog.wtf(TAG, "Failed reading Uri grants", e);
8507        } finally {
8508            IoUtils.closeQuietly(fis);
8509        }
8510    }
8511
8512    /**
8513     * @param uri This uri must NOT contain an embedded userId.
8514     * @param userId The userId in which the uri is to be resolved.
8515     */
8516    @Override
8517    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8518        enforceNotIsolatedCaller("takePersistableUriPermission");
8519
8520        Preconditions.checkFlagsArgument(modeFlags,
8521                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8522
8523        synchronized (this) {
8524            final int callingUid = Binder.getCallingUid();
8525            boolean persistChanged = false;
8526            GrantUri grantUri = new GrantUri(userId, uri, false);
8527
8528            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8529                    new GrantUri(userId, uri, false));
8530            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8531                    new GrantUri(userId, uri, true));
8532
8533            final boolean exactValid = (exactPerm != null)
8534                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8535            final boolean prefixValid = (prefixPerm != null)
8536                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8537
8538            if (!(exactValid || prefixValid)) {
8539                throw new SecurityException("No persistable permission grants found for UID "
8540                        + callingUid + " and Uri " + grantUri.toSafeString());
8541            }
8542
8543            if (exactValid) {
8544                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8545            }
8546            if (prefixValid) {
8547                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8548            }
8549
8550            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8551
8552            if (persistChanged) {
8553                schedulePersistUriGrants();
8554            }
8555        }
8556    }
8557
8558    /**
8559     * @param uri This uri must NOT contain an embedded userId.
8560     * @param userId The userId in which the uri is to be resolved.
8561     */
8562    @Override
8563    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8564        enforceNotIsolatedCaller("releasePersistableUriPermission");
8565
8566        Preconditions.checkFlagsArgument(modeFlags,
8567                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8568
8569        synchronized (this) {
8570            final int callingUid = Binder.getCallingUid();
8571            boolean persistChanged = false;
8572
8573            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8574                    new GrantUri(userId, uri, false));
8575            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8576                    new GrantUri(userId, uri, true));
8577            if (exactPerm == null && prefixPerm == null) {
8578                throw new SecurityException("No permission grants found for UID " + callingUid
8579                        + " and Uri " + uri.toSafeString());
8580            }
8581
8582            if (exactPerm != null) {
8583                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8584                removeUriPermissionIfNeededLocked(exactPerm);
8585            }
8586            if (prefixPerm != null) {
8587                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8588                removeUriPermissionIfNeededLocked(prefixPerm);
8589            }
8590
8591            if (persistChanged) {
8592                schedulePersistUriGrants();
8593            }
8594        }
8595    }
8596
8597    /**
8598     * Prune any older {@link UriPermission} for the given UID until outstanding
8599     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8600     *
8601     * @return if any mutations occured that require persisting.
8602     */
8603    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8604        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8605        if (perms == null) return false;
8606        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8607
8608        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8609        for (UriPermission perm : perms.values()) {
8610            if (perm.persistedModeFlags != 0) {
8611                persisted.add(perm);
8612            }
8613        }
8614
8615        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8616        if (trimCount <= 0) return false;
8617
8618        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8619        for (int i = 0; i < trimCount; i++) {
8620            final UriPermission perm = persisted.get(i);
8621
8622            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8623                    "Trimming grant created at " + perm.persistedCreateTime);
8624
8625            perm.releasePersistableModes(~0);
8626            removeUriPermissionIfNeededLocked(perm);
8627        }
8628
8629        return true;
8630    }
8631
8632    @Override
8633    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8634            String packageName, boolean incoming) {
8635        enforceNotIsolatedCaller("getPersistedUriPermissions");
8636        Preconditions.checkNotNull(packageName, "packageName");
8637
8638        final int callingUid = Binder.getCallingUid();
8639        final IPackageManager pm = AppGlobals.getPackageManager();
8640        try {
8641            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8642                    UserHandle.getUserId(callingUid));
8643            if (packageUid != callingUid) {
8644                throw new SecurityException(
8645                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8646            }
8647        } catch (RemoteException e) {
8648            throw new SecurityException("Failed to verify package name ownership");
8649        }
8650
8651        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8652        synchronized (this) {
8653            if (incoming) {
8654                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8655                        callingUid);
8656                if (perms == null) {
8657                    Slog.w(TAG, "No permission grants found for " + packageName);
8658                } else {
8659                    for (UriPermission perm : perms.values()) {
8660                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8661                            result.add(perm.buildPersistedPublicApiObject());
8662                        }
8663                    }
8664                }
8665            } else {
8666                final int size = mGrantedUriPermissions.size();
8667                for (int i = 0; i < size; i++) {
8668                    final ArrayMap<GrantUri, UriPermission> perms =
8669                            mGrantedUriPermissions.valueAt(i);
8670                    for (UriPermission perm : perms.values()) {
8671                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8672                            result.add(perm.buildPersistedPublicApiObject());
8673                        }
8674                    }
8675                }
8676            }
8677        }
8678        return new ParceledListSlice<android.content.UriPermission>(result);
8679    }
8680
8681    @Override
8682    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8683            String packageName, int userId) {
8684        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8685                "getGrantedUriPermissions");
8686
8687        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8688        synchronized (this) {
8689            final int size = mGrantedUriPermissions.size();
8690            for (int i = 0; i < size; i++) {
8691                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8692                for (UriPermission perm : perms.values()) {
8693                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8694                            && perm.persistedModeFlags != 0) {
8695                        result.add(perm.buildPersistedPublicApiObject());
8696                    }
8697                }
8698            }
8699        }
8700        return new ParceledListSlice<android.content.UriPermission>(result);
8701    }
8702
8703    @Override
8704    public void clearGrantedUriPermissions(String packageName, int userId) {
8705        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8706                "clearGrantedUriPermissions");
8707        removeUriPermissionsForPackageLocked(packageName, userId, true);
8708    }
8709
8710    @Override
8711    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8712        synchronized (this) {
8713            ProcessRecord app =
8714                who != null ? getRecordForAppLocked(who) : null;
8715            if (app == null) return;
8716
8717            Message msg = Message.obtain();
8718            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8719            msg.obj = app;
8720            msg.arg1 = waiting ? 1 : 0;
8721            mUiHandler.sendMessage(msg);
8722        }
8723    }
8724
8725    @Override
8726    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8727        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8728        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8729        outInfo.availMem = Process.getFreeMemory();
8730        outInfo.totalMem = Process.getTotalMemory();
8731        outInfo.threshold = homeAppMem;
8732        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8733        outInfo.hiddenAppThreshold = cachedAppMem;
8734        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8735                ProcessList.SERVICE_ADJ);
8736        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8737                ProcessList.VISIBLE_APP_ADJ);
8738        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8739                ProcessList.FOREGROUND_APP_ADJ);
8740    }
8741
8742    // =========================================================
8743    // TASK MANAGEMENT
8744    // =========================================================
8745
8746    @Override
8747    public List<IAppTask> getAppTasks(String callingPackage) {
8748        int callingUid = Binder.getCallingUid();
8749        long ident = Binder.clearCallingIdentity();
8750
8751        synchronized(this) {
8752            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8753            try {
8754                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8755
8756                final int N = mRecentTasks.size();
8757                for (int i = 0; i < N; i++) {
8758                    TaskRecord tr = mRecentTasks.get(i);
8759                    // Skip tasks that do not match the caller.  We don't need to verify
8760                    // callingPackage, because we are also limiting to callingUid and know
8761                    // that will limit to the correct security sandbox.
8762                    if (tr.effectiveUid != callingUid) {
8763                        continue;
8764                    }
8765                    Intent intent = tr.getBaseIntent();
8766                    if (intent == null ||
8767                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8768                        continue;
8769                    }
8770                    ActivityManager.RecentTaskInfo taskInfo =
8771                            createRecentTaskInfoFromTaskRecord(tr);
8772                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8773                    list.add(taskImpl);
8774                }
8775            } finally {
8776                Binder.restoreCallingIdentity(ident);
8777            }
8778            return list;
8779        }
8780    }
8781
8782    @Override
8783    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8784        final int callingUid = Binder.getCallingUid();
8785        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8786
8787        synchronized(this) {
8788            if (DEBUG_ALL) Slog.v(
8789                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8790
8791            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8792                    callingUid);
8793
8794            // TODO: Improve with MRU list from all ActivityStacks.
8795            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8796        }
8797
8798        return list;
8799    }
8800
8801    /**
8802     * Creates a new RecentTaskInfo from a TaskRecord.
8803     */
8804    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8805        // Update the task description to reflect any changes in the task stack
8806        tr.updateTaskDescription();
8807
8808        // Compose the recent task info
8809        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8810        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8811        rti.persistentId = tr.taskId;
8812        rti.baseIntent = new Intent(tr.getBaseIntent());
8813        rti.origActivity = tr.origActivity;
8814        rti.realActivity = tr.realActivity;
8815        rti.description = tr.lastDescription;
8816        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8817        rti.userId = tr.userId;
8818        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8819        rti.firstActiveTime = tr.firstActiveTime;
8820        rti.lastActiveTime = tr.lastActiveTime;
8821        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8822        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8823        rti.numActivities = 0;
8824        if (tr.mBounds != null) {
8825            rti.bounds = new Rect(tr.mBounds);
8826        }
8827        rti.isDockable = tr.canGoInDockedStack();
8828        rti.resizeMode = tr.mResizeMode;
8829
8830        ActivityRecord base = null;
8831        ActivityRecord top = null;
8832        ActivityRecord tmp;
8833
8834        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8835            tmp = tr.mActivities.get(i);
8836            if (tmp.finishing) {
8837                continue;
8838            }
8839            base = tmp;
8840            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8841                top = base;
8842            }
8843            rti.numActivities++;
8844        }
8845
8846        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8847        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8848
8849        return rti;
8850    }
8851
8852    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8853        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8854                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8855        if (!allowed) {
8856            if (checkPermission(android.Manifest.permission.GET_TASKS,
8857                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8858                // Temporary compatibility: some existing apps on the system image may
8859                // still be requesting the old permission and not switched to the new
8860                // one; if so, we'll still allow them full access.  This means we need
8861                // to see if they are holding the old permission and are a system app.
8862                try {
8863                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8864                        allowed = true;
8865                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8866                                + " is using old GET_TASKS but privileged; allowing");
8867                    }
8868                } catch (RemoteException e) {
8869                }
8870            }
8871        }
8872        if (!allowed) {
8873            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8874                    + " does not hold REAL_GET_TASKS; limiting output");
8875        }
8876        return allowed;
8877    }
8878
8879    @Override
8880    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8881        final int callingUid = Binder.getCallingUid();
8882        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8883                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8884
8885        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8886        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8887        synchronized (this) {
8888            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8889                    callingUid);
8890            final boolean detailed = checkCallingPermission(
8891                    android.Manifest.permission.GET_DETAILED_TASKS)
8892                    == PackageManager.PERMISSION_GRANTED;
8893
8894            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8895                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8896                return Collections.emptyList();
8897            }
8898            mRecentTasks.loadUserRecentsLocked(userId);
8899
8900            final int recentsCount = mRecentTasks.size();
8901            ArrayList<ActivityManager.RecentTaskInfo> res =
8902                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8903
8904            final Set<Integer> includedUsers;
8905            if (includeProfiles) {
8906                includedUsers = mUserController.getProfileIds(userId);
8907            } else {
8908                includedUsers = new HashSet<>();
8909            }
8910            includedUsers.add(Integer.valueOf(userId));
8911
8912            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8913                TaskRecord tr = mRecentTasks.get(i);
8914                // Only add calling user or related users recent tasks
8915                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8916                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8917                    continue;
8918                }
8919
8920                if (tr.realActivitySuspended) {
8921                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8922                    continue;
8923                }
8924
8925                // Return the entry if desired by the caller.  We always return
8926                // the first entry, because callers always expect this to be the
8927                // foreground app.  We may filter others if the caller has
8928                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8929                // we should exclude the entry.
8930
8931                if (i == 0
8932                        || withExcluded
8933                        || (tr.intent == null)
8934                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8935                                == 0)) {
8936                    if (!allowed) {
8937                        // If the caller doesn't have the GET_TASKS permission, then only
8938                        // allow them to see a small subset of tasks -- their own and home.
8939                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8940                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8941                            continue;
8942                        }
8943                    }
8944                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8945                        if (tr.stack != null && tr.stack.isHomeStack()) {
8946                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8947                                    "Skipping, home stack task: " + tr);
8948                            continue;
8949                        }
8950                    }
8951                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8952                        final ActivityStack stack = tr.stack;
8953                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8954                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8955                                    "Skipping, top task in docked stack: " + tr);
8956                            continue;
8957                        }
8958                    }
8959                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8960                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8961                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8962                                    "Skipping, pinned stack task: " + tr);
8963                            continue;
8964                        }
8965                    }
8966                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8967                        // Don't include auto remove tasks that are finished or finishing.
8968                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8969                                "Skipping, auto-remove without activity: " + tr);
8970                        continue;
8971                    }
8972                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8973                            && !tr.isAvailable) {
8974                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8975                                "Skipping, unavail real act: " + tr);
8976                        continue;
8977                    }
8978
8979                    if (!tr.mUserSetupComplete) {
8980                        // Don't include task launched while user is not done setting-up.
8981                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8982                                "Skipping, user setup not complete: " + tr);
8983                        continue;
8984                    }
8985
8986                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8987                    if (!detailed) {
8988                        rti.baseIntent.replaceExtras((Bundle)null);
8989                    }
8990
8991                    res.add(rti);
8992                    maxNum--;
8993                }
8994            }
8995            return res;
8996        }
8997    }
8998
8999    @Override
9000    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9001        synchronized (this) {
9002            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9003                    "getTaskThumbnail()");
9004            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9005                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9006            if (tr != null) {
9007                return tr.getTaskThumbnailLocked();
9008            }
9009        }
9010        return null;
9011    }
9012
9013    @Override
9014    public int addAppTask(IBinder activityToken, Intent intent,
9015            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9016        final int callingUid = Binder.getCallingUid();
9017        final long callingIdent = Binder.clearCallingIdentity();
9018
9019        try {
9020            synchronized (this) {
9021                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9022                if (r == null) {
9023                    throw new IllegalArgumentException("Activity does not exist; token="
9024                            + activityToken);
9025                }
9026                ComponentName comp = intent.getComponent();
9027                if (comp == null) {
9028                    throw new IllegalArgumentException("Intent " + intent
9029                            + " must specify explicit component");
9030                }
9031                if (thumbnail.getWidth() != mThumbnailWidth
9032                        || thumbnail.getHeight() != mThumbnailHeight) {
9033                    throw new IllegalArgumentException("Bad thumbnail size: got "
9034                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9035                            + mThumbnailWidth + "x" + mThumbnailHeight);
9036                }
9037                if (intent.getSelector() != null) {
9038                    intent.setSelector(null);
9039                }
9040                if (intent.getSourceBounds() != null) {
9041                    intent.setSourceBounds(null);
9042                }
9043                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9044                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9045                        // The caller has added this as an auto-remove task...  that makes no
9046                        // sense, so turn off auto-remove.
9047                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9048                    }
9049                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9050                    // Must be a new task.
9051                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9052                }
9053                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9054                    mLastAddedTaskActivity = null;
9055                }
9056                ActivityInfo ainfo = mLastAddedTaskActivity;
9057                if (ainfo == null) {
9058                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9059                            comp, 0, UserHandle.getUserId(callingUid));
9060                    if (ainfo.applicationInfo.uid != callingUid) {
9061                        throw new SecurityException(
9062                                "Can't add task for another application: target uid="
9063                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9064                    }
9065                }
9066
9067                // Use the full screen as the context for the task thumbnail
9068                final Point displaySize = new Point();
9069                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9070                r.task.stack.getDisplaySize(displaySize);
9071                thumbnailInfo.taskWidth = displaySize.x;
9072                thumbnailInfo.taskHeight = displaySize.y;
9073                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9074
9075                TaskRecord task = new TaskRecord(this,
9076                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9077                        ainfo, intent, description, thumbnailInfo);
9078
9079                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9080                if (trimIdx >= 0) {
9081                    // If this would have caused a trim, then we'll abort because that
9082                    // means it would be added at the end of the list but then just removed.
9083                    return INVALID_TASK_ID;
9084                }
9085
9086                final int N = mRecentTasks.size();
9087                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9088                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9089                    tr.removedFromRecents();
9090                }
9091
9092                task.inRecents = true;
9093                mRecentTasks.add(task);
9094                r.task.stack.addTask(task, false, "addAppTask");
9095
9096                task.setLastThumbnailLocked(thumbnail);
9097                task.freeLastThumbnail();
9098
9099                return task.taskId;
9100            }
9101        } finally {
9102            Binder.restoreCallingIdentity(callingIdent);
9103        }
9104    }
9105
9106    @Override
9107    public Point getAppTaskThumbnailSize() {
9108        synchronized (this) {
9109            return new Point(mThumbnailWidth,  mThumbnailHeight);
9110        }
9111    }
9112
9113    @Override
9114    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9115        synchronized (this) {
9116            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9117            if (r != null) {
9118                r.setTaskDescription(td);
9119                r.task.updateTaskDescription();
9120            }
9121        }
9122    }
9123
9124    @Override
9125    public void setTaskResizeable(int taskId, int resizeableMode) {
9126        synchronized (this) {
9127            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9128                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9129            if (task == null) {
9130                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9131                return;
9132            }
9133            if (task.mResizeMode != resizeableMode) {
9134                task.mResizeMode = resizeableMode;
9135                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9136                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9137                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9138            }
9139        }
9140    }
9141
9142    @Override
9143    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9144        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9145        long ident = Binder.clearCallingIdentity();
9146        try {
9147            synchronized (this) {
9148                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9149                if (task == null) {
9150                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9151                    return;
9152                }
9153                int stackId = task.stack.mStackId;
9154                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9155                // in crop windows resize mode or if the task size is affected by the docked stack
9156                // changing size. No need to update configuration.
9157                if (bounds != null && task.inCropWindowsResizeMode()
9158                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9159                    mWindowManager.scrollTask(task.taskId, bounds);
9160                    return;
9161                }
9162
9163                // Place the task in the right stack if it isn't there already based on
9164                // the requested bounds.
9165                // The stack transition logic is:
9166                // - a null bounds on a freeform task moves that task to fullscreen
9167                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9168                //   that task to freeform
9169                // - otherwise the task is not moved
9170                if (!StackId.isTaskResizeAllowed(stackId)) {
9171                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9172                }
9173                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9174                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9175                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9176                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9177                }
9178                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9179                if (stackId != task.stack.mStackId) {
9180                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9181                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9182                    preserveWindow = false;
9183                }
9184
9185                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9186                        false /* deferResume */);
9187            }
9188        } finally {
9189            Binder.restoreCallingIdentity(ident);
9190        }
9191    }
9192
9193    @Override
9194    public Rect getTaskBounds(int taskId) {
9195        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9196        long ident = Binder.clearCallingIdentity();
9197        Rect rect = new Rect();
9198        try {
9199            synchronized (this) {
9200                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9201                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9202                if (task == null) {
9203                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9204                    return rect;
9205                }
9206                if (task.stack != null) {
9207                    // Return the bounds from window manager since it will be adjusted for various
9208                    // things like the presense of a docked stack for tasks that aren't resizeable.
9209                    mWindowManager.getTaskBounds(task.taskId, rect);
9210                } else {
9211                    // Task isn't in window manager yet since it isn't associated with a stack.
9212                    // Return the persist value from activity manager
9213                    if (task.mBounds != null) {
9214                        rect.set(task.mBounds);
9215                    } else if (task.mLastNonFullscreenBounds != null) {
9216                        rect.set(task.mLastNonFullscreenBounds);
9217                    }
9218                }
9219            }
9220        } finally {
9221            Binder.restoreCallingIdentity(ident);
9222        }
9223        return rect;
9224    }
9225
9226    @Override
9227    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9228        if (userId != UserHandle.getCallingUserId()) {
9229            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9230                    "getTaskDescriptionIcon");
9231        }
9232        final File passedIconFile = new File(filePath);
9233        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9234                passedIconFile.getName());
9235        if (!legitIconFile.getPath().equals(filePath)
9236                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9237            throw new IllegalArgumentException("Bad file path: " + filePath
9238                    + " passed for userId " + userId);
9239        }
9240        return mRecentTasks.getTaskDescriptionIcon(filePath);
9241    }
9242
9243    @Override
9244    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9245            throws RemoteException {
9246        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9247                opts.getCustomInPlaceResId() == 0) {
9248            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9249                    "with valid animation");
9250        }
9251        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9252        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9253                opts.getCustomInPlaceResId());
9254        mWindowManager.executeAppTransition();
9255    }
9256
9257    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9258            boolean removeFromRecents) {
9259        if (removeFromRecents) {
9260            mRecentTasks.remove(tr);
9261            tr.removedFromRecents();
9262        }
9263        ComponentName component = tr.getBaseIntent().getComponent();
9264        if (component == null) {
9265            Slog.w(TAG, "No component for base intent of task: " + tr);
9266            return;
9267        }
9268
9269        // Find any running services associated with this app and stop if needed.
9270        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9271
9272        if (!killProcess) {
9273            return;
9274        }
9275
9276        // Determine if the process(es) for this task should be killed.
9277        final String pkg = component.getPackageName();
9278        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9279        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9280        for (int i = 0; i < pmap.size(); i++) {
9281
9282            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9283            for (int j = 0; j < uids.size(); j++) {
9284                ProcessRecord proc = uids.valueAt(j);
9285                if (proc.userId != tr.userId) {
9286                    // Don't kill process for a different user.
9287                    continue;
9288                }
9289                if (proc == mHomeProcess) {
9290                    // Don't kill the home process along with tasks from the same package.
9291                    continue;
9292                }
9293                if (!proc.pkgList.containsKey(pkg)) {
9294                    // Don't kill process that is not associated with this task.
9295                    continue;
9296                }
9297
9298                for (int k = 0; k < proc.activities.size(); k++) {
9299                    TaskRecord otherTask = proc.activities.get(k).task;
9300                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9301                        // Don't kill process(es) that has an activity in a different task that is
9302                        // also in recents.
9303                        return;
9304                    }
9305                }
9306
9307                if (proc.foregroundServices) {
9308                    // Don't kill process(es) with foreground service.
9309                    return;
9310                }
9311
9312                // Add process to kill list.
9313                procsToKill.add(proc);
9314            }
9315        }
9316
9317        // Kill the running processes.
9318        for (int i = 0; i < procsToKill.size(); i++) {
9319            ProcessRecord pr = procsToKill.get(i);
9320            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9321                    && pr.curReceiver == null) {
9322                pr.kill("remove task", true);
9323            } else {
9324                // We delay killing processes that are not in the background or running a receiver.
9325                pr.waitingToKill = "remove task";
9326            }
9327        }
9328    }
9329
9330    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9331        // Remove all tasks with activities in the specified package from the list of recent tasks
9332        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9333            TaskRecord tr = mRecentTasks.get(i);
9334            if (tr.userId != userId) continue;
9335
9336            ComponentName cn = tr.intent.getComponent();
9337            if (cn != null && cn.getPackageName().equals(packageName)) {
9338                // If the package name matches, remove the task.
9339                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9340            }
9341        }
9342    }
9343
9344    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9345            int userId) {
9346
9347        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9348            TaskRecord tr = mRecentTasks.get(i);
9349            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9350                continue;
9351            }
9352
9353            ComponentName cn = tr.intent.getComponent();
9354            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9355                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9356            if (sameComponent) {
9357                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9358            }
9359        }
9360    }
9361
9362    /**
9363     * Removes the task with the specified task id.
9364     *
9365     * @param taskId Identifier of the task to be removed.
9366     * @param killProcess Kill any process associated with the task if possible.
9367     * @param removeFromRecents Whether to also remove the task from recents.
9368     * @return Returns true if the given task was found and removed.
9369     */
9370    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9371            boolean removeFromRecents) {
9372        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9373                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9374        if (tr != null) {
9375            tr.removeTaskActivitiesLocked();
9376            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9377            if (tr.isPersistable) {
9378                notifyTaskPersisterLocked(null, true);
9379            }
9380            return true;
9381        }
9382        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9383        return false;
9384    }
9385
9386    @Override
9387    public void removeStack(int stackId) {
9388        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9389        if (stackId == HOME_STACK_ID) {
9390            throw new IllegalArgumentException("Removing home stack is not allowed.");
9391        }
9392
9393        synchronized (this) {
9394            final long ident = Binder.clearCallingIdentity();
9395            try {
9396                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9397                if (stack == null) {
9398                    return;
9399                }
9400                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9401                for (int i = tasks.size() - 1; i >= 0; i--) {
9402                    removeTaskByIdLocked(
9403                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9404                }
9405            } finally {
9406                Binder.restoreCallingIdentity(ident);
9407            }
9408        }
9409    }
9410
9411    @Override
9412    public boolean removeTask(int taskId) {
9413        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9414        synchronized (this) {
9415            final long ident = Binder.clearCallingIdentity();
9416            try {
9417                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9418            } finally {
9419                Binder.restoreCallingIdentity(ident);
9420            }
9421        }
9422    }
9423
9424    /**
9425     * TODO: Add mController hook
9426     */
9427    @Override
9428    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9429        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9430
9431        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9432        synchronized(this) {
9433            moveTaskToFrontLocked(taskId, flags, bOptions);
9434        }
9435    }
9436
9437    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9438        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9439
9440        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9441                Binder.getCallingUid(), -1, -1, "Task to front")) {
9442            ActivityOptions.abort(options);
9443            return;
9444        }
9445        final long origId = Binder.clearCallingIdentity();
9446        try {
9447            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9448            if (task == null) {
9449                Slog.d(TAG, "Could not find task for id: "+ taskId);
9450                return;
9451            }
9452            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9453                mStackSupervisor.showLockTaskToast();
9454                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9455                return;
9456            }
9457            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9458            if (prev != null && prev.isRecentsActivity()) {
9459                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9460            }
9461            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9462                    false /* forceNonResizable */);
9463        } finally {
9464            Binder.restoreCallingIdentity(origId);
9465        }
9466        ActivityOptions.abort(options);
9467    }
9468
9469    /**
9470     * Moves an activity, and all of the other activities within the same task, to the bottom
9471     * of the history stack.  The activity's order within the task is unchanged.
9472     *
9473     * @param token A reference to the activity we wish to move
9474     * @param nonRoot If false then this only works if the activity is the root
9475     *                of a task; if true it will work for any activity in a task.
9476     * @return Returns true if the move completed, false if not.
9477     */
9478    @Override
9479    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9480        enforceNotIsolatedCaller("moveActivityTaskToBack");
9481        synchronized(this) {
9482            final long origId = Binder.clearCallingIdentity();
9483            try {
9484                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9485                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9486                if (task != null) {
9487                    if (mStackSupervisor.isLockedTask(task)) {
9488                        mStackSupervisor.showLockTaskToast();
9489                        return false;
9490                    }
9491                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9492                }
9493            } finally {
9494                Binder.restoreCallingIdentity(origId);
9495            }
9496        }
9497        return false;
9498    }
9499
9500    @Override
9501    public void moveTaskBackwards(int task) {
9502        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9503                "moveTaskBackwards()");
9504
9505        synchronized(this) {
9506            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9507                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9508                return;
9509            }
9510            final long origId = Binder.clearCallingIdentity();
9511            moveTaskBackwardsLocked(task);
9512            Binder.restoreCallingIdentity(origId);
9513        }
9514    }
9515
9516    private final void moveTaskBackwardsLocked(int task) {
9517        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9518    }
9519
9520    @Override
9521    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9522            IActivityContainerCallback callback) throws RemoteException {
9523        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9524        synchronized (this) {
9525            if (parentActivityToken == null) {
9526                throw new IllegalArgumentException("parent token must not be null");
9527            }
9528            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9529            if (r == null) {
9530                return null;
9531            }
9532            if (callback == null) {
9533                throw new IllegalArgumentException("callback must not be null");
9534            }
9535            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9536        }
9537    }
9538
9539    @Override
9540    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9541        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9542        synchronized (this) {
9543            mStackSupervisor.deleteActivityContainer(container);
9544        }
9545    }
9546
9547    @Override
9548    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9549        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9550        synchronized (this) {
9551            final int stackId = mStackSupervisor.getNextStackId();
9552            final ActivityStack stack =
9553                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9554            if (stack == null) {
9555                return null;
9556            }
9557            return stack.mActivityContainer;
9558        }
9559    }
9560
9561    @Override
9562    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9563        synchronized (this) {
9564            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9565            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9566                return stack.mActivityContainer.getDisplayId();
9567            }
9568            return Display.DEFAULT_DISPLAY;
9569        }
9570    }
9571
9572    @Override
9573    public int getActivityStackId(IBinder token) throws RemoteException {
9574        synchronized (this) {
9575            ActivityStack stack = ActivityRecord.getStackLocked(token);
9576            if (stack == null) {
9577                return INVALID_STACK_ID;
9578            }
9579            return stack.mStackId;
9580        }
9581    }
9582
9583    @Override
9584    public void exitFreeformMode(IBinder token) throws RemoteException {
9585        synchronized (this) {
9586            long ident = Binder.clearCallingIdentity();
9587            try {
9588                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9589                if (r == null) {
9590                    throw new IllegalArgumentException(
9591                            "exitFreeformMode: No activity record matching token=" + token);
9592                }
9593                final ActivityStack stack = r.getStackLocked(token);
9594                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9595                    throw new IllegalStateException(
9596                            "exitFreeformMode: You can only go fullscreen from freeform.");
9597                }
9598                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9599                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9600                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9601            } finally {
9602                Binder.restoreCallingIdentity(ident);
9603            }
9604        }
9605    }
9606
9607    @Override
9608    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9609        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9610        if (stackId == HOME_STACK_ID) {
9611            throw new IllegalArgumentException(
9612                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9613        }
9614        synchronized (this) {
9615            long ident = Binder.clearCallingIdentity();
9616            try {
9617                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9618                        + " to stackId=" + stackId + " toTop=" + toTop);
9619                if (stackId == DOCKED_STACK_ID) {
9620                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9621                            null /* initialBounds */);
9622                }
9623                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9624                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9625                if (result && stackId == DOCKED_STACK_ID) {
9626                    // If task moved to docked stack - show recents if needed.
9627                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9628                            "moveTaskToDockedStack");
9629                }
9630            } finally {
9631                Binder.restoreCallingIdentity(ident);
9632            }
9633        }
9634    }
9635
9636    @Override
9637    public void swapDockedAndFullscreenStack() throws RemoteException {
9638        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9639        synchronized (this) {
9640            long ident = Binder.clearCallingIdentity();
9641            try {
9642                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9643                        FULLSCREEN_WORKSPACE_STACK_ID);
9644                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9645                        : null;
9646                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9647                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9648                        : null;
9649                if (topTask == null || tasks == null || tasks.size() == 0) {
9650                    Slog.w(TAG,
9651                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9652                    return;
9653                }
9654
9655                // TODO: App transition
9656                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9657
9658                // Defer the resume so resume/pausing while moving stacks is dangerous.
9659                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9660                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9661                        ANIMATE, true /* deferResume */);
9662                final int size = tasks.size();
9663                for (int i = 0; i < size; i++) {
9664                    final int id = tasks.get(i).taskId;
9665                    if (id == topTask.taskId) {
9666                        continue;
9667                    }
9668                    mStackSupervisor.moveTaskToStackLocked(id,
9669                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9670                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9671                }
9672
9673                // Because we deferred the resume, to avoid conflicts with stack switches while
9674                // resuming, we need to do it after all the tasks are moved.
9675                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9676                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9677
9678                mWindowManager.executeAppTransition();
9679            } finally {
9680                Binder.restoreCallingIdentity(ident);
9681            }
9682        }
9683    }
9684
9685    /**
9686     * Moves the input task to the docked stack.
9687     *
9688     * @param taskId Id of task to move.
9689     * @param createMode The mode the docked stack should be created in if it doesn't exist
9690     *                   already. See
9691     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9692     *                   and
9693     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9694     * @param toTop If the task and stack should be moved to the top.
9695     * @param animate Whether we should play an animation for the moving the task
9696     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9697     *                      docked stack. Pass {@code null} to use default bounds.
9698     */
9699    @Override
9700    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9701            Rect initialBounds) {
9702        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9703        synchronized (this) {
9704            long ident = Binder.clearCallingIdentity();
9705            try {
9706                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9707                        + " to createMode=" + createMode + " toTop=" + toTop);
9708                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9709                return mStackSupervisor.moveTaskToStackLocked(
9710                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9711                        "moveTaskToDockedStack", animate);
9712            } finally {
9713                Binder.restoreCallingIdentity(ident);
9714            }
9715        }
9716    }
9717
9718    /**
9719     * Moves the top activity in the input stackId to the pinned stack.
9720     *
9721     * @param stackId Id of stack to move the top activity to pinned stack.
9722     * @param bounds Bounds to use for pinned stack.
9723     *
9724     * @return True if the top activity of the input stack was successfully moved to the pinned
9725     *          stack.
9726     */
9727    @Override
9728    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9729        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9730        synchronized (this) {
9731            if (!mSupportsPictureInPicture) {
9732                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9733                        + "Device doesn't support picture-in-pciture mode");
9734            }
9735
9736            long ident = Binder.clearCallingIdentity();
9737            try {
9738                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9739            } finally {
9740                Binder.restoreCallingIdentity(ident);
9741            }
9742        }
9743    }
9744
9745    @Override
9746    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9747            boolean preserveWindows, boolean animate, int animationDuration) {
9748        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9749        long ident = Binder.clearCallingIdentity();
9750        try {
9751            synchronized (this) {
9752                if (animate) {
9753                    if (stackId == PINNED_STACK_ID) {
9754                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9755                    } else {
9756                        throw new IllegalArgumentException("Stack: " + stackId
9757                                + " doesn't support animated resize.");
9758                    }
9759                } else {
9760                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9761                            null /* tempTaskInsetBounds */, preserveWindows,
9762                            allowResizeInDockedMode, !DEFER_RESUME);
9763                }
9764            }
9765        } finally {
9766            Binder.restoreCallingIdentity(ident);
9767        }
9768    }
9769
9770    @Override
9771    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9772            Rect tempDockedTaskInsetBounds,
9773            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9774        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9775                "resizeDockedStack()");
9776        long ident = Binder.clearCallingIdentity();
9777        try {
9778            synchronized (this) {
9779                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9780                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9781                        PRESERVE_WINDOWS);
9782            }
9783        } finally {
9784            Binder.restoreCallingIdentity(ident);
9785        }
9786    }
9787
9788    @Override
9789    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9790        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9791                "resizePinnedStack()");
9792        final long ident = Binder.clearCallingIdentity();
9793        try {
9794            synchronized (this) {
9795                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9796            }
9797        } finally {
9798            Binder.restoreCallingIdentity(ident);
9799        }
9800    }
9801
9802    @Override
9803    public void positionTaskInStack(int taskId, int stackId, int position) {
9804        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9805        if (stackId == HOME_STACK_ID) {
9806            throw new IllegalArgumentException(
9807                    "positionTaskInStack: Attempt to change the position of task "
9808                    + taskId + " in/to home stack");
9809        }
9810        synchronized (this) {
9811            long ident = Binder.clearCallingIdentity();
9812            try {
9813                if (DEBUG_STACK) Slog.d(TAG_STACK,
9814                        "positionTaskInStack: positioning task=" + taskId
9815                        + " in stackId=" + stackId + " at position=" + position);
9816                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9817            } finally {
9818                Binder.restoreCallingIdentity(ident);
9819            }
9820        }
9821    }
9822
9823    @Override
9824    public List<StackInfo> getAllStackInfos() {
9825        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9826        long ident = Binder.clearCallingIdentity();
9827        try {
9828            synchronized (this) {
9829                return mStackSupervisor.getAllStackInfosLocked();
9830            }
9831        } finally {
9832            Binder.restoreCallingIdentity(ident);
9833        }
9834    }
9835
9836    @Override
9837    public StackInfo getStackInfo(int stackId) {
9838        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9839        long ident = Binder.clearCallingIdentity();
9840        try {
9841            synchronized (this) {
9842                return mStackSupervisor.getStackInfoLocked(stackId);
9843            }
9844        } finally {
9845            Binder.restoreCallingIdentity(ident);
9846        }
9847    }
9848
9849    @Override
9850    public boolean isInHomeStack(int taskId) {
9851        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9852        long ident = Binder.clearCallingIdentity();
9853        try {
9854            synchronized (this) {
9855                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9856                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9857                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9858            }
9859        } finally {
9860            Binder.restoreCallingIdentity(ident);
9861        }
9862    }
9863
9864    @Override
9865    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9866        synchronized(this) {
9867            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9868        }
9869    }
9870
9871    @Override
9872    public void updateDeviceOwner(String packageName) {
9873        final int callingUid = Binder.getCallingUid();
9874        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9875            throw new SecurityException("updateDeviceOwner called from non-system process");
9876        }
9877        synchronized (this) {
9878            mDeviceOwnerName = packageName;
9879        }
9880    }
9881
9882    @Override
9883    public void updateLockTaskPackages(int userId, String[] packages) {
9884        final int callingUid = Binder.getCallingUid();
9885        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9886            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9887                    "updateLockTaskPackages()");
9888        }
9889        synchronized (this) {
9890            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9891                    Arrays.toString(packages));
9892            mLockTaskPackages.put(userId, packages);
9893            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9894        }
9895    }
9896
9897
9898    void startLockTaskModeLocked(TaskRecord task) {
9899        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9900        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9901            return;
9902        }
9903
9904        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9905        // is initiated by system after the pinning request was shown and locked mode is initiated
9906        // by an authorized app directly
9907        final int callingUid = Binder.getCallingUid();
9908        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9909        long ident = Binder.clearCallingIdentity();
9910        try {
9911            if (!isSystemInitiated) {
9912                task.mLockTaskUid = callingUid;
9913                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9914                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9915                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9916                    StatusBarManagerInternal statusBarManager =
9917                            LocalServices.getService(StatusBarManagerInternal.class);
9918                    if (statusBarManager != null) {
9919                        statusBarManager.showScreenPinningRequest(task.taskId);
9920                    }
9921                    return;
9922                }
9923
9924                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9925                if (stack == null || task != stack.topTask()) {
9926                    throw new IllegalArgumentException("Invalid task, not in foreground");
9927                }
9928            }
9929            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9930                    "Locking fully");
9931            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9932                    ActivityManager.LOCK_TASK_MODE_PINNED :
9933                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9934                    "startLockTask", true);
9935        } finally {
9936            Binder.restoreCallingIdentity(ident);
9937        }
9938    }
9939
9940    @Override
9941    public void startLockTaskMode(int taskId) {
9942        synchronized (this) {
9943            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9944            if (task != null) {
9945                startLockTaskModeLocked(task);
9946            }
9947        }
9948    }
9949
9950    @Override
9951    public void startLockTaskMode(IBinder token) {
9952        synchronized (this) {
9953            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9954            if (r == null) {
9955                return;
9956            }
9957            final TaskRecord task = r.task;
9958            if (task != null) {
9959                startLockTaskModeLocked(task);
9960            }
9961        }
9962    }
9963
9964    @Override
9965    public void startSystemLockTaskMode(int taskId) throws RemoteException {
9966        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
9967        // This makes inner call to look as if it was initiated by system.
9968        long ident = Binder.clearCallingIdentity();
9969        try {
9970            synchronized (this) {
9971                startLockTaskMode(taskId);
9972            }
9973        } finally {
9974            Binder.restoreCallingIdentity(ident);
9975        }
9976    }
9977
9978    @Override
9979    public void stopLockTaskMode() {
9980        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9981        if (lockTask == null) {
9982            // Our work here is done.
9983            return;
9984        }
9985
9986        final int callingUid = Binder.getCallingUid();
9987        final int lockTaskUid = lockTask.mLockTaskUid;
9988        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
9989        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
9990            // Done.
9991            return;
9992        } else {
9993            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9994            // It is possible lockTaskMode was started by the system process because
9995            // android:lockTaskMode is set to a locking value in the application manifest
9996            // instead of the app calling startLockTaskMode. In this case
9997            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
9998            // {@link TaskRecord.effectiveUid} instead. Also caller with
9999            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10000            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10001                    && callingUid != lockTaskUid
10002                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10003                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10004                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10005            }
10006        }
10007        long ident = Binder.clearCallingIdentity();
10008        try {
10009            Log.d(TAG, "stopLockTaskMode");
10010            // Stop lock task
10011            synchronized (this) {
10012                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10013                        "stopLockTask", true);
10014            }
10015        } finally {
10016            Binder.restoreCallingIdentity(ident);
10017        }
10018    }
10019
10020    /**
10021     * This API should be called by SystemUI only when user perform certain action to dismiss
10022     * lock task mode. We should only dismiss pinned lock task mode in this case.
10023     */
10024    @Override
10025    public void stopSystemLockTaskMode() throws RemoteException {
10026        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10027            stopLockTaskMode();
10028        } else {
10029            mStackSupervisor.showLockTaskToast();
10030        }
10031    }
10032
10033    @Override
10034    public boolean isInLockTaskMode() {
10035        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10036    }
10037
10038    @Override
10039    public int getLockTaskModeState() {
10040        synchronized (this) {
10041            return mStackSupervisor.getLockTaskModeState();
10042        }
10043    }
10044
10045    @Override
10046    public void showLockTaskEscapeMessage(IBinder token) {
10047        synchronized (this) {
10048            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10049            if (r == null) {
10050                return;
10051            }
10052            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10053        }
10054    }
10055
10056    // =========================================================
10057    // CONTENT PROVIDERS
10058    // =========================================================
10059
10060    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10061        List<ProviderInfo> providers = null;
10062        try {
10063            providers = AppGlobals.getPackageManager()
10064                    .queryContentProviders(app.processName, app.uid,
10065                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10066                                    | MATCH_DEBUG_TRIAGED_MISSING)
10067                    .getList();
10068        } catch (RemoteException ex) {
10069        }
10070        if (DEBUG_MU) Slog.v(TAG_MU,
10071                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10072        int userId = app.userId;
10073        if (providers != null) {
10074            int N = providers.size();
10075            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10076            for (int i=0; i<N; i++) {
10077                ProviderInfo cpi =
10078                    (ProviderInfo)providers.get(i);
10079                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10080                        cpi.name, cpi.flags);
10081                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10082                    // This is a singleton provider, but a user besides the
10083                    // default user is asking to initialize a process it runs
10084                    // in...  well, no, it doesn't actually run in this process,
10085                    // it runs in the process of the default user.  Get rid of it.
10086                    providers.remove(i);
10087                    N--;
10088                    i--;
10089                    continue;
10090                }
10091
10092                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10093                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10094                if (cpr == null) {
10095                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10096                    mProviderMap.putProviderByClass(comp, cpr);
10097                }
10098                if (DEBUG_MU) Slog.v(TAG_MU,
10099                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10100                app.pubProviders.put(cpi.name, cpr);
10101                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10102                    // Don't add this if it is a platform component that is marked
10103                    // to run in multiple processes, because this is actually
10104                    // part of the framework so doesn't make sense to track as a
10105                    // separate apk in the process.
10106                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10107                            mProcessStats);
10108                }
10109                notifyPackageUse(cpi.applicationInfo.packageName,
10110                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10111            }
10112        }
10113        return providers;
10114    }
10115
10116    /**
10117     * Check if {@link ProcessRecord} has a possible chance at accessing the
10118     * given {@link ProviderInfo}. Final permission checking is always done
10119     * in {@link ContentProvider}.
10120     */
10121    private final String checkContentProviderPermissionLocked(
10122            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10123        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10124        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10125        boolean checkedGrants = false;
10126        if (checkUser) {
10127            // Looking for cross-user grants before enforcing the typical cross-users permissions
10128            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10129            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10130                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10131                    return null;
10132                }
10133                checkedGrants = true;
10134            }
10135            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10136                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10137            if (userId != tmpTargetUserId) {
10138                // When we actually went to determine the final targer user ID, this ended
10139                // up different than our initial check for the authority.  This is because
10140                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10141                // SELF.  So we need to re-check the grants again.
10142                checkedGrants = false;
10143            }
10144        }
10145        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10146                cpi.applicationInfo.uid, cpi.exported)
10147                == PackageManager.PERMISSION_GRANTED) {
10148            return null;
10149        }
10150        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10151                cpi.applicationInfo.uid, cpi.exported)
10152                == PackageManager.PERMISSION_GRANTED) {
10153            return null;
10154        }
10155
10156        PathPermission[] pps = cpi.pathPermissions;
10157        if (pps != null) {
10158            int i = pps.length;
10159            while (i > 0) {
10160                i--;
10161                PathPermission pp = pps[i];
10162                String pprperm = pp.getReadPermission();
10163                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10164                        cpi.applicationInfo.uid, cpi.exported)
10165                        == PackageManager.PERMISSION_GRANTED) {
10166                    return null;
10167                }
10168                String ppwperm = pp.getWritePermission();
10169                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10170                        cpi.applicationInfo.uid, cpi.exported)
10171                        == PackageManager.PERMISSION_GRANTED) {
10172                    return null;
10173                }
10174            }
10175        }
10176        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10177            return null;
10178        }
10179
10180        String msg;
10181        if (!cpi.exported) {
10182            msg = "Permission Denial: opening provider " + cpi.name
10183                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10184                    + ", uid=" + callingUid + ") that is not exported from uid "
10185                    + cpi.applicationInfo.uid;
10186        } else {
10187            msg = "Permission Denial: opening provider " + cpi.name
10188                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10189                    + ", uid=" + callingUid + ") requires "
10190                    + cpi.readPermission + " or " + cpi.writePermission;
10191        }
10192        Slog.w(TAG, msg);
10193        return msg;
10194    }
10195
10196    /**
10197     * Returns if the ContentProvider has granted a uri to callingUid
10198     */
10199    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10200        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10201        if (perms != null) {
10202            for (int i=perms.size()-1; i>=0; i--) {
10203                GrantUri grantUri = perms.keyAt(i);
10204                if (grantUri.sourceUserId == userId || !checkUser) {
10205                    if (matchesProvider(grantUri.uri, cpi)) {
10206                        return true;
10207                    }
10208                }
10209            }
10210        }
10211        return false;
10212    }
10213
10214    /**
10215     * Returns true if the uri authority is one of the authorities specified in the provider.
10216     */
10217    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10218        String uriAuth = uri.getAuthority();
10219        String cpiAuth = cpi.authority;
10220        if (cpiAuth.indexOf(';') == -1) {
10221            return cpiAuth.equals(uriAuth);
10222        }
10223        String[] cpiAuths = cpiAuth.split(";");
10224        int length = cpiAuths.length;
10225        for (int i = 0; i < length; i++) {
10226            if (cpiAuths[i].equals(uriAuth)) return true;
10227        }
10228        return false;
10229    }
10230
10231    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10232            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10233        if (r != null) {
10234            for (int i=0; i<r.conProviders.size(); i++) {
10235                ContentProviderConnection conn = r.conProviders.get(i);
10236                if (conn.provider == cpr) {
10237                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10238                            "Adding provider requested by "
10239                            + r.processName + " from process "
10240                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10241                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10242                    if (stable) {
10243                        conn.stableCount++;
10244                        conn.numStableIncs++;
10245                    } else {
10246                        conn.unstableCount++;
10247                        conn.numUnstableIncs++;
10248                    }
10249                    return conn;
10250                }
10251            }
10252            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10253            if (stable) {
10254                conn.stableCount = 1;
10255                conn.numStableIncs = 1;
10256            } else {
10257                conn.unstableCount = 1;
10258                conn.numUnstableIncs = 1;
10259            }
10260            cpr.connections.add(conn);
10261            r.conProviders.add(conn);
10262            startAssociationLocked(r.uid, r.processName, r.curProcState,
10263                    cpr.uid, cpr.name, cpr.info.processName);
10264            return conn;
10265        }
10266        cpr.addExternalProcessHandleLocked(externalProcessToken);
10267        return null;
10268    }
10269
10270    boolean decProviderCountLocked(ContentProviderConnection conn,
10271            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10272        if (conn != null) {
10273            cpr = conn.provider;
10274            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10275                    "Removing provider requested by "
10276                    + conn.client.processName + " from process "
10277                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10278                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10279            if (stable) {
10280                conn.stableCount--;
10281            } else {
10282                conn.unstableCount--;
10283            }
10284            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10285                cpr.connections.remove(conn);
10286                conn.client.conProviders.remove(conn);
10287                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10288                    // The client is more important than last activity -- note the time this
10289                    // is happening, so we keep the old provider process around a bit as last
10290                    // activity to avoid thrashing it.
10291                    if (cpr.proc != null) {
10292                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10293                    }
10294                }
10295                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10296                return true;
10297            }
10298            return false;
10299        }
10300        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10301        return false;
10302    }
10303
10304    private void checkTime(long startTime, String where) {
10305        long now = SystemClock.elapsedRealtime();
10306        if ((now-startTime) > 1000) {
10307            // If we are taking more than a second, log about it.
10308            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10309        }
10310    }
10311
10312    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10313            String name, IBinder token, boolean stable, int userId) {
10314        ContentProviderRecord cpr;
10315        ContentProviderConnection conn = null;
10316        ProviderInfo cpi = null;
10317
10318        synchronized(this) {
10319            long startTime = SystemClock.elapsedRealtime();
10320
10321            ProcessRecord r = null;
10322            if (caller != null) {
10323                r = getRecordForAppLocked(caller);
10324                if (r == null) {
10325                    throw new SecurityException(
10326                            "Unable to find app for caller " + caller
10327                          + " (pid=" + Binder.getCallingPid()
10328                          + ") when getting content provider " + name);
10329                }
10330            }
10331
10332            boolean checkCrossUser = true;
10333
10334            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10335
10336            // First check if this content provider has been published...
10337            cpr = mProviderMap.getProviderByName(name, userId);
10338            // If that didn't work, check if it exists for user 0 and then
10339            // verify that it's a singleton provider before using it.
10340            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10341                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10342                if (cpr != null) {
10343                    cpi = cpr.info;
10344                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10345                            cpi.name, cpi.flags)
10346                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10347                        userId = UserHandle.USER_SYSTEM;
10348                        checkCrossUser = false;
10349                    } else {
10350                        cpr = null;
10351                        cpi = null;
10352                    }
10353                }
10354            }
10355
10356            boolean providerRunning = cpr != null;
10357            if (providerRunning) {
10358                cpi = cpr.info;
10359                String msg;
10360                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10361                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10362                        != null) {
10363                    throw new SecurityException(msg);
10364                }
10365                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10366
10367                if (r != null && cpr.canRunHere(r)) {
10368                    // This provider has been published or is in the process
10369                    // of being published...  but it is also allowed to run
10370                    // in the caller's process, so don't make a connection
10371                    // and just let the caller instantiate its own instance.
10372                    ContentProviderHolder holder = cpr.newHolder(null);
10373                    // don't give caller the provider object, it needs
10374                    // to make its own.
10375                    holder.provider = null;
10376                    return holder;
10377                }
10378
10379                final long origId = Binder.clearCallingIdentity();
10380
10381                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10382
10383                // In this case the provider instance already exists, so we can
10384                // return it right away.
10385                conn = incProviderCountLocked(r, cpr, token, stable);
10386                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10387                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10388                        // If this is a perceptible app accessing the provider,
10389                        // make sure to count it as being accessed and thus
10390                        // back up on the LRU list.  This is good because
10391                        // content providers are often expensive to start.
10392                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10393                        updateLruProcessLocked(cpr.proc, false, null);
10394                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10395                    }
10396                }
10397
10398                if (cpr.proc != null) {
10399                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10400                    boolean success = updateOomAdjLocked(cpr.proc);
10401                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10402                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10403                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10404                    // NOTE: there is still a race here where a signal could be
10405                    // pending on the process even though we managed to update its
10406                    // adj level.  Not sure what to do about this, but at least
10407                    // the race is now smaller.
10408                    if (!success) {
10409                        // Uh oh...  it looks like the provider's process
10410                        // has been killed on us.  We need to wait for a new
10411                        // process to be started, and make sure its death
10412                        // doesn't kill our process.
10413                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10414                                + " is crashing; detaching " + r);
10415                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10416                        checkTime(startTime, "getContentProviderImpl: before appDied");
10417                        appDiedLocked(cpr.proc);
10418                        checkTime(startTime, "getContentProviderImpl: after appDied");
10419                        if (!lastRef) {
10420                            // This wasn't the last ref our process had on
10421                            // the provider...  we have now been killed, bail.
10422                            return null;
10423                        }
10424                        providerRunning = false;
10425                        conn = null;
10426                    }
10427                }
10428
10429                Binder.restoreCallingIdentity(origId);
10430            }
10431
10432            if (!providerRunning) {
10433                try {
10434                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10435                    cpi = AppGlobals.getPackageManager().
10436                        resolveContentProvider(name,
10437                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10438                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10439                } catch (RemoteException ex) {
10440                }
10441                if (cpi == null) {
10442                    return null;
10443                }
10444                // If the provider is a singleton AND
10445                // (it's a call within the same user || the provider is a
10446                // privileged app)
10447                // Then allow connecting to the singleton provider
10448                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10449                        cpi.name, cpi.flags)
10450                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10451                if (singleton) {
10452                    userId = UserHandle.USER_SYSTEM;
10453                }
10454                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10455                checkTime(startTime, "getContentProviderImpl: got app info for user");
10456
10457                String msg;
10458                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10459                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10460                        != null) {
10461                    throw new SecurityException(msg);
10462                }
10463                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10464
10465                if (!mProcessesReady
10466                        && !cpi.processName.equals("system")) {
10467                    // If this content provider does not run in the system
10468                    // process, and the system is not yet ready to run other
10469                    // processes, then fail fast instead of hanging.
10470                    throw new IllegalArgumentException(
10471                            "Attempt to launch content provider before system ready");
10472                }
10473
10474                // Make sure that the user who owns this provider is running.  If not,
10475                // we don't want to allow it to run.
10476                if (!mUserController.isUserRunningLocked(userId, 0)) {
10477                    Slog.w(TAG, "Unable to launch app "
10478                            + cpi.applicationInfo.packageName + "/"
10479                            + cpi.applicationInfo.uid + " for provider "
10480                            + name + ": user " + userId + " is stopped");
10481                    return null;
10482                }
10483
10484                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10485                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10486                cpr = mProviderMap.getProviderByClass(comp, userId);
10487                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10488                final boolean firstClass = cpr == null;
10489                if (firstClass) {
10490                    final long ident = Binder.clearCallingIdentity();
10491
10492                    // If permissions need a review before any of the app components can run,
10493                    // we return no provider and launch a review activity if the calling app
10494                    // is in the foreground.
10495                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10496                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10497                            return null;
10498                        }
10499                    }
10500
10501                    try {
10502                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10503                        ApplicationInfo ai =
10504                            AppGlobals.getPackageManager().
10505                                getApplicationInfo(
10506                                        cpi.applicationInfo.packageName,
10507                                        STOCK_PM_FLAGS, userId);
10508                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10509                        if (ai == null) {
10510                            Slog.w(TAG, "No package info for content provider "
10511                                    + cpi.name);
10512                            return null;
10513                        }
10514                        ai = getAppInfoForUser(ai, userId);
10515                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10516                    } catch (RemoteException ex) {
10517                        // pm is in same process, this will never happen.
10518                    } finally {
10519                        Binder.restoreCallingIdentity(ident);
10520                    }
10521                }
10522
10523                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10524
10525                if (r != null && cpr.canRunHere(r)) {
10526                    // If this is a multiprocess provider, then just return its
10527                    // info and allow the caller to instantiate it.  Only do
10528                    // this if the provider is the same user as the caller's
10529                    // process, or can run as root (so can be in any process).
10530                    return cpr.newHolder(null);
10531                }
10532
10533                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10534                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10535                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10536
10537                // This is single process, and our app is now connecting to it.
10538                // See if we are already in the process of launching this
10539                // provider.
10540                final int N = mLaunchingProviders.size();
10541                int i;
10542                for (i = 0; i < N; i++) {
10543                    if (mLaunchingProviders.get(i) == cpr) {
10544                        break;
10545                    }
10546                }
10547
10548                // If the provider is not already being launched, then get it
10549                // started.
10550                if (i >= N) {
10551                    final long origId = Binder.clearCallingIdentity();
10552
10553                    try {
10554                        // Content provider is now in use, its package can't be stopped.
10555                        try {
10556                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10557                            AppGlobals.getPackageManager().setPackageStoppedState(
10558                                    cpr.appInfo.packageName, false, userId);
10559                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10560                        } catch (RemoteException e) {
10561                        } catch (IllegalArgumentException e) {
10562                            Slog.w(TAG, "Failed trying to unstop package "
10563                                    + cpr.appInfo.packageName + ": " + e);
10564                        }
10565
10566                        // Use existing process if already started
10567                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10568                        ProcessRecord proc = getProcessRecordLocked(
10569                                cpi.processName, cpr.appInfo.uid, false);
10570                        if (proc != null && proc.thread != null) {
10571                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10572                                    "Installing in existing process " + proc);
10573                            if (!proc.pubProviders.containsKey(cpi.name)) {
10574                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10575                                proc.pubProviders.put(cpi.name, cpr);
10576                                try {
10577                                    proc.thread.scheduleInstallProvider(cpi);
10578                                } catch (RemoteException e) {
10579                                }
10580                            }
10581                        } else {
10582                            checkTime(startTime, "getContentProviderImpl: before start process");
10583                            proc = startProcessLocked(cpi.processName,
10584                                    cpr.appInfo, false, 0, "content provider",
10585                                    new ComponentName(cpi.applicationInfo.packageName,
10586                                            cpi.name), false, false, false);
10587                            checkTime(startTime, "getContentProviderImpl: after start process");
10588                            if (proc == null) {
10589                                Slog.w(TAG, "Unable to launch app "
10590                                        + cpi.applicationInfo.packageName + "/"
10591                                        + cpi.applicationInfo.uid + " for provider "
10592                                        + name + ": process is bad");
10593                                return null;
10594                            }
10595                        }
10596                        cpr.launchingApp = proc;
10597                        mLaunchingProviders.add(cpr);
10598                    } finally {
10599                        Binder.restoreCallingIdentity(origId);
10600                    }
10601                }
10602
10603                checkTime(startTime, "getContentProviderImpl: updating data structures");
10604
10605                // Make sure the provider is published (the same provider class
10606                // may be published under multiple names).
10607                if (firstClass) {
10608                    mProviderMap.putProviderByClass(comp, cpr);
10609                }
10610
10611                mProviderMap.putProviderByName(name, cpr);
10612                conn = incProviderCountLocked(r, cpr, token, stable);
10613                if (conn != null) {
10614                    conn.waiting = true;
10615                }
10616            }
10617            checkTime(startTime, "getContentProviderImpl: done!");
10618        }
10619
10620        // Wait for the provider to be published...
10621        synchronized (cpr) {
10622            while (cpr.provider == null) {
10623                if (cpr.launchingApp == null) {
10624                    Slog.w(TAG, "Unable to launch app "
10625                            + cpi.applicationInfo.packageName + "/"
10626                            + cpi.applicationInfo.uid + " for provider "
10627                            + name + ": launching app became null");
10628                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10629                            UserHandle.getUserId(cpi.applicationInfo.uid),
10630                            cpi.applicationInfo.packageName,
10631                            cpi.applicationInfo.uid, name);
10632                    return null;
10633                }
10634                try {
10635                    if (DEBUG_MU) Slog.v(TAG_MU,
10636                            "Waiting to start provider " + cpr
10637                            + " launchingApp=" + cpr.launchingApp);
10638                    if (conn != null) {
10639                        conn.waiting = true;
10640                    }
10641                    cpr.wait();
10642                } catch (InterruptedException ex) {
10643                } finally {
10644                    if (conn != null) {
10645                        conn.waiting = false;
10646                    }
10647                }
10648            }
10649        }
10650        return cpr != null ? cpr.newHolder(conn) : null;
10651    }
10652
10653    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10654            ProcessRecord r, final int userId) {
10655        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10656                cpi.packageName, userId)) {
10657
10658            final boolean callerForeground = r == null || r.setSchedGroup
10659                    != ProcessList.SCHED_GROUP_BACKGROUND;
10660
10661            // Show a permission review UI only for starting from a foreground app
10662            if (!callerForeground) {
10663                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10664                        + cpi.packageName + " requires a permissions review");
10665                return false;
10666            }
10667
10668            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10669            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10670                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10671            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10672
10673            if (DEBUG_PERMISSIONS_REVIEW) {
10674                Slog.i(TAG, "u" + userId + " Launching permission review "
10675                        + "for package " + cpi.packageName);
10676            }
10677
10678            final UserHandle userHandle = new UserHandle(userId);
10679            mHandler.post(new Runnable() {
10680                @Override
10681                public void run() {
10682                    mContext.startActivityAsUser(intent, userHandle);
10683                }
10684            });
10685
10686            return false;
10687        }
10688
10689        return true;
10690    }
10691
10692    PackageManagerInternal getPackageManagerInternalLocked() {
10693        if (mPackageManagerInt == null) {
10694            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10695        }
10696        return mPackageManagerInt;
10697    }
10698
10699    @Override
10700    public final ContentProviderHolder getContentProvider(
10701            IApplicationThread caller, String name, int userId, boolean stable) {
10702        enforceNotIsolatedCaller("getContentProvider");
10703        if (caller == null) {
10704            String msg = "null IApplicationThread when getting content provider "
10705                    + name;
10706            Slog.w(TAG, msg);
10707            throw new SecurityException(msg);
10708        }
10709        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10710        // with cross-user grant.
10711        return getContentProviderImpl(caller, name, null, stable, userId);
10712    }
10713
10714    public ContentProviderHolder getContentProviderExternal(
10715            String name, int userId, IBinder token) {
10716        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10717            "Do not have permission in call getContentProviderExternal()");
10718        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10719                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10720        return getContentProviderExternalUnchecked(name, token, userId);
10721    }
10722
10723    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10724            IBinder token, int userId) {
10725        return getContentProviderImpl(null, name, token, true, userId);
10726    }
10727
10728    /**
10729     * Drop a content provider from a ProcessRecord's bookkeeping
10730     */
10731    public void removeContentProvider(IBinder connection, boolean stable) {
10732        enforceNotIsolatedCaller("removeContentProvider");
10733        long ident = Binder.clearCallingIdentity();
10734        try {
10735            synchronized (this) {
10736                ContentProviderConnection conn;
10737                try {
10738                    conn = (ContentProviderConnection)connection;
10739                } catch (ClassCastException e) {
10740                    String msg ="removeContentProvider: " + connection
10741                            + " not a ContentProviderConnection";
10742                    Slog.w(TAG, msg);
10743                    throw new IllegalArgumentException(msg);
10744                }
10745                if (conn == null) {
10746                    throw new NullPointerException("connection is null");
10747                }
10748                if (decProviderCountLocked(conn, null, null, stable)) {
10749                    updateOomAdjLocked();
10750                }
10751            }
10752        } finally {
10753            Binder.restoreCallingIdentity(ident);
10754        }
10755    }
10756
10757    public void removeContentProviderExternal(String name, IBinder token) {
10758        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10759            "Do not have permission in call removeContentProviderExternal()");
10760        int userId = UserHandle.getCallingUserId();
10761        long ident = Binder.clearCallingIdentity();
10762        try {
10763            removeContentProviderExternalUnchecked(name, token, userId);
10764        } finally {
10765            Binder.restoreCallingIdentity(ident);
10766        }
10767    }
10768
10769    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10770        synchronized (this) {
10771            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10772            if(cpr == null) {
10773                //remove from mProvidersByClass
10774                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10775                return;
10776            }
10777
10778            //update content provider record entry info
10779            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10780            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10781            if (localCpr.hasExternalProcessHandles()) {
10782                if (localCpr.removeExternalProcessHandleLocked(token)) {
10783                    updateOomAdjLocked();
10784                } else {
10785                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10786                            + " with no external reference for token: "
10787                            + token + ".");
10788                }
10789            } else {
10790                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10791                        + " with no external references.");
10792            }
10793        }
10794    }
10795
10796    public final void publishContentProviders(IApplicationThread caller,
10797            List<ContentProviderHolder> providers) {
10798        if (providers == null) {
10799            return;
10800        }
10801
10802        enforceNotIsolatedCaller("publishContentProviders");
10803        synchronized (this) {
10804            final ProcessRecord r = getRecordForAppLocked(caller);
10805            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10806            if (r == null) {
10807                throw new SecurityException(
10808                        "Unable to find app for caller " + caller
10809                      + " (pid=" + Binder.getCallingPid()
10810                      + ") when publishing content providers");
10811            }
10812
10813            final long origId = Binder.clearCallingIdentity();
10814
10815            final int N = providers.size();
10816            for (int i = 0; i < N; i++) {
10817                ContentProviderHolder src = providers.get(i);
10818                if (src == null || src.info == null || src.provider == null) {
10819                    continue;
10820                }
10821                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10822                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10823                if (dst != null) {
10824                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10825                    mProviderMap.putProviderByClass(comp, dst);
10826                    String names[] = dst.info.authority.split(";");
10827                    for (int j = 0; j < names.length; j++) {
10828                        mProviderMap.putProviderByName(names[j], dst);
10829                    }
10830
10831                    int launchingCount = mLaunchingProviders.size();
10832                    int j;
10833                    boolean wasInLaunchingProviders = false;
10834                    for (j = 0; j < launchingCount; j++) {
10835                        if (mLaunchingProviders.get(j) == dst) {
10836                            mLaunchingProviders.remove(j);
10837                            wasInLaunchingProviders = true;
10838                            j--;
10839                            launchingCount--;
10840                        }
10841                    }
10842                    if (wasInLaunchingProviders) {
10843                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10844                    }
10845                    synchronized (dst) {
10846                        dst.provider = src.provider;
10847                        dst.proc = r;
10848                        dst.notifyAll();
10849                    }
10850                    updateOomAdjLocked(r);
10851                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10852                            src.info.authority);
10853                }
10854            }
10855
10856            Binder.restoreCallingIdentity(origId);
10857        }
10858    }
10859
10860    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10861        ContentProviderConnection conn;
10862        try {
10863            conn = (ContentProviderConnection)connection;
10864        } catch (ClassCastException e) {
10865            String msg ="refContentProvider: " + connection
10866                    + " not a ContentProviderConnection";
10867            Slog.w(TAG, msg);
10868            throw new IllegalArgumentException(msg);
10869        }
10870        if (conn == null) {
10871            throw new NullPointerException("connection is null");
10872        }
10873
10874        synchronized (this) {
10875            if (stable > 0) {
10876                conn.numStableIncs += stable;
10877            }
10878            stable = conn.stableCount + stable;
10879            if (stable < 0) {
10880                throw new IllegalStateException("stableCount < 0: " + stable);
10881            }
10882
10883            if (unstable > 0) {
10884                conn.numUnstableIncs += unstable;
10885            }
10886            unstable = conn.unstableCount + unstable;
10887            if (unstable < 0) {
10888                throw new IllegalStateException("unstableCount < 0: " + unstable);
10889            }
10890
10891            if ((stable+unstable) <= 0) {
10892                throw new IllegalStateException("ref counts can't go to zero here: stable="
10893                        + stable + " unstable=" + unstable);
10894            }
10895            conn.stableCount = stable;
10896            conn.unstableCount = unstable;
10897            return !conn.dead;
10898        }
10899    }
10900
10901    public void unstableProviderDied(IBinder connection) {
10902        ContentProviderConnection conn;
10903        try {
10904            conn = (ContentProviderConnection)connection;
10905        } catch (ClassCastException e) {
10906            String msg ="refContentProvider: " + connection
10907                    + " not a ContentProviderConnection";
10908            Slog.w(TAG, msg);
10909            throw new IllegalArgumentException(msg);
10910        }
10911        if (conn == null) {
10912            throw new NullPointerException("connection is null");
10913        }
10914
10915        // Safely retrieve the content provider associated with the connection.
10916        IContentProvider provider;
10917        synchronized (this) {
10918            provider = conn.provider.provider;
10919        }
10920
10921        if (provider == null) {
10922            // Um, yeah, we're way ahead of you.
10923            return;
10924        }
10925
10926        // Make sure the caller is being honest with us.
10927        if (provider.asBinder().pingBinder()) {
10928            // Er, no, still looks good to us.
10929            synchronized (this) {
10930                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10931                        + " says " + conn + " died, but we don't agree");
10932                return;
10933            }
10934        }
10935
10936        // Well look at that!  It's dead!
10937        synchronized (this) {
10938            if (conn.provider.provider != provider) {
10939                // But something changed...  good enough.
10940                return;
10941            }
10942
10943            ProcessRecord proc = conn.provider.proc;
10944            if (proc == null || proc.thread == null) {
10945                // Seems like the process is already cleaned up.
10946                return;
10947            }
10948
10949            // As far as we're concerned, this is just like receiving a
10950            // death notification...  just a bit prematurely.
10951            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10952                    + ") early provider death");
10953            final long ident = Binder.clearCallingIdentity();
10954            try {
10955                appDiedLocked(proc);
10956            } finally {
10957                Binder.restoreCallingIdentity(ident);
10958            }
10959        }
10960    }
10961
10962    @Override
10963    public void appNotRespondingViaProvider(IBinder connection) {
10964        enforceCallingPermission(
10965                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10966
10967        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10968        if (conn == null) {
10969            Slog.w(TAG, "ContentProviderConnection is null");
10970            return;
10971        }
10972
10973        final ProcessRecord host = conn.provider.proc;
10974        if (host == null) {
10975            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10976            return;
10977        }
10978
10979        mHandler.post(new Runnable() {
10980            @Override
10981            public void run() {
10982                mAppErrors.appNotResponding(host, null, null, false,
10983                        "ContentProvider not responding");
10984            }
10985        });
10986    }
10987
10988    public final void installSystemProviders() {
10989        List<ProviderInfo> providers;
10990        synchronized (this) {
10991            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10992            providers = generateApplicationProvidersLocked(app);
10993            if (providers != null) {
10994                for (int i=providers.size()-1; i>=0; i--) {
10995                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10996                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10997                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10998                                + ": not system .apk");
10999                        providers.remove(i);
11000                    }
11001                }
11002            }
11003        }
11004        if (providers != null) {
11005            mSystemThread.installSystemProviders(providers);
11006        }
11007
11008        mCoreSettingsObserver = new CoreSettingsObserver(this);
11009        mFontScaleSettingObserver = new FontScaleSettingObserver();
11010
11011        //mUsageStatsService.monitorPackages();
11012    }
11013
11014    private void startPersistentApps(int matchFlags) {
11015        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11016
11017        synchronized (this) {
11018            try {
11019                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11020                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11021                for (ApplicationInfo app : apps) {
11022                    if (!"android".equals(app.packageName)) {
11023                        addAppLocked(app, false, null /* ABI override */);
11024                    }
11025                }
11026            } catch (RemoteException ex) {
11027            }
11028        }
11029    }
11030
11031    /**
11032     * When a user is unlocked, we need to install encryption-unaware providers
11033     * belonging to any running apps.
11034     */
11035    private void installEncryptionUnawareProviders(int userId) {
11036        if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
11037            // TODO: eventually pivot this back to look at current user state,
11038            // similar to the comment in UserManager.isUserUnlocked(), but for
11039            // now, if we started apps when "unlocked" then unaware providers
11040            // have already been spun up.
11041            return;
11042        }
11043
11044        // We're only interested in providers that are encryption unaware, and
11045        // we don't care about uninstalled apps, since there's no way they're
11046        // running at this point.
11047        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11048
11049        synchronized (this) {
11050            final int NP = mProcessNames.getMap().size();
11051            for (int ip = 0; ip < NP; ip++) {
11052                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11053                final int NA = apps.size();
11054                for (int ia = 0; ia < NA; ia++) {
11055                    final ProcessRecord app = apps.valueAt(ia);
11056                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11057
11058                    final int NG = app.pkgList.size();
11059                    for (int ig = 0; ig < NG; ig++) {
11060                        try {
11061                            final String pkgName = app.pkgList.keyAt(ig);
11062                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11063                                    .getPackageInfo(pkgName, matchFlags, userId);
11064                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11065                                for (ProviderInfo provInfo : pkgInfo.providers) {
11066                                    Log.v(TAG, "Installing " + provInfo);
11067                                    app.thread.scheduleInstallProvider(provInfo);
11068                                }
11069                            }
11070                        } catch (RemoteException ignored) {
11071                        }
11072                    }
11073                }
11074            }
11075        }
11076    }
11077
11078    /**
11079     * Allows apps to retrieve the MIME type of a URI.
11080     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11081     * users, then it does not need permission to access the ContentProvider.
11082     * Either, it needs cross-user uri grants.
11083     *
11084     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11085     *
11086     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11087     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11088     */
11089    public String getProviderMimeType(Uri uri, int userId) {
11090        enforceNotIsolatedCaller("getProviderMimeType");
11091        final String name = uri.getAuthority();
11092        int callingUid = Binder.getCallingUid();
11093        int callingPid = Binder.getCallingPid();
11094        long ident = 0;
11095        boolean clearedIdentity = false;
11096        synchronized (this) {
11097            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11098        }
11099        if (canClearIdentity(callingPid, callingUid, userId)) {
11100            clearedIdentity = true;
11101            ident = Binder.clearCallingIdentity();
11102        }
11103        ContentProviderHolder holder = null;
11104        try {
11105            holder = getContentProviderExternalUnchecked(name, null, userId);
11106            if (holder != null) {
11107                return holder.provider.getType(uri);
11108            }
11109        } catch (RemoteException e) {
11110            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11111            return null;
11112        } finally {
11113            // We need to clear the identity to call removeContentProviderExternalUnchecked
11114            if (!clearedIdentity) {
11115                ident = Binder.clearCallingIdentity();
11116            }
11117            try {
11118                if (holder != null) {
11119                    removeContentProviderExternalUnchecked(name, null, userId);
11120                }
11121            } finally {
11122                Binder.restoreCallingIdentity(ident);
11123            }
11124        }
11125
11126        return null;
11127    }
11128
11129    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11130        if (UserHandle.getUserId(callingUid) == userId) {
11131            return true;
11132        }
11133        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11134                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11135                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11136                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11137                return true;
11138        }
11139        return false;
11140    }
11141
11142    // =========================================================
11143    // GLOBAL MANAGEMENT
11144    // =========================================================
11145
11146    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11147            boolean isolated, int isolatedUid) {
11148        String proc = customProcess != null ? customProcess : info.processName;
11149        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11150        final int userId = UserHandle.getUserId(info.uid);
11151        int uid = info.uid;
11152        if (isolated) {
11153            if (isolatedUid == 0) {
11154                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11155                while (true) {
11156                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11157                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11158                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11159                    }
11160                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11161                    mNextIsolatedProcessUid++;
11162                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11163                        // No process for this uid, use it.
11164                        break;
11165                    }
11166                    stepsLeft--;
11167                    if (stepsLeft <= 0) {
11168                        return null;
11169                    }
11170                }
11171            } else {
11172                // Special case for startIsolatedProcess (internal only), where
11173                // the uid of the isolated process is specified by the caller.
11174                uid = isolatedUid;
11175            }
11176        }
11177        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11178        if (!mBooted && !mBooting
11179                && userId == UserHandle.USER_SYSTEM
11180                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11181            r.persistent = true;
11182        }
11183        addProcessNameLocked(r);
11184        return r;
11185    }
11186
11187    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11188            String abiOverride) {
11189        ProcessRecord app;
11190        if (!isolated) {
11191            app = getProcessRecordLocked(info.processName, info.uid, true);
11192        } else {
11193            app = null;
11194        }
11195
11196        if (app == null) {
11197            app = newProcessRecordLocked(info, null, isolated, 0);
11198            updateLruProcessLocked(app, false, null);
11199            updateOomAdjLocked();
11200        }
11201
11202        // This package really, really can not be stopped.
11203        try {
11204            AppGlobals.getPackageManager().setPackageStoppedState(
11205                    info.packageName, false, UserHandle.getUserId(app.uid));
11206        } catch (RemoteException e) {
11207        } catch (IllegalArgumentException e) {
11208            Slog.w(TAG, "Failed trying to unstop package "
11209                    + info.packageName + ": " + e);
11210        }
11211
11212        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11213            app.persistent = true;
11214            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11215        }
11216        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11217            mPersistentStartingProcesses.add(app);
11218            startProcessLocked(app, "added application", app.processName, abiOverride,
11219                    null /* entryPoint */, null /* entryPointArgs */);
11220        }
11221
11222        return app;
11223    }
11224
11225    public void unhandledBack() {
11226        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11227                "unhandledBack()");
11228
11229        synchronized(this) {
11230            final long origId = Binder.clearCallingIdentity();
11231            try {
11232                getFocusedStack().unhandledBackLocked();
11233            } finally {
11234                Binder.restoreCallingIdentity(origId);
11235            }
11236        }
11237    }
11238
11239    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11240        enforceNotIsolatedCaller("openContentUri");
11241        final int userId = UserHandle.getCallingUserId();
11242        String name = uri.getAuthority();
11243        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11244        ParcelFileDescriptor pfd = null;
11245        if (cph != null) {
11246            // We record the binder invoker's uid in thread-local storage before
11247            // going to the content provider to open the file.  Later, in the code
11248            // that handles all permissions checks, we look for this uid and use
11249            // that rather than the Activity Manager's own uid.  The effect is that
11250            // we do the check against the caller's permissions even though it looks
11251            // to the content provider like the Activity Manager itself is making
11252            // the request.
11253            Binder token = new Binder();
11254            sCallerIdentity.set(new Identity(
11255                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11256            try {
11257                pfd = cph.provider.openFile(null, uri, "r", null, token);
11258            } catch (FileNotFoundException e) {
11259                // do nothing; pfd will be returned null
11260            } finally {
11261                // Ensure that whatever happens, we clean up the identity state
11262                sCallerIdentity.remove();
11263                // Ensure we're done with the provider.
11264                removeContentProviderExternalUnchecked(name, null, userId);
11265            }
11266        } else {
11267            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11268        }
11269        return pfd;
11270    }
11271
11272    // Actually is sleeping or shutting down or whatever else in the future
11273    // is an inactive state.
11274    public boolean isSleepingOrShuttingDown() {
11275        return isSleeping() || mShuttingDown;
11276    }
11277
11278    public boolean isSleeping() {
11279        return mSleeping;
11280    }
11281
11282    void onWakefulnessChanged(int wakefulness) {
11283        synchronized(this) {
11284            mWakefulness = wakefulness;
11285            updateSleepIfNeededLocked();
11286        }
11287    }
11288
11289    void finishRunningVoiceLocked() {
11290        if (mRunningVoice != null) {
11291            mRunningVoice = null;
11292            mVoiceWakeLock.release();
11293            updateSleepIfNeededLocked();
11294        }
11295    }
11296
11297    void startTimeTrackingFocusedActivityLocked() {
11298        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11299            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11300        }
11301    }
11302
11303    void updateSleepIfNeededLocked() {
11304        if (mSleeping && !shouldSleepLocked()) {
11305            mSleeping = false;
11306            startTimeTrackingFocusedActivityLocked();
11307            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11308            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11309            updateOomAdjLocked();
11310        } else if (!mSleeping && shouldSleepLocked()) {
11311            mSleeping = true;
11312            if (mCurAppTimeTracker != null) {
11313                mCurAppTimeTracker.stop();
11314            }
11315            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11316            mStackSupervisor.goingToSleepLocked();
11317            updateOomAdjLocked();
11318
11319            // Initialize the wake times of all processes.
11320            checkExcessivePowerUsageLocked(false);
11321            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11322            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11323            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11324        }
11325    }
11326
11327    private boolean shouldSleepLocked() {
11328        // Resume applications while running a voice interactor.
11329        if (mRunningVoice != null) {
11330            return false;
11331        }
11332
11333        // TODO: Transform the lock screen state into a sleep token instead.
11334        switch (mWakefulness) {
11335            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11336            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11337            case PowerManagerInternal.WAKEFULNESS_DOZING:
11338                // Pause applications whenever the lock screen is shown or any sleep
11339                // tokens have been acquired.
11340                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11341            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11342            default:
11343                // If we're asleep then pause applications unconditionally.
11344                return true;
11345        }
11346    }
11347
11348    /** Pokes the task persister. */
11349    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11350        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11351    }
11352
11353    /** Notifies all listeners when the task stack has changed. */
11354    void notifyTaskStackChangedLocked() {
11355        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11356        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11357        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11358        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11359    }
11360
11361    /** Notifies all listeners when an Activity is pinned. */
11362    void notifyActivityPinnedLocked() {
11363        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11364        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11365    }
11366
11367    /**
11368     * Notifies all listeners when an attempt was made to start an an activity that is already
11369     * running in the pinned stack and the activity was not actually started, but the task is
11370     * either brought to the front or a new Intent is delivered to it.
11371     */
11372    void notifyPinnedActivityRestartAttemptLocked() {
11373        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11374        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11375    }
11376
11377    /** Notifies all listeners when the pinned stack animation ends. */
11378    @Override
11379    public void notifyPinnedStackAnimationEnded() {
11380        synchronized (this) {
11381            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11382            mHandler.obtainMessage(
11383                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11384        }
11385    }
11386
11387    @Override
11388    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11389        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11390    }
11391
11392    @Override
11393    public boolean shutdown(int timeout) {
11394        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11395                != PackageManager.PERMISSION_GRANTED) {
11396            throw new SecurityException("Requires permission "
11397                    + android.Manifest.permission.SHUTDOWN);
11398        }
11399
11400        boolean timedout = false;
11401
11402        synchronized(this) {
11403            mShuttingDown = true;
11404            updateEventDispatchingLocked();
11405            timedout = mStackSupervisor.shutdownLocked(timeout);
11406        }
11407
11408        mAppOpsService.shutdown();
11409        if (mUsageStatsService != null) {
11410            mUsageStatsService.prepareShutdown();
11411        }
11412        mBatteryStatsService.shutdown();
11413        synchronized (this) {
11414            mProcessStats.shutdownLocked();
11415            notifyTaskPersisterLocked(null, true);
11416        }
11417
11418        return timedout;
11419    }
11420
11421    public final void activitySlept(IBinder token) {
11422        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11423
11424        final long origId = Binder.clearCallingIdentity();
11425
11426        synchronized (this) {
11427            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11428            if (r != null) {
11429                mStackSupervisor.activitySleptLocked(r);
11430            }
11431        }
11432
11433        Binder.restoreCallingIdentity(origId);
11434    }
11435
11436    private String lockScreenShownToString() {
11437        switch (mLockScreenShown) {
11438            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11439            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11440            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11441            default: return "Unknown=" + mLockScreenShown;
11442        }
11443    }
11444
11445    void logLockScreen(String msg) {
11446        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11447                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11448                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11449                + " mSleeping=" + mSleeping);
11450    }
11451
11452    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11453        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11454        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11455        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11456            boolean wasRunningVoice = mRunningVoice != null;
11457            mRunningVoice = session;
11458            if (!wasRunningVoice) {
11459                mVoiceWakeLock.acquire();
11460                updateSleepIfNeededLocked();
11461            }
11462        }
11463    }
11464
11465    private void updateEventDispatchingLocked() {
11466        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11467    }
11468
11469    public void setLockScreenShown(boolean shown) {
11470        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11471                != PackageManager.PERMISSION_GRANTED) {
11472            throw new SecurityException("Requires permission "
11473                    + android.Manifest.permission.DEVICE_POWER);
11474        }
11475
11476        synchronized(this) {
11477            long ident = Binder.clearCallingIdentity();
11478            try {
11479                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11480                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11481                updateSleepIfNeededLocked();
11482            } finally {
11483                Binder.restoreCallingIdentity(ident);
11484            }
11485        }
11486    }
11487
11488    @Override
11489    public void notifyLockedProfile(@UserIdInt int userId) {
11490        try {
11491            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11492                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11493            }
11494        } catch (RemoteException ex) {
11495            throw new SecurityException("Fail to check is caller a privileged app", ex);
11496        }
11497
11498        synchronized (this) {
11499            if (mStackSupervisor.isUserLockedProfile(userId)) {
11500                final long ident = Binder.clearCallingIdentity();
11501                try {
11502                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11503                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11504                        // If there is no device lock, we will show the profile's credential page.
11505                        mActivityStarter.showConfirmDeviceCredential(userId);
11506                    } else {
11507                        // Showing launcher to avoid user entering credential twice.
11508                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11509                    }
11510                } finally {
11511                    Binder.restoreCallingIdentity(ident);
11512                }
11513            }
11514        }
11515    }
11516
11517    @Override
11518    public void startConfirmDeviceCredentialIntent(Intent intent) {
11519        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11520        synchronized (this) {
11521            final long ident = Binder.clearCallingIdentity();
11522            try {
11523                mActivityStarter.startConfirmCredentialIntent(intent);
11524            } finally {
11525                Binder.restoreCallingIdentity(ident);
11526            }
11527        }
11528    }
11529
11530    @Override
11531    public void stopAppSwitches() {
11532        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11533                != PackageManager.PERMISSION_GRANTED) {
11534            throw new SecurityException("viewquires permission "
11535                    + android.Manifest.permission.STOP_APP_SWITCHES);
11536        }
11537
11538        synchronized(this) {
11539            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11540                    + APP_SWITCH_DELAY_TIME;
11541            mDidAppSwitch = false;
11542            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11543            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11544            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11545        }
11546    }
11547
11548    public void resumeAppSwitches() {
11549        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11550                != PackageManager.PERMISSION_GRANTED) {
11551            throw new SecurityException("Requires permission "
11552                    + android.Manifest.permission.STOP_APP_SWITCHES);
11553        }
11554
11555        synchronized(this) {
11556            // Note that we don't execute any pending app switches... we will
11557            // let those wait until either the timeout, or the next start
11558            // activity request.
11559            mAppSwitchesAllowedTime = 0;
11560        }
11561    }
11562
11563    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11564            int callingPid, int callingUid, String name) {
11565        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11566            return true;
11567        }
11568
11569        int perm = checkComponentPermission(
11570                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11571                sourceUid, -1, true);
11572        if (perm == PackageManager.PERMISSION_GRANTED) {
11573            return true;
11574        }
11575
11576        // If the actual IPC caller is different from the logical source, then
11577        // also see if they are allowed to control app switches.
11578        if (callingUid != -1 && callingUid != sourceUid) {
11579            perm = checkComponentPermission(
11580                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11581                    callingUid, -1, true);
11582            if (perm == PackageManager.PERMISSION_GRANTED) {
11583                return true;
11584            }
11585        }
11586
11587        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11588        return false;
11589    }
11590
11591    public void setDebugApp(String packageName, boolean waitForDebugger,
11592            boolean persistent) {
11593        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11594                "setDebugApp()");
11595
11596        long ident = Binder.clearCallingIdentity();
11597        try {
11598            // Note that this is not really thread safe if there are multiple
11599            // callers into it at the same time, but that's not a situation we
11600            // care about.
11601            if (persistent) {
11602                final ContentResolver resolver = mContext.getContentResolver();
11603                Settings.Global.putString(
11604                    resolver, Settings.Global.DEBUG_APP,
11605                    packageName);
11606                Settings.Global.putInt(
11607                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11608                    waitForDebugger ? 1 : 0);
11609            }
11610
11611            synchronized (this) {
11612                if (!persistent) {
11613                    mOrigDebugApp = mDebugApp;
11614                    mOrigWaitForDebugger = mWaitForDebugger;
11615                }
11616                mDebugApp = packageName;
11617                mWaitForDebugger = waitForDebugger;
11618                mDebugTransient = !persistent;
11619                if (packageName != null) {
11620                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11621                            false, UserHandle.USER_ALL, "set debug app");
11622                }
11623            }
11624        } finally {
11625            Binder.restoreCallingIdentity(ident);
11626        }
11627    }
11628
11629    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11630        synchronized (this) {
11631            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11632            if (!isDebuggable) {
11633                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11634                    throw new SecurityException("Process not debuggable: " + app.packageName);
11635                }
11636            }
11637
11638            mTrackAllocationApp = processName;
11639        }
11640    }
11641
11642    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11643        synchronized (this) {
11644            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11645            if (!isDebuggable) {
11646                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11647                    throw new SecurityException("Process not debuggable: " + app.packageName);
11648                }
11649            }
11650            mProfileApp = processName;
11651            mProfileFile = profilerInfo.profileFile;
11652            if (mProfileFd != null) {
11653                try {
11654                    mProfileFd.close();
11655                } catch (IOException e) {
11656                }
11657                mProfileFd = null;
11658            }
11659            mProfileFd = profilerInfo.profileFd;
11660            mSamplingInterval = profilerInfo.samplingInterval;
11661            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11662            mProfileType = 0;
11663        }
11664    }
11665
11666    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11667        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11668        if (!isDebuggable) {
11669            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11670                throw new SecurityException("Process not debuggable: " + app.packageName);
11671            }
11672        }
11673        mNativeDebuggingApp = processName;
11674    }
11675
11676    @Override
11677    public void setAlwaysFinish(boolean enabled) {
11678        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11679                "setAlwaysFinish()");
11680
11681        long ident = Binder.clearCallingIdentity();
11682        try {
11683            Settings.Global.putInt(
11684                    mContext.getContentResolver(),
11685                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11686
11687            synchronized (this) {
11688                mAlwaysFinishActivities = enabled;
11689            }
11690        } finally {
11691            Binder.restoreCallingIdentity(ident);
11692        }
11693    }
11694
11695    @Override
11696    public void setLenientBackgroundCheck(boolean enabled) {
11697        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11698                "setLenientBackgroundCheck()");
11699
11700        long ident = Binder.clearCallingIdentity();
11701        try {
11702            Settings.Global.putInt(
11703                    mContext.getContentResolver(),
11704                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11705
11706            synchronized (this) {
11707                mLenientBackgroundCheck = enabled;
11708            }
11709        } finally {
11710            Binder.restoreCallingIdentity(ident);
11711        }
11712    }
11713
11714    @Override
11715    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11716        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11717                "setActivityController()");
11718        synchronized (this) {
11719            mController = controller;
11720            mControllerIsAMonkey = imAMonkey;
11721            Watchdog.getInstance().setActivityController(controller);
11722        }
11723    }
11724
11725    @Override
11726    public void setUserIsMonkey(boolean userIsMonkey) {
11727        synchronized (this) {
11728            synchronized (mPidsSelfLocked) {
11729                final int callingPid = Binder.getCallingPid();
11730                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11731                if (precessRecord == null) {
11732                    throw new SecurityException("Unknown process: " + callingPid);
11733                }
11734                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11735                    throw new SecurityException("Only an instrumentation process "
11736                            + "with a UiAutomation can call setUserIsMonkey");
11737                }
11738            }
11739            mUserIsMonkey = userIsMonkey;
11740        }
11741    }
11742
11743    @Override
11744    public boolean isUserAMonkey() {
11745        synchronized (this) {
11746            // If there is a controller also implies the user is a monkey.
11747            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11748        }
11749    }
11750
11751    public void requestBugReport(int bugreportType) {
11752        String service = null;
11753        switch (bugreportType) {
11754            case ActivityManager.BUGREPORT_OPTION_FULL:
11755                service = "bugreport";
11756                break;
11757            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11758                service = "bugreportplus";
11759                break;
11760            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11761                service = "bugreportremote";
11762                break;
11763        }
11764        if (service == null) {
11765            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11766                    + bugreportType);
11767        }
11768        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11769        SystemProperties.set("ctl.start", service);
11770    }
11771
11772    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11773        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11774    }
11775
11776    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11777        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11778            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11779        }
11780        return KEY_DISPATCHING_TIMEOUT;
11781    }
11782
11783    @Override
11784    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11785        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11786                != PackageManager.PERMISSION_GRANTED) {
11787            throw new SecurityException("Requires permission "
11788                    + android.Manifest.permission.FILTER_EVENTS);
11789        }
11790        ProcessRecord proc;
11791        long timeout;
11792        synchronized (this) {
11793            synchronized (mPidsSelfLocked) {
11794                proc = mPidsSelfLocked.get(pid);
11795            }
11796            timeout = getInputDispatchingTimeoutLocked(proc);
11797        }
11798
11799        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11800            return -1;
11801        }
11802
11803        return timeout;
11804    }
11805
11806    /**
11807     * Handle input dispatching timeouts.
11808     * Returns whether input dispatching should be aborted or not.
11809     */
11810    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11811            final ActivityRecord activity, final ActivityRecord parent,
11812            final boolean aboveSystem, String reason) {
11813        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11814                != PackageManager.PERMISSION_GRANTED) {
11815            throw new SecurityException("Requires permission "
11816                    + android.Manifest.permission.FILTER_EVENTS);
11817        }
11818
11819        final String annotation;
11820        if (reason == null) {
11821            annotation = "Input dispatching timed out";
11822        } else {
11823            annotation = "Input dispatching timed out (" + reason + ")";
11824        }
11825
11826        if (proc != null) {
11827            synchronized (this) {
11828                if (proc.debugging) {
11829                    return false;
11830                }
11831
11832                if (mDidDexOpt) {
11833                    // Give more time since we were dexopting.
11834                    mDidDexOpt = false;
11835                    return false;
11836                }
11837
11838                if (proc.instrumentationClass != null) {
11839                    Bundle info = new Bundle();
11840                    info.putString("shortMsg", "keyDispatchingTimedOut");
11841                    info.putString("longMsg", annotation);
11842                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11843                    return true;
11844                }
11845            }
11846            mHandler.post(new Runnable() {
11847                @Override
11848                public void run() {
11849                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11850                }
11851            });
11852        }
11853
11854        return true;
11855    }
11856
11857    @Override
11858    public Bundle getAssistContextExtras(int requestType) {
11859        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11860                null, null, true, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11861        if (pae == null) {
11862            return null;
11863        }
11864        synchronized (pae) {
11865            while (!pae.haveResult) {
11866                try {
11867                    pae.wait();
11868                } catch (InterruptedException e) {
11869                }
11870            }
11871        }
11872        synchronized (this) {
11873            buildAssistBundleLocked(pae, pae.result);
11874            mPendingAssistExtras.remove(pae);
11875            mUiHandler.removeCallbacks(pae);
11876        }
11877        return pae.extras;
11878    }
11879
11880    @Override
11881    public boolean isAssistDataAllowedOnCurrentActivity() {
11882        int userId;
11883        synchronized (this) {
11884            userId = mUserController.getCurrentUserIdLocked();
11885            ActivityRecord activity = getFocusedStack().topActivity();
11886            if (activity == null) {
11887                return false;
11888            }
11889            userId = activity.userId;
11890        }
11891        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11892                Context.DEVICE_POLICY_SERVICE);
11893        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11894    }
11895
11896    @Override
11897    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11898        long ident = Binder.clearCallingIdentity();
11899        try {
11900            synchronized (this) {
11901                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11902                ActivityRecord top = getFocusedStack().topActivity();
11903                if (top != caller) {
11904                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11905                            + " is not current top " + top);
11906                    return false;
11907                }
11908                if (!top.nowVisible) {
11909                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11910                            + " is not visible");
11911                    return false;
11912                }
11913            }
11914            AssistUtils utils = new AssistUtils(mContext);
11915            return utils.showSessionForActiveService(args,
11916                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11917        } finally {
11918            Binder.restoreCallingIdentity(ident);
11919        }
11920    }
11921
11922    @Override
11923    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11924            Bundle receiverExtras,
11925            IBinder activityToken, boolean focused) {
11926        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11927                activityToken, focused,
11928                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11929                != null;
11930    }
11931
11932    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11933            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused,
11934            int userHandle, Bundle args, long timeout) {
11935        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11936                "enqueueAssistContext()");
11937        synchronized (this) {
11938            ActivityRecord activity = getFocusedStack().topActivity();
11939            if (activity == null) {
11940                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11941                return null;
11942            }
11943            if (activity.app == null || activity.app.thread == null) {
11944                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11945                return null;
11946            }
11947            if (focused) {
11948                if (activityToken != null) {
11949                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11950                    if (activity != caller) {
11951                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11952                                + " is not current top " + activity);
11953                        return null;
11954                    }
11955                }
11956            } else {
11957                activity = ActivityRecord.forTokenLocked(activityToken);
11958                if (activity == null) {
11959                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
11960                            + " couldn't be found");
11961                    return null;
11962                }
11963            }
11964
11965            PendingAssistExtras pae;
11966            Bundle extras = new Bundle();
11967            if (args != null) {
11968                extras.putAll(args);
11969            }
11970            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11971            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11972            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
11973                    userHandle);
11974            try {
11975                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11976                        requestType);
11977                mPendingAssistExtras.add(pae);
11978                mUiHandler.postDelayed(pae, timeout);
11979            } catch (RemoteException e) {
11980                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11981                return null;
11982            }
11983            return pae;
11984        }
11985    }
11986
11987    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11988        IResultReceiver receiver;
11989        synchronized (this) {
11990            mPendingAssistExtras.remove(pae);
11991            receiver = pae.receiver;
11992        }
11993        if (receiver != null) {
11994            // Caller wants result sent back to them.
11995            Bundle sendBundle = new Bundle();
11996            // At least return the receiver extras
11997            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
11998                    pae.receiverExtras);
11999            try {
12000                pae.receiver.send(0, sendBundle);
12001            } catch (RemoteException e) {
12002            }
12003        }
12004    }
12005
12006    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12007        if (result != null) {
12008            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12009        }
12010        if (pae.hint != null) {
12011            pae.extras.putBoolean(pae.hint, true);
12012        }
12013    }
12014
12015    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12016            AssistContent content, Uri referrer) {
12017        PendingAssistExtras pae = (PendingAssistExtras)token;
12018        synchronized (pae) {
12019            pae.result = extras;
12020            pae.structure = structure;
12021            pae.content = content;
12022            if (referrer != null) {
12023                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12024            }
12025            pae.haveResult = true;
12026            pae.notifyAll();
12027            if (pae.intent == null && pae.receiver == null) {
12028                // Caller is just waiting for the result.
12029                return;
12030            }
12031        }
12032
12033        // We are now ready to launch the assist activity.
12034        IResultReceiver sendReceiver = null;
12035        Bundle sendBundle = null;
12036        synchronized (this) {
12037            buildAssistBundleLocked(pae, extras);
12038            boolean exists = mPendingAssistExtras.remove(pae);
12039            mUiHandler.removeCallbacks(pae);
12040            if (!exists) {
12041                // Timed out.
12042                return;
12043            }
12044            if ((sendReceiver=pae.receiver) != null) {
12045                // Caller wants result sent back to them.
12046                sendBundle = new Bundle();
12047                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12048                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12049                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12050                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12051                        pae.receiverExtras);
12052            }
12053        }
12054        if (sendReceiver != null) {
12055            try {
12056                sendReceiver.send(0, sendBundle);
12057            } catch (RemoteException e) {
12058            }
12059            return;
12060        }
12061
12062        long ident = Binder.clearCallingIdentity();
12063        try {
12064            pae.intent.replaceExtras(pae.extras);
12065            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12066                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12067                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12068            closeSystemDialogs("assist");
12069            try {
12070                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12071            } catch (ActivityNotFoundException e) {
12072                Slog.w(TAG, "No activity to handle assist action.", e);
12073            }
12074        } finally {
12075            Binder.restoreCallingIdentity(ident);
12076        }
12077    }
12078
12079    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12080            Bundle args) {
12081        return enqueueAssistContext(requestType, intent, hint, null, null, null, true,
12082                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12083    }
12084
12085    public void registerProcessObserver(IProcessObserver observer) {
12086        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12087                "registerProcessObserver()");
12088        synchronized (this) {
12089            mProcessObservers.register(observer);
12090        }
12091    }
12092
12093    @Override
12094    public void unregisterProcessObserver(IProcessObserver observer) {
12095        synchronized (this) {
12096            mProcessObservers.unregister(observer);
12097        }
12098    }
12099
12100    @Override
12101    public void registerUidObserver(IUidObserver observer, int which) {
12102        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12103                "registerUidObserver()");
12104        synchronized (this) {
12105            mUidObservers.register(observer, which);
12106        }
12107    }
12108
12109    @Override
12110    public void unregisterUidObserver(IUidObserver observer) {
12111        synchronized (this) {
12112            mUidObservers.unregister(observer);
12113        }
12114    }
12115
12116    @Override
12117    public boolean convertFromTranslucent(IBinder token) {
12118        final long origId = Binder.clearCallingIdentity();
12119        try {
12120            synchronized (this) {
12121                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12122                if (r == null) {
12123                    return false;
12124                }
12125                final boolean translucentChanged = r.changeWindowTranslucency(true);
12126                if (translucentChanged) {
12127                    r.task.stack.releaseBackgroundResources(r);
12128                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12129                }
12130                mWindowManager.setAppFullscreen(token, true);
12131                return translucentChanged;
12132            }
12133        } finally {
12134            Binder.restoreCallingIdentity(origId);
12135        }
12136    }
12137
12138    @Override
12139    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12140        final long origId = Binder.clearCallingIdentity();
12141        try {
12142            synchronized (this) {
12143                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12144                if (r == null) {
12145                    return false;
12146                }
12147                int index = r.task.mActivities.lastIndexOf(r);
12148                if (index > 0) {
12149                    ActivityRecord under = r.task.mActivities.get(index - 1);
12150                    under.returningOptions = options;
12151                }
12152                final boolean translucentChanged = r.changeWindowTranslucency(false);
12153                if (translucentChanged) {
12154                    r.task.stack.convertActivityToTranslucent(r);
12155                }
12156                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12157                mWindowManager.setAppFullscreen(token, false);
12158                return translucentChanged;
12159            }
12160        } finally {
12161            Binder.restoreCallingIdentity(origId);
12162        }
12163    }
12164
12165    @Override
12166    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12167        final long origId = Binder.clearCallingIdentity();
12168        try {
12169            synchronized (this) {
12170                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12171                if (r != null) {
12172                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12173                }
12174            }
12175            return false;
12176        } finally {
12177            Binder.restoreCallingIdentity(origId);
12178        }
12179    }
12180
12181    @Override
12182    public boolean isBackgroundVisibleBehind(IBinder token) {
12183        final long origId = Binder.clearCallingIdentity();
12184        try {
12185            synchronized (this) {
12186                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12187                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12188                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12189                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12190                return visible;
12191            }
12192        } finally {
12193            Binder.restoreCallingIdentity(origId);
12194        }
12195    }
12196
12197    @Override
12198    public ActivityOptions getActivityOptions(IBinder token) {
12199        final long origId = Binder.clearCallingIdentity();
12200        try {
12201            synchronized (this) {
12202                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12203                if (r != null) {
12204                    final ActivityOptions activityOptions = r.pendingOptions;
12205                    r.pendingOptions = null;
12206                    return activityOptions;
12207                }
12208                return null;
12209            }
12210        } finally {
12211            Binder.restoreCallingIdentity(origId);
12212        }
12213    }
12214
12215    @Override
12216    public void setImmersive(IBinder token, boolean immersive) {
12217        synchronized(this) {
12218            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12219            if (r == null) {
12220                throw new IllegalArgumentException();
12221            }
12222            r.immersive = immersive;
12223
12224            // update associated state if we're frontmost
12225            if (r == mFocusedActivity) {
12226                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12227                applyUpdateLockStateLocked(r);
12228            }
12229        }
12230    }
12231
12232    @Override
12233    public boolean isImmersive(IBinder token) {
12234        synchronized (this) {
12235            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12236            if (r == null) {
12237                throw new IllegalArgumentException();
12238            }
12239            return r.immersive;
12240        }
12241    }
12242
12243    @Override
12244    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12245        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12246            throw new UnsupportedOperationException("VR mode not supported on this device!");
12247        }
12248
12249        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12250
12251        ActivityRecord r;
12252        synchronized (this) {
12253            r = ActivityRecord.isInStackLocked(token);
12254        }
12255
12256        if (r == null) {
12257            throw new IllegalArgumentException();
12258        }
12259
12260        int err;
12261        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12262                VrManagerInternal.NO_ERROR) {
12263            return err;
12264        }
12265
12266        synchronized(this) {
12267            r.requestedVrComponent = (enabled) ? packageName : null;
12268
12269            // Update associated state if this activity is currently focused
12270            if (r == mFocusedActivity) {
12271                applyUpdateVrModeLocked(r);
12272            }
12273            return 0;
12274        }
12275    }
12276
12277    @Override
12278    public boolean isVrModePackageEnabled(ComponentName packageName) {
12279        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12280            throw new UnsupportedOperationException("VR mode not supported on this device!");
12281        }
12282
12283        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12284
12285        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12286                VrManagerInternal.NO_ERROR;
12287    }
12288
12289    public boolean isTopActivityImmersive() {
12290        enforceNotIsolatedCaller("startActivity");
12291        synchronized (this) {
12292            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12293            return (r != null) ? r.immersive : false;
12294        }
12295    }
12296
12297    @Override
12298    public boolean isTopOfTask(IBinder token) {
12299        synchronized (this) {
12300            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12301            if (r == null) {
12302                throw new IllegalArgumentException();
12303            }
12304            return r.task.getTopActivity() == r;
12305        }
12306    }
12307
12308    public final void enterSafeMode() {
12309        synchronized(this) {
12310            // It only makes sense to do this before the system is ready
12311            // and started launching other packages.
12312            if (!mSystemReady) {
12313                try {
12314                    AppGlobals.getPackageManager().enterSafeMode();
12315                } catch (RemoteException e) {
12316                }
12317            }
12318
12319            mSafeMode = true;
12320        }
12321    }
12322
12323    public final void showSafeModeOverlay() {
12324        View v = LayoutInflater.from(mContext).inflate(
12325                com.android.internal.R.layout.safe_mode, null);
12326        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12327        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12328        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12329        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12330        lp.gravity = Gravity.BOTTOM | Gravity.START;
12331        lp.format = v.getBackground().getOpacity();
12332        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12333                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12334        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12335        ((WindowManager)mContext.getSystemService(
12336                Context.WINDOW_SERVICE)).addView(v, lp);
12337    }
12338
12339    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12340        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12341            return;
12342        }
12343        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12344        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12345        synchronized (stats) {
12346            if (mBatteryStatsService.isOnBattery()) {
12347                mBatteryStatsService.enforceCallingPermission();
12348                int MY_UID = Binder.getCallingUid();
12349                final int uid;
12350                if (sender == null) {
12351                    uid = sourceUid;
12352                } else {
12353                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12354                }
12355                BatteryStatsImpl.Uid.Pkg pkg =
12356                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12357                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12358                pkg.noteWakeupAlarmLocked(tag);
12359            }
12360        }
12361    }
12362
12363    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12364        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12365            return;
12366        }
12367        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12368        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12369        synchronized (stats) {
12370            mBatteryStatsService.enforceCallingPermission();
12371            int MY_UID = Binder.getCallingUid();
12372            final int uid;
12373            if (sender == null) {
12374                uid = sourceUid;
12375            } else {
12376                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12377            }
12378            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12379        }
12380    }
12381
12382    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12383        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12384            return;
12385        }
12386        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12387        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12388        synchronized (stats) {
12389            mBatteryStatsService.enforceCallingPermission();
12390            int MY_UID = Binder.getCallingUid();
12391            final int uid;
12392            if (sender == null) {
12393                uid = sourceUid;
12394            } else {
12395                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12396            }
12397            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12398        }
12399    }
12400
12401    public boolean killPids(int[] pids, String pReason, boolean secure) {
12402        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12403            throw new SecurityException("killPids only available to the system");
12404        }
12405        String reason = (pReason == null) ? "Unknown" : pReason;
12406        // XXX Note: don't acquire main activity lock here, because the window
12407        // manager calls in with its locks held.
12408
12409        boolean killed = false;
12410        synchronized (mPidsSelfLocked) {
12411            int worstType = 0;
12412            for (int i=0; i<pids.length; i++) {
12413                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12414                if (proc != null) {
12415                    int type = proc.setAdj;
12416                    if (type > worstType) {
12417                        worstType = type;
12418                    }
12419                }
12420            }
12421
12422            // If the worst oom_adj is somewhere in the cached proc LRU range,
12423            // then constrain it so we will kill all cached procs.
12424            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12425                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12426                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12427            }
12428
12429            // If this is not a secure call, don't let it kill processes that
12430            // are important.
12431            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12432                worstType = ProcessList.SERVICE_ADJ;
12433            }
12434
12435            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12436            for (int i=0; i<pids.length; i++) {
12437                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12438                if (proc == null) {
12439                    continue;
12440                }
12441                int adj = proc.setAdj;
12442                if (adj >= worstType && !proc.killedByAm) {
12443                    proc.kill(reason, true);
12444                    killed = true;
12445                }
12446            }
12447        }
12448        return killed;
12449    }
12450
12451    @Override
12452    public void killUid(int appId, int userId, String reason) {
12453        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12454        synchronized (this) {
12455            final long identity = Binder.clearCallingIdentity();
12456            try {
12457                killPackageProcessesLocked(null, appId, userId,
12458                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12459                        reason != null ? reason : "kill uid");
12460            } finally {
12461                Binder.restoreCallingIdentity(identity);
12462            }
12463        }
12464    }
12465
12466    @Override
12467    public boolean killProcessesBelowForeground(String reason) {
12468        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12469            throw new SecurityException("killProcessesBelowForeground() only available to system");
12470        }
12471
12472        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12473    }
12474
12475    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12476        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12477            throw new SecurityException("killProcessesBelowAdj() only available to system");
12478        }
12479
12480        boolean killed = false;
12481        synchronized (mPidsSelfLocked) {
12482            final int size = mPidsSelfLocked.size();
12483            for (int i = 0; i < size; i++) {
12484                final int pid = mPidsSelfLocked.keyAt(i);
12485                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12486                if (proc == null) continue;
12487
12488                final int adj = proc.setAdj;
12489                if (adj > belowAdj && !proc.killedByAm) {
12490                    proc.kill(reason, true);
12491                    killed = true;
12492                }
12493            }
12494        }
12495        return killed;
12496    }
12497
12498    @Override
12499    public void hang(final IBinder who, boolean allowRestart) {
12500        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12501                != PackageManager.PERMISSION_GRANTED) {
12502            throw new SecurityException("Requires permission "
12503                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12504        }
12505
12506        final IBinder.DeathRecipient death = new DeathRecipient() {
12507            @Override
12508            public void binderDied() {
12509                synchronized (this) {
12510                    notifyAll();
12511                }
12512            }
12513        };
12514
12515        try {
12516            who.linkToDeath(death, 0);
12517        } catch (RemoteException e) {
12518            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12519            return;
12520        }
12521
12522        synchronized (this) {
12523            Watchdog.getInstance().setAllowRestart(allowRestart);
12524            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12525            synchronized (death) {
12526                while (who.isBinderAlive()) {
12527                    try {
12528                        death.wait();
12529                    } catch (InterruptedException e) {
12530                    }
12531                }
12532            }
12533            Watchdog.getInstance().setAllowRestart(true);
12534        }
12535    }
12536
12537    @Override
12538    public void restart() {
12539        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12540                != PackageManager.PERMISSION_GRANTED) {
12541            throw new SecurityException("Requires permission "
12542                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12543        }
12544
12545        Log.i(TAG, "Sending shutdown broadcast...");
12546
12547        BroadcastReceiver br = new BroadcastReceiver() {
12548            @Override public void onReceive(Context context, Intent intent) {
12549                // Now the broadcast is done, finish up the low-level shutdown.
12550                Log.i(TAG, "Shutting down activity manager...");
12551                shutdown(10000);
12552                Log.i(TAG, "Shutdown complete, restarting!");
12553                Process.killProcess(Process.myPid());
12554                System.exit(10);
12555            }
12556        };
12557
12558        // First send the high-level shut down broadcast.
12559        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12560        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12561        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12562        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12563        mContext.sendOrderedBroadcastAsUser(intent,
12564                UserHandle.ALL, null, br, mHandler, 0, null, null);
12565        */
12566        br.onReceive(mContext, intent);
12567    }
12568
12569    private long getLowRamTimeSinceIdle(long now) {
12570        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12571    }
12572
12573    @Override
12574    public void performIdleMaintenance() {
12575        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12576                != PackageManager.PERMISSION_GRANTED) {
12577            throw new SecurityException("Requires permission "
12578                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12579        }
12580
12581        synchronized (this) {
12582            final long now = SystemClock.uptimeMillis();
12583            final long timeSinceLastIdle = now - mLastIdleTime;
12584            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12585            mLastIdleTime = now;
12586            mLowRamTimeSinceLastIdle = 0;
12587            if (mLowRamStartTime != 0) {
12588                mLowRamStartTime = now;
12589            }
12590
12591            StringBuilder sb = new StringBuilder(128);
12592            sb.append("Idle maintenance over ");
12593            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12594            sb.append(" low RAM for ");
12595            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12596            Slog.i(TAG, sb.toString());
12597
12598            // If at least 1/3 of our time since the last idle period has been spent
12599            // with RAM low, then we want to kill processes.
12600            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12601
12602            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12603                ProcessRecord proc = mLruProcesses.get(i);
12604                if (proc.notCachedSinceIdle) {
12605                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12606                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12607                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12608                        if (doKilling && proc.initialIdlePss != 0
12609                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12610                            sb = new StringBuilder(128);
12611                            sb.append("Kill");
12612                            sb.append(proc.processName);
12613                            sb.append(" in idle maint: pss=");
12614                            sb.append(proc.lastPss);
12615                            sb.append(", swapPss=");
12616                            sb.append(proc.lastSwapPss);
12617                            sb.append(", initialPss=");
12618                            sb.append(proc.initialIdlePss);
12619                            sb.append(", period=");
12620                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12621                            sb.append(", lowRamPeriod=");
12622                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12623                            Slog.wtfQuiet(TAG, sb.toString());
12624                            proc.kill("idle maint (pss " + proc.lastPss
12625                                    + " from " + proc.initialIdlePss + ")", true);
12626                        }
12627                    }
12628                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12629                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12630                    proc.notCachedSinceIdle = true;
12631                    proc.initialIdlePss = 0;
12632                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12633                            mTestPssMode, isSleeping(), now);
12634                }
12635            }
12636
12637            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12638            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12639        }
12640    }
12641
12642    private void retrieveSettings() {
12643        final ContentResolver resolver = mContext.getContentResolver();
12644        final boolean freeformWindowManagement =
12645                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12646                        || Settings.Global.getInt(
12647                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12648        final boolean supportsPictureInPicture =
12649                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12650
12651        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12652        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12653        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12654        final boolean alwaysFinishActivities =
12655                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12656        final boolean lenientBackgroundCheck =
12657                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12658        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12659        final boolean forceResizable = Settings.Global.getInt(
12660                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12661        // Transfer any global setting for forcing RTL layout, into a System Property
12662        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12663
12664        final Configuration configuration = new Configuration();
12665        Settings.System.getConfiguration(resolver, configuration);
12666        if (forceRtl) {
12667            // This will take care of setting the correct layout direction flags
12668            configuration.setLayoutDirection(configuration.locale);
12669        }
12670
12671        synchronized (this) {
12672            mDebugApp = mOrigDebugApp = debugApp;
12673            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12674            mAlwaysFinishActivities = alwaysFinishActivities;
12675            mLenientBackgroundCheck = lenientBackgroundCheck;
12676            mForceResizableActivities = forceResizable;
12677            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12678            if (supportsMultiWindow || forceResizable) {
12679                mSupportsMultiWindow = true;
12680                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12681                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12682            } else {
12683                mSupportsMultiWindow = false;
12684                mSupportsFreeformWindowManagement = false;
12685                mSupportsPictureInPicture = false;
12686            }
12687            // This happens before any activities are started, so we can
12688            // change mConfiguration in-place.
12689            updateConfigurationLocked(configuration, null, true);
12690            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12691                    "Initial config: " + mConfiguration);
12692
12693            // Load resources only after the current configuration has been set.
12694            final Resources res = mContext.getResources();
12695            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12696            mThumbnailWidth = res.getDimensionPixelSize(
12697                    com.android.internal.R.dimen.thumbnail_width);
12698            mThumbnailHeight = res.getDimensionPixelSize(
12699                    com.android.internal.R.dimen.thumbnail_height);
12700            mFullscreenThumbnailScale = res.getFraction(
12701                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12702            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12703                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12704            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12705                    com.android.internal.R.string.config_appsNotReportingCrashes));
12706        }
12707    }
12708
12709    public boolean testIsSystemReady() {
12710        // no need to synchronize(this) just to read & return the value
12711        return mSystemReady;
12712    }
12713
12714    public void systemReady(final Runnable goingCallback) {
12715        synchronized(this) {
12716            if (mSystemReady) {
12717                // If we're done calling all the receivers, run the next "boot phase" passed in
12718                // by the SystemServer
12719                if (goingCallback != null) {
12720                    goingCallback.run();
12721                }
12722                return;
12723            }
12724
12725            mLocalDeviceIdleController
12726                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12727
12728            // Make sure we have the current profile info, since it is needed for security checks.
12729            mUserController.onSystemReady();
12730            mRecentTasks.onSystemReadyLocked();
12731            mAppOpsService.systemReady();
12732            mSystemReady = true;
12733        }
12734
12735        ArrayList<ProcessRecord> procsToKill = null;
12736        synchronized(mPidsSelfLocked) {
12737            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12738                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12739                if (!isAllowedWhileBooting(proc.info)){
12740                    if (procsToKill == null) {
12741                        procsToKill = new ArrayList<ProcessRecord>();
12742                    }
12743                    procsToKill.add(proc);
12744                }
12745            }
12746        }
12747
12748        synchronized(this) {
12749            if (procsToKill != null) {
12750                for (int i=procsToKill.size()-1; i>=0; i--) {
12751                    ProcessRecord proc = procsToKill.get(i);
12752                    Slog.i(TAG, "Removing system update proc: " + proc);
12753                    removeProcessLocked(proc, true, false, "system update done");
12754                }
12755            }
12756
12757            // Now that we have cleaned up any update processes, we
12758            // are ready to start launching real processes and know that
12759            // we won't trample on them any more.
12760            mProcessesReady = true;
12761        }
12762
12763        Slog.i(TAG, "System now ready");
12764        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12765            SystemClock.uptimeMillis());
12766
12767        synchronized(this) {
12768            // Make sure we have no pre-ready processes sitting around.
12769
12770            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12771                ResolveInfo ri = mContext.getPackageManager()
12772                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12773                                STOCK_PM_FLAGS);
12774                CharSequence errorMsg = null;
12775                if (ri != null) {
12776                    ActivityInfo ai = ri.activityInfo;
12777                    ApplicationInfo app = ai.applicationInfo;
12778                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12779                        mTopAction = Intent.ACTION_FACTORY_TEST;
12780                        mTopData = null;
12781                        mTopComponent = new ComponentName(app.packageName,
12782                                ai.name);
12783                    } else {
12784                        errorMsg = mContext.getResources().getText(
12785                                com.android.internal.R.string.factorytest_not_system);
12786                    }
12787                } else {
12788                    errorMsg = mContext.getResources().getText(
12789                            com.android.internal.R.string.factorytest_no_action);
12790                }
12791                if (errorMsg != null) {
12792                    mTopAction = null;
12793                    mTopData = null;
12794                    mTopComponent = null;
12795                    Message msg = Message.obtain();
12796                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12797                    msg.getData().putCharSequence("msg", errorMsg);
12798                    mUiHandler.sendMessage(msg);
12799                }
12800            }
12801        }
12802
12803        retrieveSettings();
12804        final int currentUserId;
12805        synchronized (this) {
12806            currentUserId = mUserController.getCurrentUserIdLocked();
12807            readGrantedUriPermissionsLocked();
12808        }
12809
12810        if (goingCallback != null) goingCallback.run();
12811
12812        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12813                Integer.toString(currentUserId), currentUserId);
12814        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12815                Integer.toString(currentUserId), currentUserId);
12816        mSystemServiceManager.startUser(currentUserId);
12817
12818        synchronized (this) {
12819            // Only start up encryption-aware persistent apps; once user is
12820            // unlocked we'll come back around and start unaware apps
12821            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12822
12823            // Start up initial activity.
12824            mBooting = true;
12825            // Enable home activity for system user, so that the system can always boot
12826            if (UserManager.isSplitSystemUser()) {
12827                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12828                try {
12829                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12830                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12831                            UserHandle.USER_SYSTEM);
12832                } catch (RemoteException e) {
12833                    throw e.rethrowAsRuntimeException();
12834                }
12835            }
12836            startHomeActivityLocked(currentUserId, "systemReady");
12837
12838            try {
12839                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12840                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12841                            + " data partition or your device will be unstable.");
12842                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12843                }
12844            } catch (RemoteException e) {
12845            }
12846
12847            if (!Build.isBuildConsistent()) {
12848                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12849                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12850            }
12851
12852            long ident = Binder.clearCallingIdentity();
12853            try {
12854                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12855                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12856                        | Intent.FLAG_RECEIVER_FOREGROUND);
12857                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12858                broadcastIntentLocked(null, null, intent,
12859                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12860                        null, false, false, MY_PID, Process.SYSTEM_UID,
12861                        currentUserId);
12862                intent = new Intent(Intent.ACTION_USER_STARTING);
12863                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12864                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12865                broadcastIntentLocked(null, null, intent,
12866                        null, new IIntentReceiver.Stub() {
12867                            @Override
12868                            public void performReceive(Intent intent, int resultCode, String data,
12869                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12870                                    throws RemoteException {
12871                            }
12872                        }, 0, null, null,
12873                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12874                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12875            } catch (Throwable t) {
12876                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12877            } finally {
12878                Binder.restoreCallingIdentity(ident);
12879            }
12880            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12881            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12882        }
12883    }
12884
12885    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12886        synchronized (this) {
12887            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12888        }
12889    }
12890
12891    void skipCurrentReceiverLocked(ProcessRecord app) {
12892        for (BroadcastQueue queue : mBroadcastQueues) {
12893            queue.skipCurrentReceiverLocked(app);
12894        }
12895    }
12896
12897    /**
12898     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12899     * The application process will exit immediately after this call returns.
12900     * @param app object of the crashing app, null for the system server
12901     * @param crashInfo describing the exception
12902     */
12903    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12904        ProcessRecord r = findAppProcess(app, "Crash");
12905        final String processName = app == null ? "system_server"
12906                : (r == null ? "unknown" : r.processName);
12907
12908        handleApplicationCrashInner("crash", r, processName, crashInfo);
12909    }
12910
12911    /* Native crash reporting uses this inner version because it needs to be somewhat
12912     * decoupled from the AM-managed cleanup lifecycle
12913     */
12914    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12915            ApplicationErrorReport.CrashInfo crashInfo) {
12916        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12917                UserHandle.getUserId(Binder.getCallingUid()), processName,
12918                r == null ? -1 : r.info.flags,
12919                crashInfo.exceptionClassName,
12920                crashInfo.exceptionMessage,
12921                crashInfo.throwFileName,
12922                crashInfo.throwLineNumber);
12923
12924        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12925
12926        mAppErrors.crashApplication(r, crashInfo);
12927    }
12928
12929    public void handleApplicationStrictModeViolation(
12930            IBinder app,
12931            int violationMask,
12932            StrictMode.ViolationInfo info) {
12933        ProcessRecord r = findAppProcess(app, "StrictMode");
12934        if (r == null) {
12935            return;
12936        }
12937
12938        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12939            Integer stackFingerprint = info.hashCode();
12940            boolean logIt = true;
12941            synchronized (mAlreadyLoggedViolatedStacks) {
12942                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12943                    logIt = false;
12944                    // TODO: sub-sample into EventLog for these, with
12945                    // the info.durationMillis?  Then we'd get
12946                    // the relative pain numbers, without logging all
12947                    // the stack traces repeatedly.  We'd want to do
12948                    // likewise in the client code, which also does
12949                    // dup suppression, before the Binder call.
12950                } else {
12951                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12952                        mAlreadyLoggedViolatedStacks.clear();
12953                    }
12954                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12955                }
12956            }
12957            if (logIt) {
12958                logStrictModeViolationToDropBox(r, info);
12959            }
12960        }
12961
12962        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12963            AppErrorResult result = new AppErrorResult();
12964            synchronized (this) {
12965                final long origId = Binder.clearCallingIdentity();
12966
12967                Message msg = Message.obtain();
12968                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12969                HashMap<String, Object> data = new HashMap<String, Object>();
12970                data.put("result", result);
12971                data.put("app", r);
12972                data.put("violationMask", violationMask);
12973                data.put("info", info);
12974                msg.obj = data;
12975                mUiHandler.sendMessage(msg);
12976
12977                Binder.restoreCallingIdentity(origId);
12978            }
12979            int res = result.get();
12980            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12981        }
12982    }
12983
12984    // Depending on the policy in effect, there could be a bunch of
12985    // these in quick succession so we try to batch these together to
12986    // minimize disk writes, number of dropbox entries, and maximize
12987    // compression, by having more fewer, larger records.
12988    private void logStrictModeViolationToDropBox(
12989            ProcessRecord process,
12990            StrictMode.ViolationInfo info) {
12991        if (info == null) {
12992            return;
12993        }
12994        final boolean isSystemApp = process == null ||
12995                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12996                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12997        final String processName = process == null ? "unknown" : process.processName;
12998        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12999        final DropBoxManager dbox = (DropBoxManager)
13000                mContext.getSystemService(Context.DROPBOX_SERVICE);
13001
13002        // Exit early if the dropbox isn't configured to accept this report type.
13003        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13004
13005        boolean bufferWasEmpty;
13006        boolean needsFlush;
13007        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13008        synchronized (sb) {
13009            bufferWasEmpty = sb.length() == 0;
13010            appendDropBoxProcessHeaders(process, processName, sb);
13011            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13012            sb.append("System-App: ").append(isSystemApp).append("\n");
13013            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13014            if (info.violationNumThisLoop != 0) {
13015                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13016            }
13017            if (info.numAnimationsRunning != 0) {
13018                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13019            }
13020            if (info.broadcastIntentAction != null) {
13021                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13022            }
13023            if (info.durationMillis != -1) {
13024                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13025            }
13026            if (info.numInstances != -1) {
13027                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13028            }
13029            if (info.tags != null) {
13030                for (String tag : info.tags) {
13031                    sb.append("Span-Tag: ").append(tag).append("\n");
13032                }
13033            }
13034            sb.append("\n");
13035            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13036                sb.append(info.crashInfo.stackTrace);
13037                sb.append("\n");
13038            }
13039            if (info.message != null) {
13040                sb.append(info.message);
13041                sb.append("\n");
13042            }
13043
13044            // Only buffer up to ~64k.  Various logging bits truncate
13045            // things at 128k.
13046            needsFlush = (sb.length() > 64 * 1024);
13047        }
13048
13049        // Flush immediately if the buffer's grown too large, or this
13050        // is a non-system app.  Non-system apps are isolated with a
13051        // different tag & policy and not batched.
13052        //
13053        // Batching is useful during internal testing with
13054        // StrictMode settings turned up high.  Without batching,
13055        // thousands of separate files could be created on boot.
13056        if (!isSystemApp || needsFlush) {
13057            new Thread("Error dump: " + dropboxTag) {
13058                @Override
13059                public void run() {
13060                    String report;
13061                    synchronized (sb) {
13062                        report = sb.toString();
13063                        sb.delete(0, sb.length());
13064                        sb.trimToSize();
13065                    }
13066                    if (report.length() != 0) {
13067                        dbox.addText(dropboxTag, report);
13068                    }
13069                }
13070            }.start();
13071            return;
13072        }
13073
13074        // System app batching:
13075        if (!bufferWasEmpty) {
13076            // An existing dropbox-writing thread is outstanding, so
13077            // we don't need to start it up.  The existing thread will
13078            // catch the buffer appends we just did.
13079            return;
13080        }
13081
13082        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13083        // (After this point, we shouldn't access AMS internal data structures.)
13084        new Thread("Error dump: " + dropboxTag) {
13085            @Override
13086            public void run() {
13087                // 5 second sleep to let stacks arrive and be batched together
13088                try {
13089                    Thread.sleep(5000);  // 5 seconds
13090                } catch (InterruptedException e) {}
13091
13092                String errorReport;
13093                synchronized (mStrictModeBuffer) {
13094                    errorReport = mStrictModeBuffer.toString();
13095                    if (errorReport.length() == 0) {
13096                        return;
13097                    }
13098                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13099                    mStrictModeBuffer.trimToSize();
13100                }
13101                dbox.addText(dropboxTag, errorReport);
13102            }
13103        }.start();
13104    }
13105
13106    /**
13107     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13108     * @param app object of the crashing app, null for the system server
13109     * @param tag reported by the caller
13110     * @param system whether this wtf is coming from the system
13111     * @param crashInfo describing the context of the error
13112     * @return true if the process should exit immediately (WTF is fatal)
13113     */
13114    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13115            final ApplicationErrorReport.CrashInfo crashInfo) {
13116        final int callingUid = Binder.getCallingUid();
13117        final int callingPid = Binder.getCallingPid();
13118
13119        if (system) {
13120            // If this is coming from the system, we could very well have low-level
13121            // system locks held, so we want to do this all asynchronously.  And we
13122            // never want this to become fatal, so there is that too.
13123            mHandler.post(new Runnable() {
13124                @Override public void run() {
13125                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13126                }
13127            });
13128            return false;
13129        }
13130
13131        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13132                crashInfo);
13133
13134        if (r != null && r.pid != Process.myPid() &&
13135                Settings.Global.getInt(mContext.getContentResolver(),
13136                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13137            mAppErrors.crashApplication(r, crashInfo);
13138            return true;
13139        } else {
13140            return false;
13141        }
13142    }
13143
13144    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13145            final ApplicationErrorReport.CrashInfo crashInfo) {
13146        final ProcessRecord r = findAppProcess(app, "WTF");
13147        final String processName = app == null ? "system_server"
13148                : (r == null ? "unknown" : r.processName);
13149
13150        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13151                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13152
13153        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13154
13155        return r;
13156    }
13157
13158    /**
13159     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13160     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13161     */
13162    private ProcessRecord findAppProcess(IBinder app, String reason) {
13163        if (app == null) {
13164            return null;
13165        }
13166
13167        synchronized (this) {
13168            final int NP = mProcessNames.getMap().size();
13169            for (int ip=0; ip<NP; ip++) {
13170                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13171                final int NA = apps.size();
13172                for (int ia=0; ia<NA; ia++) {
13173                    ProcessRecord p = apps.valueAt(ia);
13174                    if (p.thread != null && p.thread.asBinder() == app) {
13175                        return p;
13176                    }
13177                }
13178            }
13179
13180            Slog.w(TAG, "Can't find mystery application for " + reason
13181                    + " from pid=" + Binder.getCallingPid()
13182                    + " uid=" + Binder.getCallingUid() + ": " + app);
13183            return null;
13184        }
13185    }
13186
13187    /**
13188     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13189     * to append various headers to the dropbox log text.
13190     */
13191    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13192            StringBuilder sb) {
13193        // Watchdog thread ends up invoking this function (with
13194        // a null ProcessRecord) to add the stack file to dropbox.
13195        // Do not acquire a lock on this (am) in such cases, as it
13196        // could cause a potential deadlock, if and when watchdog
13197        // is invoked due to unavailability of lock on am and it
13198        // would prevent watchdog from killing system_server.
13199        if (process == null) {
13200            sb.append("Process: ").append(processName).append("\n");
13201            return;
13202        }
13203        // Note: ProcessRecord 'process' is guarded by the service
13204        // instance.  (notably process.pkgList, which could otherwise change
13205        // concurrently during execution of this method)
13206        synchronized (this) {
13207            sb.append("Process: ").append(processName).append("\n");
13208            int flags = process.info.flags;
13209            IPackageManager pm = AppGlobals.getPackageManager();
13210            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13211            for (int ip=0; ip<process.pkgList.size(); ip++) {
13212                String pkg = process.pkgList.keyAt(ip);
13213                sb.append("Package: ").append(pkg);
13214                try {
13215                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13216                    if (pi != null) {
13217                        sb.append(" v").append(pi.versionCode);
13218                        if (pi.versionName != null) {
13219                            sb.append(" (").append(pi.versionName).append(")");
13220                        }
13221                    }
13222                } catch (RemoteException e) {
13223                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13224                }
13225                sb.append("\n");
13226            }
13227        }
13228    }
13229
13230    private static String processClass(ProcessRecord process) {
13231        if (process == null || process.pid == MY_PID) {
13232            return "system_server";
13233        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13234            return "system_app";
13235        } else {
13236            return "data_app";
13237        }
13238    }
13239
13240    private volatile long mWtfClusterStart;
13241    private volatile int mWtfClusterCount;
13242
13243    /**
13244     * Write a description of an error (crash, WTF, ANR) to the drop box.
13245     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13246     * @param process which caused the error, null means the system server
13247     * @param activity which triggered the error, null if unknown
13248     * @param parent activity related to the error, null if unknown
13249     * @param subject line related to the error, null if absent
13250     * @param report in long form describing the error, null if absent
13251     * @param logFile to include in the report, null if none
13252     * @param crashInfo giving an application stack trace, null if absent
13253     */
13254    public void addErrorToDropBox(String eventType,
13255            ProcessRecord process, String processName, ActivityRecord activity,
13256            ActivityRecord parent, String subject,
13257            final String report, final File logFile,
13258            final ApplicationErrorReport.CrashInfo crashInfo) {
13259        // NOTE -- this must never acquire the ActivityManagerService lock,
13260        // otherwise the watchdog may be prevented from resetting the system.
13261
13262        final String dropboxTag = processClass(process) + "_" + eventType;
13263        final DropBoxManager dbox = (DropBoxManager)
13264                mContext.getSystemService(Context.DROPBOX_SERVICE);
13265
13266        // Exit early if the dropbox isn't configured to accept this report type.
13267        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13268
13269        // Rate-limit how often we're willing to do the heavy lifting below to
13270        // collect and record logs; currently 5 logs per 10 second period.
13271        final long now = SystemClock.elapsedRealtime();
13272        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13273            mWtfClusterStart = now;
13274            mWtfClusterCount = 1;
13275        } else {
13276            if (mWtfClusterCount++ >= 5) return;
13277        }
13278
13279        final StringBuilder sb = new StringBuilder(1024);
13280        appendDropBoxProcessHeaders(process, processName, sb);
13281        if (process != null) {
13282            sb.append("Foreground: ")
13283                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13284                    .append("\n");
13285        }
13286        if (activity != null) {
13287            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13288        }
13289        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13290            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13291        }
13292        if (parent != null && parent != activity) {
13293            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13294        }
13295        if (subject != null) {
13296            sb.append("Subject: ").append(subject).append("\n");
13297        }
13298        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13299        if (Debug.isDebuggerConnected()) {
13300            sb.append("Debugger: Connected\n");
13301        }
13302        sb.append("\n");
13303
13304        // Do the rest in a worker thread to avoid blocking the caller on I/O
13305        // (After this point, we shouldn't access AMS internal data structures.)
13306        Thread worker = new Thread("Error dump: " + dropboxTag) {
13307            @Override
13308            public void run() {
13309                if (report != null) {
13310                    sb.append(report);
13311                }
13312                if (logFile != null) {
13313                    try {
13314                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13315                                    "\n\n[[TRUNCATED]]"));
13316                    } catch (IOException e) {
13317                        Slog.e(TAG, "Error reading " + logFile, e);
13318                    }
13319                }
13320                if (crashInfo != null && crashInfo.stackTrace != null) {
13321                    sb.append(crashInfo.stackTrace);
13322                }
13323
13324                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13325                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13326                if (lines > 0) {
13327                    sb.append("\n");
13328
13329                    // Merge several logcat streams, and take the last N lines
13330                    InputStreamReader input = null;
13331                    try {
13332                        java.lang.Process logcat = new ProcessBuilder(
13333                                "/system/bin/timeout", "-k", "15s", "10s",
13334                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13335                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13336                                        .redirectErrorStream(true).start();
13337
13338                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13339                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13340                        input = new InputStreamReader(logcat.getInputStream());
13341
13342                        int num;
13343                        char[] buf = new char[8192];
13344                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13345                    } catch (IOException e) {
13346                        Slog.e(TAG, "Error running logcat", e);
13347                    } finally {
13348                        if (input != null) try { input.close(); } catch (IOException e) {}
13349                    }
13350                }
13351
13352                dbox.addText(dropboxTag, sb.toString());
13353            }
13354        };
13355
13356        if (process == null) {
13357            // If process is null, we are being called from some internal code
13358            // and may be about to die -- run this synchronously.
13359            worker.run();
13360        } else {
13361            worker.start();
13362        }
13363    }
13364
13365    @Override
13366    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13367        enforceNotIsolatedCaller("getProcessesInErrorState");
13368        // assume our apps are happy - lazy create the list
13369        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13370
13371        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13372                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13373        int userId = UserHandle.getUserId(Binder.getCallingUid());
13374
13375        synchronized (this) {
13376
13377            // iterate across all processes
13378            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13379                ProcessRecord app = mLruProcesses.get(i);
13380                if (!allUsers && app.userId != userId) {
13381                    continue;
13382                }
13383                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13384                    // This one's in trouble, so we'll generate a report for it
13385                    // crashes are higher priority (in case there's a crash *and* an anr)
13386                    ActivityManager.ProcessErrorStateInfo report = null;
13387                    if (app.crashing) {
13388                        report = app.crashingReport;
13389                    } else if (app.notResponding) {
13390                        report = app.notRespondingReport;
13391                    }
13392
13393                    if (report != null) {
13394                        if (errList == null) {
13395                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13396                        }
13397                        errList.add(report);
13398                    } else {
13399                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13400                                " crashing = " + app.crashing +
13401                                " notResponding = " + app.notResponding);
13402                    }
13403                }
13404            }
13405        }
13406
13407        return errList;
13408    }
13409
13410    static int procStateToImportance(int procState, int memAdj,
13411            ActivityManager.RunningAppProcessInfo currApp) {
13412        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13413        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13414            currApp.lru = memAdj;
13415        } else {
13416            currApp.lru = 0;
13417        }
13418        return imp;
13419    }
13420
13421    private void fillInProcMemInfo(ProcessRecord app,
13422            ActivityManager.RunningAppProcessInfo outInfo) {
13423        outInfo.pid = app.pid;
13424        outInfo.uid = app.info.uid;
13425        if (mHeavyWeightProcess == app) {
13426            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13427        }
13428        if (app.persistent) {
13429            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13430        }
13431        if (app.activities.size() > 0) {
13432            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13433        }
13434        outInfo.lastTrimLevel = app.trimMemoryLevel;
13435        int adj = app.curAdj;
13436        int procState = app.curProcState;
13437        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13438        outInfo.importanceReasonCode = app.adjTypeCode;
13439        outInfo.processState = app.curProcState;
13440    }
13441
13442    @Override
13443    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13444        enforceNotIsolatedCaller("getRunningAppProcesses");
13445
13446        final int callingUid = Binder.getCallingUid();
13447
13448        // Lazy instantiation of list
13449        List<ActivityManager.RunningAppProcessInfo> runList = null;
13450        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13451                callingUid) == PackageManager.PERMISSION_GRANTED;
13452        final int userId = UserHandle.getUserId(callingUid);
13453        final boolean allUids = isGetTasksAllowed(
13454                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13455
13456        synchronized (this) {
13457            // Iterate across all processes
13458            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13459                ProcessRecord app = mLruProcesses.get(i);
13460                if ((!allUsers && app.userId != userId)
13461                        || (!allUids && app.uid != callingUid)) {
13462                    continue;
13463                }
13464                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13465                    // Generate process state info for running application
13466                    ActivityManager.RunningAppProcessInfo currApp =
13467                        new ActivityManager.RunningAppProcessInfo(app.processName,
13468                                app.pid, app.getPackageList());
13469                    fillInProcMemInfo(app, currApp);
13470                    if (app.adjSource instanceof ProcessRecord) {
13471                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13472                        currApp.importanceReasonImportance =
13473                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13474                                        app.adjSourceProcState);
13475                    } else if (app.adjSource instanceof ActivityRecord) {
13476                        ActivityRecord r = (ActivityRecord)app.adjSource;
13477                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13478                    }
13479                    if (app.adjTarget instanceof ComponentName) {
13480                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13481                    }
13482                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13483                    //        + " lru=" + currApp.lru);
13484                    if (runList == null) {
13485                        runList = new ArrayList<>();
13486                    }
13487                    runList.add(currApp);
13488                }
13489            }
13490        }
13491        return runList;
13492    }
13493
13494    @Override
13495    public List<ApplicationInfo> getRunningExternalApplications() {
13496        enforceNotIsolatedCaller("getRunningExternalApplications");
13497        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13498        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13499        if (runningApps != null && runningApps.size() > 0) {
13500            Set<String> extList = new HashSet<String>();
13501            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13502                if (app.pkgList != null) {
13503                    for (String pkg : app.pkgList) {
13504                        extList.add(pkg);
13505                    }
13506                }
13507            }
13508            IPackageManager pm = AppGlobals.getPackageManager();
13509            for (String pkg : extList) {
13510                try {
13511                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13512                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13513                        retList.add(info);
13514                    }
13515                } catch (RemoteException e) {
13516                }
13517            }
13518        }
13519        return retList;
13520    }
13521
13522    @Override
13523    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13524        enforceNotIsolatedCaller("getMyMemoryState");
13525        synchronized (this) {
13526            ProcessRecord proc;
13527            synchronized (mPidsSelfLocked) {
13528                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13529            }
13530            fillInProcMemInfo(proc, outInfo);
13531        }
13532    }
13533
13534    @Override
13535    public int getMemoryTrimLevel() {
13536        enforceNotIsolatedCaller("getMyMemoryState");
13537        synchronized (this) {
13538            return mLastMemoryLevel;
13539        }
13540    }
13541
13542    @Override
13543    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13544            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13545        (new ActivityManagerShellCommand(this, false)).exec(
13546                this, in, out, err, args, resultReceiver);
13547    }
13548
13549    @Override
13550    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13551        if (checkCallingPermission(android.Manifest.permission.DUMP)
13552                != PackageManager.PERMISSION_GRANTED) {
13553            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13554                    + Binder.getCallingPid()
13555                    + ", uid=" + Binder.getCallingUid()
13556                    + " without permission "
13557                    + android.Manifest.permission.DUMP);
13558            return;
13559        }
13560
13561        boolean dumpAll = false;
13562        boolean dumpClient = false;
13563        String dumpPackage = null;
13564
13565        int opti = 0;
13566        while (opti < args.length) {
13567            String opt = args[opti];
13568            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13569                break;
13570            }
13571            opti++;
13572            if ("-a".equals(opt)) {
13573                dumpAll = true;
13574            } else if ("-c".equals(opt)) {
13575                dumpClient = true;
13576            } else if ("-p".equals(opt)) {
13577                if (opti < args.length) {
13578                    dumpPackage = args[opti];
13579                    opti++;
13580                } else {
13581                    pw.println("Error: -p option requires package argument");
13582                    return;
13583                }
13584                dumpClient = true;
13585            } else if ("-h".equals(opt)) {
13586                ActivityManagerShellCommand.dumpHelp(pw, true);
13587                return;
13588            } else {
13589                pw.println("Unknown argument: " + opt + "; use -h for help");
13590            }
13591        }
13592
13593        long origId = Binder.clearCallingIdentity();
13594        boolean more = false;
13595        // Is the caller requesting to dump a particular piece of data?
13596        if (opti < args.length) {
13597            String cmd = args[opti];
13598            opti++;
13599            if ("activities".equals(cmd) || "a".equals(cmd)) {
13600                synchronized (this) {
13601                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13602                }
13603            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13604                synchronized (this) {
13605                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13606                }
13607            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13608                String[] newArgs;
13609                String name;
13610                if (opti >= args.length) {
13611                    name = null;
13612                    newArgs = EMPTY_STRING_ARRAY;
13613                } else {
13614                    dumpPackage = args[opti];
13615                    opti++;
13616                    newArgs = new String[args.length - opti];
13617                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13618                            args.length - opti);
13619                }
13620                synchronized (this) {
13621                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13622                }
13623            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13624                String[] newArgs;
13625                String name;
13626                if (opti >= args.length) {
13627                    name = null;
13628                    newArgs = EMPTY_STRING_ARRAY;
13629                } else {
13630                    dumpPackage = args[opti];
13631                    opti++;
13632                    newArgs = new String[args.length - opti];
13633                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13634                            args.length - opti);
13635                }
13636                synchronized (this) {
13637                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13638                }
13639            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13640                String[] newArgs;
13641                String name;
13642                if (opti >= args.length) {
13643                    name = null;
13644                    newArgs = EMPTY_STRING_ARRAY;
13645                } else {
13646                    dumpPackage = args[opti];
13647                    opti++;
13648                    newArgs = new String[args.length - opti];
13649                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13650                            args.length - opti);
13651                }
13652                synchronized (this) {
13653                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13654                }
13655            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13656                synchronized (this) {
13657                    dumpOomLocked(fd, pw, args, opti, true);
13658                }
13659            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13660                synchronized (this) {
13661                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13662                }
13663            } else if ("provider".equals(cmd)) {
13664                String[] newArgs;
13665                String name;
13666                if (opti >= args.length) {
13667                    name = null;
13668                    newArgs = EMPTY_STRING_ARRAY;
13669                } else {
13670                    name = args[opti];
13671                    opti++;
13672                    newArgs = new String[args.length - opti];
13673                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13674                }
13675                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13676                    pw.println("No providers match: " + name);
13677                    pw.println("Use -h for help.");
13678                }
13679            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13680                synchronized (this) {
13681                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13682                }
13683            } else if ("service".equals(cmd)) {
13684                String[] newArgs;
13685                String name;
13686                if (opti >= args.length) {
13687                    name = null;
13688                    newArgs = EMPTY_STRING_ARRAY;
13689                } else {
13690                    name = args[opti];
13691                    opti++;
13692                    newArgs = new String[args.length - opti];
13693                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13694                            args.length - opti);
13695                }
13696                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13697                    pw.println("No services match: " + name);
13698                    pw.println("Use -h for help.");
13699                }
13700            } else if ("package".equals(cmd)) {
13701                String[] newArgs;
13702                if (opti >= args.length) {
13703                    pw.println("package: no package name specified");
13704                    pw.println("Use -h for help.");
13705                } else {
13706                    dumpPackage = args[opti];
13707                    opti++;
13708                    newArgs = new String[args.length - opti];
13709                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13710                            args.length - opti);
13711                    args = newArgs;
13712                    opti = 0;
13713                    more = true;
13714                }
13715            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13716                synchronized (this) {
13717                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13718                }
13719            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13720                synchronized (this) {
13721                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13722                }
13723            } else if ("locks".equals(cmd)) {
13724                LockGuard.dump(fd, pw, args);
13725            } else {
13726                // Dumping a single activity?
13727                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13728                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13729                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13730                    if (res < 0) {
13731                        pw.println("Bad activity command, or no activities match: " + cmd);
13732                        pw.println("Use -h for help.");
13733                    }
13734                }
13735            }
13736            if (!more) {
13737                Binder.restoreCallingIdentity(origId);
13738                return;
13739            }
13740        }
13741
13742        // No piece of data specified, dump everything.
13743        synchronized (this) {
13744            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13745            pw.println();
13746            if (dumpAll) {
13747                pw.println("-------------------------------------------------------------------------------");
13748            }
13749            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13750            pw.println();
13751            if (dumpAll) {
13752                pw.println("-------------------------------------------------------------------------------");
13753            }
13754            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13755            pw.println();
13756            if (dumpAll) {
13757                pw.println("-------------------------------------------------------------------------------");
13758            }
13759            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13760            pw.println();
13761            if (dumpAll) {
13762                pw.println("-------------------------------------------------------------------------------");
13763            }
13764            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13765            pw.println();
13766            if (dumpAll) {
13767                pw.println("-------------------------------------------------------------------------------");
13768            }
13769            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13770            pw.println();
13771            if (dumpAll) {
13772                pw.println("-------------------------------------------------------------------------------");
13773            }
13774            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13775            if (mAssociations.size() > 0) {
13776                pw.println();
13777                if (dumpAll) {
13778                    pw.println("-------------------------------------------------------------------------------");
13779                }
13780                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13781            }
13782            pw.println();
13783            if (dumpAll) {
13784                pw.println("-------------------------------------------------------------------------------");
13785            }
13786            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13787        }
13788        Binder.restoreCallingIdentity(origId);
13789    }
13790
13791    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13792            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13793        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13794
13795        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13796                dumpPackage);
13797        boolean needSep = printedAnything;
13798
13799        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13800                dumpPackage, needSep, "  mFocusedActivity: ");
13801        if (printed) {
13802            printedAnything = true;
13803            needSep = false;
13804        }
13805
13806        if (dumpPackage == null) {
13807            if (needSep) {
13808                pw.println();
13809            }
13810            needSep = true;
13811            printedAnything = true;
13812            mStackSupervisor.dump(pw, "  ");
13813        }
13814
13815        if (!printedAnything) {
13816            pw.println("  (nothing)");
13817        }
13818    }
13819
13820    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13821            int opti, boolean dumpAll, String dumpPackage) {
13822        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13823
13824        boolean printedAnything = false;
13825
13826        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13827            boolean printedHeader = false;
13828
13829            final int N = mRecentTasks.size();
13830            for (int i=0; i<N; i++) {
13831                TaskRecord tr = mRecentTasks.get(i);
13832                if (dumpPackage != null) {
13833                    if (tr.realActivity == null ||
13834                            !dumpPackage.equals(tr.realActivity)) {
13835                        continue;
13836                    }
13837                }
13838                if (!printedHeader) {
13839                    pw.println("  Recent tasks:");
13840                    printedHeader = true;
13841                    printedAnything = true;
13842                }
13843                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13844                        pw.println(tr);
13845                if (dumpAll) {
13846                    mRecentTasks.get(i).dump(pw, "    ");
13847                }
13848            }
13849        }
13850
13851        if (!printedAnything) {
13852            pw.println("  (nothing)");
13853        }
13854    }
13855
13856    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13857            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13858        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13859
13860        int dumpUid = 0;
13861        if (dumpPackage != null) {
13862            IPackageManager pm = AppGlobals.getPackageManager();
13863            try {
13864                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13865            } catch (RemoteException e) {
13866            }
13867        }
13868
13869        boolean printedAnything = false;
13870
13871        final long now = SystemClock.uptimeMillis();
13872
13873        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13874            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13875                    = mAssociations.valueAt(i1);
13876            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13877                SparseArray<ArrayMap<String, Association>> sourceUids
13878                        = targetComponents.valueAt(i2);
13879                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13880                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13881                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13882                        Association ass = sourceProcesses.valueAt(i4);
13883                        if (dumpPackage != null) {
13884                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13885                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13886                                continue;
13887                            }
13888                        }
13889                        printedAnything = true;
13890                        pw.print("  ");
13891                        pw.print(ass.mTargetProcess);
13892                        pw.print("/");
13893                        UserHandle.formatUid(pw, ass.mTargetUid);
13894                        pw.print(" <- ");
13895                        pw.print(ass.mSourceProcess);
13896                        pw.print("/");
13897                        UserHandle.formatUid(pw, ass.mSourceUid);
13898                        pw.println();
13899                        pw.print("    via ");
13900                        pw.print(ass.mTargetComponent.flattenToShortString());
13901                        pw.println();
13902                        pw.print("    ");
13903                        long dur = ass.mTime;
13904                        if (ass.mNesting > 0) {
13905                            dur += now - ass.mStartTime;
13906                        }
13907                        TimeUtils.formatDuration(dur, pw);
13908                        pw.print(" (");
13909                        pw.print(ass.mCount);
13910                        pw.print(" times)");
13911                        pw.print("  ");
13912                        for (int i=0; i<ass.mStateTimes.length; i++) {
13913                            long amt = ass.mStateTimes[i];
13914                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13915                                amt += now - ass.mLastStateUptime;
13916                            }
13917                            if (amt != 0) {
13918                                pw.print(" ");
13919                                pw.print(ProcessList.makeProcStateString(
13920                                            i + ActivityManager.MIN_PROCESS_STATE));
13921                                pw.print("=");
13922                                TimeUtils.formatDuration(amt, pw);
13923                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13924                                    pw.print("*");
13925                                }
13926                            }
13927                        }
13928                        pw.println();
13929                        if (ass.mNesting > 0) {
13930                            pw.print("    Currently active: ");
13931                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13932                            pw.println();
13933                        }
13934                    }
13935                }
13936            }
13937
13938        }
13939
13940        if (!printedAnything) {
13941            pw.println("  (nothing)");
13942        }
13943    }
13944
13945    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13946            String header, boolean needSep) {
13947        boolean printed = false;
13948        int whichAppId = -1;
13949        if (dumpPackage != null) {
13950            try {
13951                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13952                        dumpPackage, 0);
13953                whichAppId = UserHandle.getAppId(info.uid);
13954            } catch (NameNotFoundException e) {
13955                e.printStackTrace();
13956            }
13957        }
13958        for (int i=0; i<uids.size(); i++) {
13959            UidRecord uidRec = uids.valueAt(i);
13960            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13961                continue;
13962            }
13963            if (!printed) {
13964                printed = true;
13965                if (needSep) {
13966                    pw.println();
13967                }
13968                pw.print("  ");
13969                pw.println(header);
13970                needSep = true;
13971            }
13972            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13973            pw.print(": "); pw.println(uidRec);
13974        }
13975        return printed;
13976    }
13977
13978    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13979            int opti, boolean dumpAll, String dumpPackage) {
13980        boolean needSep = false;
13981        boolean printedAnything = false;
13982        int numPers = 0;
13983
13984        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13985
13986        if (dumpAll) {
13987            final int NP = mProcessNames.getMap().size();
13988            for (int ip=0; ip<NP; ip++) {
13989                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13990                final int NA = procs.size();
13991                for (int ia=0; ia<NA; ia++) {
13992                    ProcessRecord r = procs.valueAt(ia);
13993                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13994                        continue;
13995                    }
13996                    if (!needSep) {
13997                        pw.println("  All known processes:");
13998                        needSep = true;
13999                        printedAnything = true;
14000                    }
14001                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14002                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14003                        pw.print(" "); pw.println(r);
14004                    r.dump(pw, "    ");
14005                    if (r.persistent) {
14006                        numPers++;
14007                    }
14008                }
14009            }
14010        }
14011
14012        if (mIsolatedProcesses.size() > 0) {
14013            boolean printed = false;
14014            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14015                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14016                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14017                    continue;
14018                }
14019                if (!printed) {
14020                    if (needSep) {
14021                        pw.println();
14022                    }
14023                    pw.println("  Isolated process list (sorted by uid):");
14024                    printedAnything = true;
14025                    printed = true;
14026                    needSep = true;
14027                }
14028                pw.println(String.format("%sIsolated #%2d: %s",
14029                        "    ", i, r.toString()));
14030            }
14031        }
14032
14033        if (mActiveUids.size() > 0) {
14034            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14035                printedAnything = needSep = true;
14036            }
14037        }
14038        if (mValidateUids.size() > 0) {
14039            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14040                printedAnything = needSep = true;
14041            }
14042        }
14043
14044        if (mLruProcesses.size() > 0) {
14045            if (needSep) {
14046                pw.println();
14047            }
14048            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14049                    pw.print(" total, non-act at ");
14050                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14051                    pw.print(", non-svc at ");
14052                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14053                    pw.println("):");
14054            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14055            needSep = true;
14056            printedAnything = true;
14057        }
14058
14059        if (dumpAll || dumpPackage != null) {
14060            synchronized (mPidsSelfLocked) {
14061                boolean printed = false;
14062                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14063                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14064                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14065                        continue;
14066                    }
14067                    if (!printed) {
14068                        if (needSep) pw.println();
14069                        needSep = true;
14070                        pw.println("  PID mappings:");
14071                        printed = true;
14072                        printedAnything = true;
14073                    }
14074                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14075                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14076                }
14077            }
14078        }
14079
14080        if (mForegroundProcesses.size() > 0) {
14081            synchronized (mPidsSelfLocked) {
14082                boolean printed = false;
14083                for (int i=0; i<mForegroundProcesses.size(); i++) {
14084                    ProcessRecord r = mPidsSelfLocked.get(
14085                            mForegroundProcesses.valueAt(i).pid);
14086                    if (dumpPackage != null && (r == null
14087                            || !r.pkgList.containsKey(dumpPackage))) {
14088                        continue;
14089                    }
14090                    if (!printed) {
14091                        if (needSep) pw.println();
14092                        needSep = true;
14093                        pw.println("  Foreground Processes:");
14094                        printed = true;
14095                        printedAnything = true;
14096                    }
14097                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14098                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14099                }
14100            }
14101        }
14102
14103        if (mPersistentStartingProcesses.size() > 0) {
14104            if (needSep) pw.println();
14105            needSep = true;
14106            printedAnything = true;
14107            pw.println("  Persisent processes that are starting:");
14108            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14109                    "Starting Norm", "Restarting PERS", dumpPackage);
14110        }
14111
14112        if (mRemovedProcesses.size() > 0) {
14113            if (needSep) pw.println();
14114            needSep = true;
14115            printedAnything = true;
14116            pw.println("  Processes that are being removed:");
14117            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14118                    "Removed Norm", "Removed PERS", dumpPackage);
14119        }
14120
14121        if (mProcessesOnHold.size() > 0) {
14122            if (needSep) pw.println();
14123            needSep = true;
14124            printedAnything = true;
14125            pw.println("  Processes that are on old until the system is ready:");
14126            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14127                    "OnHold Norm", "OnHold PERS", dumpPackage);
14128        }
14129
14130        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14131
14132        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14133        if (needSep) {
14134            printedAnything = true;
14135        }
14136
14137        if (dumpPackage == null) {
14138            pw.println();
14139            needSep = false;
14140            mUserController.dump(pw, dumpAll);
14141        }
14142        if (mHomeProcess != null && (dumpPackage == null
14143                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14144            if (needSep) {
14145                pw.println();
14146                needSep = false;
14147            }
14148            pw.println("  mHomeProcess: " + mHomeProcess);
14149        }
14150        if (mPreviousProcess != null && (dumpPackage == null
14151                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14152            if (needSep) {
14153                pw.println();
14154                needSep = false;
14155            }
14156            pw.println("  mPreviousProcess: " + mPreviousProcess);
14157        }
14158        if (dumpAll) {
14159            StringBuilder sb = new StringBuilder(128);
14160            sb.append("  mPreviousProcessVisibleTime: ");
14161            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14162            pw.println(sb);
14163        }
14164        if (mHeavyWeightProcess != null && (dumpPackage == null
14165                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14166            if (needSep) {
14167                pw.println();
14168                needSep = false;
14169            }
14170            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14171        }
14172        if (dumpPackage == null) {
14173            pw.println("  mConfiguration: " + mConfiguration);
14174        }
14175        if (dumpAll) {
14176            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14177            if (mCompatModePackages.getPackages().size() > 0) {
14178                boolean printed = false;
14179                for (Map.Entry<String, Integer> entry
14180                        : mCompatModePackages.getPackages().entrySet()) {
14181                    String pkg = entry.getKey();
14182                    int mode = entry.getValue();
14183                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14184                        continue;
14185                    }
14186                    if (!printed) {
14187                        pw.println("  mScreenCompatPackages:");
14188                        printed = true;
14189                    }
14190                    pw.print("    "); pw.print(pkg); pw.print(": ");
14191                            pw.print(mode); pw.println();
14192                }
14193            }
14194        }
14195        if (dumpPackage == null) {
14196            pw.println("  mWakefulness="
14197                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14198            pw.println("  mSleepTokens=" + mSleepTokens);
14199            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14200                    + lockScreenShownToString());
14201            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14202            if (mRunningVoice != null) {
14203                pw.println("  mRunningVoice=" + mRunningVoice);
14204                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14205            }
14206        }
14207        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14208                || mOrigWaitForDebugger) {
14209            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14210                    || dumpPackage.equals(mOrigDebugApp)) {
14211                if (needSep) {
14212                    pw.println();
14213                    needSep = false;
14214                }
14215                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14216                        + " mDebugTransient=" + mDebugTransient
14217                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14218            }
14219        }
14220        if (mCurAppTimeTracker != null) {
14221            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14222        }
14223        if (mMemWatchProcesses.getMap().size() > 0) {
14224            pw.println("  Mem watch processes:");
14225            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14226                    = mMemWatchProcesses.getMap();
14227            for (int i=0; i<procs.size(); i++) {
14228                final String proc = procs.keyAt(i);
14229                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14230                for (int j=0; j<uids.size(); j++) {
14231                    if (needSep) {
14232                        pw.println();
14233                        needSep = false;
14234                    }
14235                    StringBuilder sb = new StringBuilder();
14236                    sb.append("    ").append(proc).append('/');
14237                    UserHandle.formatUid(sb, uids.keyAt(j));
14238                    Pair<Long, String> val = uids.valueAt(j);
14239                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14240                    if (val.second != null) {
14241                        sb.append(", report to ").append(val.second);
14242                    }
14243                    pw.println(sb.toString());
14244                }
14245            }
14246            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14247            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14248            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14249                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14250        }
14251        if (mTrackAllocationApp != null) {
14252            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14253                if (needSep) {
14254                    pw.println();
14255                    needSep = false;
14256                }
14257                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14258            }
14259        }
14260        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14261                || mProfileFd != null) {
14262            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14263                if (needSep) {
14264                    pw.println();
14265                    needSep = false;
14266                }
14267                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14268                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14269                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14270                        + mAutoStopProfiler);
14271                pw.println("  mProfileType=" + mProfileType);
14272            }
14273        }
14274        if (mNativeDebuggingApp != null) {
14275            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14276                if (needSep) {
14277                    pw.println();
14278                    needSep = false;
14279                }
14280                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14281            }
14282        }
14283        if (dumpPackage == null) {
14284            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14285                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14286                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14287            }
14288            if (mController != null) {
14289                pw.println("  mController=" + mController
14290                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14291            }
14292            if (dumpAll) {
14293                pw.println("  Total persistent processes: " + numPers);
14294                pw.println("  mProcessesReady=" + mProcessesReady
14295                        + " mSystemReady=" + mSystemReady
14296                        + " mBooted=" + mBooted
14297                        + " mFactoryTest=" + mFactoryTest);
14298                pw.println("  mBooting=" + mBooting
14299                        + " mCallFinishBooting=" + mCallFinishBooting
14300                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14301                pw.print("  mLastPowerCheckRealtime=");
14302                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14303                        pw.println("");
14304                pw.print("  mLastPowerCheckUptime=");
14305                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14306                        pw.println("");
14307                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14308                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14309                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14310                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14311                        + " (" + mLruProcesses.size() + " total)"
14312                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14313                        + " mNumServiceProcs=" + mNumServiceProcs
14314                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14315                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14316                        + " mLastMemoryLevel=" + mLastMemoryLevel
14317                        + " mLastNumProcesses=" + mLastNumProcesses);
14318                long now = SystemClock.uptimeMillis();
14319                pw.print("  mLastIdleTime=");
14320                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14321                        pw.print(" mLowRamSinceLastIdle=");
14322                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14323                        pw.println();
14324            }
14325        }
14326
14327        if (!printedAnything) {
14328            pw.println("  (nothing)");
14329        }
14330    }
14331
14332    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14333            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14334        if (mProcessesToGc.size() > 0) {
14335            boolean printed = false;
14336            long now = SystemClock.uptimeMillis();
14337            for (int i=0; i<mProcessesToGc.size(); i++) {
14338                ProcessRecord proc = mProcessesToGc.get(i);
14339                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14340                    continue;
14341                }
14342                if (!printed) {
14343                    if (needSep) pw.println();
14344                    needSep = true;
14345                    pw.println("  Processes that are waiting to GC:");
14346                    printed = true;
14347                }
14348                pw.print("    Process "); pw.println(proc);
14349                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14350                        pw.print(", last gced=");
14351                        pw.print(now-proc.lastRequestedGc);
14352                        pw.print(" ms ago, last lowMem=");
14353                        pw.print(now-proc.lastLowMemory);
14354                        pw.println(" ms ago");
14355
14356            }
14357        }
14358        return needSep;
14359    }
14360
14361    void printOomLevel(PrintWriter pw, String name, int adj) {
14362        pw.print("    ");
14363        if (adj >= 0) {
14364            pw.print(' ');
14365            if (adj < 10) pw.print(' ');
14366        } else {
14367            if (adj > -10) pw.print(' ');
14368        }
14369        pw.print(adj);
14370        pw.print(": ");
14371        pw.print(name);
14372        pw.print(" (");
14373        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14374        pw.println(")");
14375    }
14376
14377    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14378            int opti, boolean dumpAll) {
14379        boolean needSep = false;
14380
14381        if (mLruProcesses.size() > 0) {
14382            if (needSep) pw.println();
14383            needSep = true;
14384            pw.println("  OOM levels:");
14385            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14386            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14387            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14388            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14389            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14390            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14391            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14392            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14393            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14394            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14395            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14396            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14397            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14398            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14399
14400            if (needSep) pw.println();
14401            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14402                    pw.print(" total, non-act at ");
14403                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14404                    pw.print(", non-svc at ");
14405                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14406                    pw.println("):");
14407            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14408            needSep = true;
14409        }
14410
14411        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14412
14413        pw.println();
14414        pw.println("  mHomeProcess: " + mHomeProcess);
14415        pw.println("  mPreviousProcess: " + mPreviousProcess);
14416        if (mHeavyWeightProcess != null) {
14417            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14418        }
14419
14420        return true;
14421    }
14422
14423    /**
14424     * There are three ways to call this:
14425     *  - no provider specified: dump all the providers
14426     *  - a flattened component name that matched an existing provider was specified as the
14427     *    first arg: dump that one provider
14428     *  - the first arg isn't the flattened component name of an existing provider:
14429     *    dump all providers whose component contains the first arg as a substring
14430     */
14431    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14432            int opti, boolean dumpAll) {
14433        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14434    }
14435
14436    static class ItemMatcher {
14437        ArrayList<ComponentName> components;
14438        ArrayList<String> strings;
14439        ArrayList<Integer> objects;
14440        boolean all;
14441
14442        ItemMatcher() {
14443            all = true;
14444        }
14445
14446        void build(String name) {
14447            ComponentName componentName = ComponentName.unflattenFromString(name);
14448            if (componentName != null) {
14449                if (components == null) {
14450                    components = new ArrayList<ComponentName>();
14451                }
14452                components.add(componentName);
14453                all = false;
14454            } else {
14455                int objectId = 0;
14456                // Not a '/' separated full component name; maybe an object ID?
14457                try {
14458                    objectId = Integer.parseInt(name, 16);
14459                    if (objects == null) {
14460                        objects = new ArrayList<Integer>();
14461                    }
14462                    objects.add(objectId);
14463                    all = false;
14464                } catch (RuntimeException e) {
14465                    // Not an integer; just do string match.
14466                    if (strings == null) {
14467                        strings = new ArrayList<String>();
14468                    }
14469                    strings.add(name);
14470                    all = false;
14471                }
14472            }
14473        }
14474
14475        int build(String[] args, int opti) {
14476            for (; opti<args.length; opti++) {
14477                String name = args[opti];
14478                if ("--".equals(name)) {
14479                    return opti+1;
14480                }
14481                build(name);
14482            }
14483            return opti;
14484        }
14485
14486        boolean match(Object object, ComponentName comp) {
14487            if (all) {
14488                return true;
14489            }
14490            if (components != null) {
14491                for (int i=0; i<components.size(); i++) {
14492                    if (components.get(i).equals(comp)) {
14493                        return true;
14494                    }
14495                }
14496            }
14497            if (objects != null) {
14498                for (int i=0; i<objects.size(); i++) {
14499                    if (System.identityHashCode(object) == objects.get(i)) {
14500                        return true;
14501                    }
14502                }
14503            }
14504            if (strings != null) {
14505                String flat = comp.flattenToString();
14506                for (int i=0; i<strings.size(); i++) {
14507                    if (flat.contains(strings.get(i))) {
14508                        return true;
14509                    }
14510                }
14511            }
14512            return false;
14513        }
14514    }
14515
14516    /**
14517     * There are three things that cmd can be:
14518     *  - a flattened component name that matches an existing activity
14519     *  - the cmd arg isn't the flattened component name of an existing activity:
14520     *    dump all activity whose component contains the cmd as a substring
14521     *  - A hex number of the ActivityRecord object instance.
14522     */
14523    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14524            int opti, boolean dumpAll) {
14525        ArrayList<ActivityRecord> activities;
14526
14527        synchronized (this) {
14528            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14529        }
14530
14531        if (activities.size() <= 0) {
14532            return false;
14533        }
14534
14535        String[] newArgs = new String[args.length - opti];
14536        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14537
14538        TaskRecord lastTask = null;
14539        boolean needSep = false;
14540        for (int i=activities.size()-1; i>=0; i--) {
14541            ActivityRecord r = activities.get(i);
14542            if (needSep) {
14543                pw.println();
14544            }
14545            needSep = true;
14546            synchronized (this) {
14547                if (lastTask != r.task) {
14548                    lastTask = r.task;
14549                    pw.print("TASK "); pw.print(lastTask.affinity);
14550                            pw.print(" id="); pw.println(lastTask.taskId);
14551                    if (dumpAll) {
14552                        lastTask.dump(pw, "  ");
14553                    }
14554                }
14555            }
14556            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14557        }
14558        return true;
14559    }
14560
14561    /**
14562     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14563     * there is a thread associated with the activity.
14564     */
14565    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14566            final ActivityRecord r, String[] args, boolean dumpAll) {
14567        String innerPrefix = prefix + "  ";
14568        synchronized (this) {
14569            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14570                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14571                    pw.print(" pid=");
14572                    if (r.app != null) pw.println(r.app.pid);
14573                    else pw.println("(not running)");
14574            if (dumpAll) {
14575                r.dump(pw, innerPrefix);
14576            }
14577        }
14578        if (r.app != null && r.app.thread != null) {
14579            // flush anything that is already in the PrintWriter since the thread is going
14580            // to write to the file descriptor directly
14581            pw.flush();
14582            try {
14583                TransferPipe tp = new TransferPipe();
14584                try {
14585                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14586                            r.appToken, innerPrefix, args);
14587                    tp.go(fd);
14588                } finally {
14589                    tp.kill();
14590                }
14591            } catch (IOException e) {
14592                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14593            } catch (RemoteException e) {
14594                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14595            }
14596        }
14597    }
14598
14599    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14600            int opti, boolean dumpAll, String dumpPackage) {
14601        boolean needSep = false;
14602        boolean onlyHistory = false;
14603        boolean printedAnything = false;
14604
14605        if ("history".equals(dumpPackage)) {
14606            if (opti < args.length && "-s".equals(args[opti])) {
14607                dumpAll = false;
14608            }
14609            onlyHistory = true;
14610            dumpPackage = null;
14611        }
14612
14613        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14614        if (!onlyHistory && dumpAll) {
14615            if (mRegisteredReceivers.size() > 0) {
14616                boolean printed = false;
14617                Iterator it = mRegisteredReceivers.values().iterator();
14618                while (it.hasNext()) {
14619                    ReceiverList r = (ReceiverList)it.next();
14620                    if (dumpPackage != null && (r.app == null ||
14621                            !dumpPackage.equals(r.app.info.packageName))) {
14622                        continue;
14623                    }
14624                    if (!printed) {
14625                        pw.println("  Registered Receivers:");
14626                        needSep = true;
14627                        printed = true;
14628                        printedAnything = true;
14629                    }
14630                    pw.print("  * "); pw.println(r);
14631                    r.dump(pw, "    ");
14632                }
14633            }
14634
14635            if (mReceiverResolver.dump(pw, needSep ?
14636                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14637                    "    ", dumpPackage, false, false)) {
14638                needSep = true;
14639                printedAnything = true;
14640            }
14641        }
14642
14643        for (BroadcastQueue q : mBroadcastQueues) {
14644            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14645            printedAnything |= needSep;
14646        }
14647
14648        needSep = true;
14649
14650        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14651            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14652                if (needSep) {
14653                    pw.println();
14654                }
14655                needSep = true;
14656                printedAnything = true;
14657                pw.print("  Sticky broadcasts for user ");
14658                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14659                StringBuilder sb = new StringBuilder(128);
14660                for (Map.Entry<String, ArrayList<Intent>> ent
14661                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14662                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14663                    if (dumpAll) {
14664                        pw.println(":");
14665                        ArrayList<Intent> intents = ent.getValue();
14666                        final int N = intents.size();
14667                        for (int i=0; i<N; i++) {
14668                            sb.setLength(0);
14669                            sb.append("    Intent: ");
14670                            intents.get(i).toShortString(sb, false, true, false, false);
14671                            pw.println(sb.toString());
14672                            Bundle bundle = intents.get(i).getExtras();
14673                            if (bundle != null) {
14674                                pw.print("      ");
14675                                pw.println(bundle.toString());
14676                            }
14677                        }
14678                    } else {
14679                        pw.println("");
14680                    }
14681                }
14682            }
14683        }
14684
14685        if (!onlyHistory && dumpAll) {
14686            pw.println();
14687            for (BroadcastQueue queue : mBroadcastQueues) {
14688                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14689                        + queue.mBroadcastsScheduled);
14690            }
14691            pw.println("  mHandler:");
14692            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14693            needSep = true;
14694            printedAnything = true;
14695        }
14696
14697        if (!printedAnything) {
14698            pw.println("  (nothing)");
14699        }
14700    }
14701
14702    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14703            int opti, boolean dumpAll, String dumpPackage) {
14704        boolean needSep;
14705        boolean printedAnything = false;
14706
14707        ItemMatcher matcher = new ItemMatcher();
14708        matcher.build(args, opti);
14709
14710        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14711
14712        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14713        printedAnything |= needSep;
14714
14715        if (mLaunchingProviders.size() > 0) {
14716            boolean printed = false;
14717            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14718                ContentProviderRecord r = mLaunchingProviders.get(i);
14719                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14720                    continue;
14721                }
14722                if (!printed) {
14723                    if (needSep) pw.println();
14724                    needSep = true;
14725                    pw.println("  Launching content providers:");
14726                    printed = true;
14727                    printedAnything = true;
14728                }
14729                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14730                        pw.println(r);
14731            }
14732        }
14733
14734        if (!printedAnything) {
14735            pw.println("  (nothing)");
14736        }
14737    }
14738
14739    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14740            int opti, boolean dumpAll, String dumpPackage) {
14741        boolean needSep = false;
14742        boolean printedAnything = false;
14743
14744        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14745
14746        if (mGrantedUriPermissions.size() > 0) {
14747            boolean printed = false;
14748            int dumpUid = -2;
14749            if (dumpPackage != null) {
14750                try {
14751                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14752                            MATCH_UNINSTALLED_PACKAGES, 0);
14753                } catch (NameNotFoundException e) {
14754                    dumpUid = -1;
14755                }
14756            }
14757            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14758                int uid = mGrantedUriPermissions.keyAt(i);
14759                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14760                    continue;
14761                }
14762                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14763                if (!printed) {
14764                    if (needSep) pw.println();
14765                    needSep = true;
14766                    pw.println("  Granted Uri Permissions:");
14767                    printed = true;
14768                    printedAnything = true;
14769                }
14770                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14771                for (UriPermission perm : perms.values()) {
14772                    pw.print("    "); pw.println(perm);
14773                    if (dumpAll) {
14774                        perm.dump(pw, "      ");
14775                    }
14776                }
14777            }
14778        }
14779
14780        if (!printedAnything) {
14781            pw.println("  (nothing)");
14782        }
14783    }
14784
14785    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14786            int opti, boolean dumpAll, String dumpPackage) {
14787        boolean printed = false;
14788
14789        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14790
14791        if (mIntentSenderRecords.size() > 0) {
14792            Iterator<WeakReference<PendingIntentRecord>> it
14793                    = mIntentSenderRecords.values().iterator();
14794            while (it.hasNext()) {
14795                WeakReference<PendingIntentRecord> ref = it.next();
14796                PendingIntentRecord rec = ref != null ? ref.get(): null;
14797                if (dumpPackage != null && (rec == null
14798                        || !dumpPackage.equals(rec.key.packageName))) {
14799                    continue;
14800                }
14801                printed = true;
14802                if (rec != null) {
14803                    pw.print("  * "); pw.println(rec);
14804                    if (dumpAll) {
14805                        rec.dump(pw, "    ");
14806                    }
14807                } else {
14808                    pw.print("  * "); pw.println(ref);
14809                }
14810            }
14811        }
14812
14813        if (!printed) {
14814            pw.println("  (nothing)");
14815        }
14816    }
14817
14818    private static final int dumpProcessList(PrintWriter pw,
14819            ActivityManagerService service, List list,
14820            String prefix, String normalLabel, String persistentLabel,
14821            String dumpPackage) {
14822        int numPers = 0;
14823        final int N = list.size()-1;
14824        for (int i=N; i>=0; i--) {
14825            ProcessRecord r = (ProcessRecord)list.get(i);
14826            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14827                continue;
14828            }
14829            pw.println(String.format("%s%s #%2d: %s",
14830                    prefix, (r.persistent ? persistentLabel : normalLabel),
14831                    i, r.toString()));
14832            if (r.persistent) {
14833                numPers++;
14834            }
14835        }
14836        return numPers;
14837    }
14838
14839    private static final boolean dumpProcessOomList(PrintWriter pw,
14840            ActivityManagerService service, List<ProcessRecord> origList,
14841            String prefix, String normalLabel, String persistentLabel,
14842            boolean inclDetails, String dumpPackage) {
14843
14844        ArrayList<Pair<ProcessRecord, Integer>> list
14845                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14846        for (int i=0; i<origList.size(); i++) {
14847            ProcessRecord r = origList.get(i);
14848            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14849                continue;
14850            }
14851            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14852        }
14853
14854        if (list.size() <= 0) {
14855            return false;
14856        }
14857
14858        Comparator<Pair<ProcessRecord, Integer>> comparator
14859                = new Comparator<Pair<ProcessRecord, Integer>>() {
14860            @Override
14861            public int compare(Pair<ProcessRecord, Integer> object1,
14862                    Pair<ProcessRecord, Integer> object2) {
14863                if (object1.first.setAdj != object2.first.setAdj) {
14864                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14865                }
14866                if (object1.first.setProcState != object2.first.setProcState) {
14867                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14868                }
14869                if (object1.second.intValue() != object2.second.intValue()) {
14870                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14871                }
14872                return 0;
14873            }
14874        };
14875
14876        Collections.sort(list, comparator);
14877
14878        final long curRealtime = SystemClock.elapsedRealtime();
14879        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14880        final long curUptime = SystemClock.uptimeMillis();
14881        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14882
14883        for (int i=list.size()-1; i>=0; i--) {
14884            ProcessRecord r = list.get(i).first;
14885            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14886            char schedGroup;
14887            switch (r.setSchedGroup) {
14888                case ProcessList.SCHED_GROUP_BACKGROUND:
14889                    schedGroup = 'B';
14890                    break;
14891                case ProcessList.SCHED_GROUP_DEFAULT:
14892                    schedGroup = 'F';
14893                    break;
14894                case ProcessList.SCHED_GROUP_TOP_APP:
14895                    schedGroup = 'T';
14896                    break;
14897                default:
14898                    schedGroup = '?';
14899                    break;
14900            }
14901            char foreground;
14902            if (r.foregroundActivities) {
14903                foreground = 'A';
14904            } else if (r.foregroundServices) {
14905                foreground = 'S';
14906            } else {
14907                foreground = ' ';
14908            }
14909            String procState = ProcessList.makeProcStateString(r.curProcState);
14910            pw.print(prefix);
14911            pw.print(r.persistent ? persistentLabel : normalLabel);
14912            pw.print(" #");
14913            int num = (origList.size()-1)-list.get(i).second;
14914            if (num < 10) pw.print(' ');
14915            pw.print(num);
14916            pw.print(": ");
14917            pw.print(oomAdj);
14918            pw.print(' ');
14919            pw.print(schedGroup);
14920            pw.print('/');
14921            pw.print(foreground);
14922            pw.print('/');
14923            pw.print(procState);
14924            pw.print(" trm:");
14925            if (r.trimMemoryLevel < 10) pw.print(' ');
14926            pw.print(r.trimMemoryLevel);
14927            pw.print(' ');
14928            pw.print(r.toShortString());
14929            pw.print(" (");
14930            pw.print(r.adjType);
14931            pw.println(')');
14932            if (r.adjSource != null || r.adjTarget != null) {
14933                pw.print(prefix);
14934                pw.print("    ");
14935                if (r.adjTarget instanceof ComponentName) {
14936                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14937                } else if (r.adjTarget != null) {
14938                    pw.print(r.adjTarget.toString());
14939                } else {
14940                    pw.print("{null}");
14941                }
14942                pw.print("<=");
14943                if (r.adjSource instanceof ProcessRecord) {
14944                    pw.print("Proc{");
14945                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14946                    pw.println("}");
14947                } else if (r.adjSource != null) {
14948                    pw.println(r.adjSource.toString());
14949                } else {
14950                    pw.println("{null}");
14951                }
14952            }
14953            if (inclDetails) {
14954                pw.print(prefix);
14955                pw.print("    ");
14956                pw.print("oom: max="); pw.print(r.maxAdj);
14957                pw.print(" curRaw="); pw.print(r.curRawAdj);
14958                pw.print(" setRaw="); pw.print(r.setRawAdj);
14959                pw.print(" cur="); pw.print(r.curAdj);
14960                pw.print(" set="); pw.println(r.setAdj);
14961                pw.print(prefix);
14962                pw.print("    ");
14963                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14964                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14965                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14966                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14967                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14968                pw.println();
14969                pw.print(prefix);
14970                pw.print("    ");
14971                pw.print("cached="); pw.print(r.cached);
14972                pw.print(" empty="); pw.print(r.empty);
14973                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14974
14975                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14976                    if (r.lastWakeTime != 0) {
14977                        long wtime;
14978                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14979                        synchronized (stats) {
14980                            wtime = stats.getProcessWakeTime(r.info.uid,
14981                                    r.pid, curRealtime);
14982                        }
14983                        long timeUsed = wtime - r.lastWakeTime;
14984                        pw.print(prefix);
14985                        pw.print("    ");
14986                        pw.print("keep awake over ");
14987                        TimeUtils.formatDuration(realtimeSince, pw);
14988                        pw.print(" used ");
14989                        TimeUtils.formatDuration(timeUsed, pw);
14990                        pw.print(" (");
14991                        pw.print((timeUsed*100)/realtimeSince);
14992                        pw.println("%)");
14993                    }
14994                    if (r.lastCpuTime != 0) {
14995                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14996                        pw.print(prefix);
14997                        pw.print("    ");
14998                        pw.print("run cpu over ");
14999                        TimeUtils.formatDuration(uptimeSince, pw);
15000                        pw.print(" used ");
15001                        TimeUtils.formatDuration(timeUsed, pw);
15002                        pw.print(" (");
15003                        pw.print((timeUsed*100)/uptimeSince);
15004                        pw.println("%)");
15005                    }
15006                }
15007            }
15008        }
15009        return true;
15010    }
15011
15012    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15013            String[] args) {
15014        ArrayList<ProcessRecord> procs;
15015        synchronized (this) {
15016            if (args != null && args.length > start
15017                    && args[start].charAt(0) != '-') {
15018                procs = new ArrayList<ProcessRecord>();
15019                int pid = -1;
15020                try {
15021                    pid = Integer.parseInt(args[start]);
15022                } catch (NumberFormatException e) {
15023                }
15024                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15025                    ProcessRecord proc = mLruProcesses.get(i);
15026                    if (proc.pid == pid) {
15027                        procs.add(proc);
15028                    } else if (allPkgs && proc.pkgList != null
15029                            && proc.pkgList.containsKey(args[start])) {
15030                        procs.add(proc);
15031                    } else if (proc.processName.equals(args[start])) {
15032                        procs.add(proc);
15033                    }
15034                }
15035                if (procs.size() <= 0) {
15036                    return null;
15037                }
15038            } else {
15039                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15040            }
15041        }
15042        return procs;
15043    }
15044
15045    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15046            PrintWriter pw, String[] args) {
15047        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15048        if (procs == null) {
15049            pw.println("No process found for: " + args[0]);
15050            return;
15051        }
15052
15053        long uptime = SystemClock.uptimeMillis();
15054        long realtime = SystemClock.elapsedRealtime();
15055        pw.println("Applications Graphics Acceleration Info:");
15056        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15057
15058        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15059            ProcessRecord r = procs.get(i);
15060            if (r.thread != null) {
15061                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15062                pw.flush();
15063                try {
15064                    TransferPipe tp = new TransferPipe();
15065                    try {
15066                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15067                        tp.go(fd);
15068                    } finally {
15069                        tp.kill();
15070                    }
15071                } catch (IOException e) {
15072                    pw.println("Failure while dumping the app: " + r);
15073                    pw.flush();
15074                } catch (RemoteException e) {
15075                    pw.println("Got a RemoteException while dumping the app " + r);
15076                    pw.flush();
15077                }
15078            }
15079        }
15080    }
15081
15082    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15083        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15084        if (procs == null) {
15085            pw.println("No process found for: " + args[0]);
15086            return;
15087        }
15088
15089        pw.println("Applications Database Info:");
15090
15091        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15092            ProcessRecord r = procs.get(i);
15093            if (r.thread != null) {
15094                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15095                pw.flush();
15096                try {
15097                    TransferPipe tp = new TransferPipe();
15098                    try {
15099                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15100                        tp.go(fd);
15101                    } finally {
15102                        tp.kill();
15103                    }
15104                } catch (IOException e) {
15105                    pw.println("Failure while dumping the app: " + r);
15106                    pw.flush();
15107                } catch (RemoteException e) {
15108                    pw.println("Got a RemoteException while dumping the app " + r);
15109                    pw.flush();
15110                }
15111            }
15112        }
15113    }
15114
15115    final static class MemItem {
15116        final boolean isProc;
15117        final String label;
15118        final String shortLabel;
15119        final long pss;
15120        final long swapPss;
15121        final int id;
15122        final boolean hasActivities;
15123        ArrayList<MemItem> subitems;
15124
15125        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15126                boolean _hasActivities) {
15127            isProc = true;
15128            label = _label;
15129            shortLabel = _shortLabel;
15130            pss = _pss;
15131            swapPss = _swapPss;
15132            id = _id;
15133            hasActivities = _hasActivities;
15134        }
15135
15136        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15137            isProc = false;
15138            label = _label;
15139            shortLabel = _shortLabel;
15140            pss = _pss;
15141            swapPss = _swapPss;
15142            id = _id;
15143            hasActivities = false;
15144        }
15145    }
15146
15147    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15148            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15149        if (sort && !isCompact) {
15150            Collections.sort(items, new Comparator<MemItem>() {
15151                @Override
15152                public int compare(MemItem lhs, MemItem rhs) {
15153                    if (lhs.pss < rhs.pss) {
15154                        return 1;
15155                    } else if (lhs.pss > rhs.pss) {
15156                        return -1;
15157                    }
15158                    return 0;
15159                }
15160            });
15161        }
15162
15163        for (int i=0; i<items.size(); i++) {
15164            MemItem mi = items.get(i);
15165            if (!isCompact) {
15166                if (dumpSwapPss) {
15167                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15168                            mi.label, stringifyKBSize(mi.swapPss));
15169                } else {
15170                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15171                }
15172            } else if (mi.isProc) {
15173                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15174                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15175                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15176                pw.println(mi.hasActivities ? ",a" : ",e");
15177            } else {
15178                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15179                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15180            }
15181            if (mi.subitems != null) {
15182                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15183                        true, isCompact, dumpSwapPss);
15184            }
15185        }
15186    }
15187
15188    // These are in KB.
15189    static final long[] DUMP_MEM_BUCKETS = new long[] {
15190        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15191        120*1024, 160*1024, 200*1024,
15192        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15193        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15194    };
15195
15196    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15197            boolean stackLike) {
15198        int start = label.lastIndexOf('.');
15199        if (start >= 0) start++;
15200        else start = 0;
15201        int end = label.length();
15202        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15203            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15204                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15205                out.append(bucket);
15206                out.append(stackLike ? "MB." : "MB ");
15207                out.append(label, start, end);
15208                return;
15209            }
15210        }
15211        out.append(memKB/1024);
15212        out.append(stackLike ? "MB." : "MB ");
15213        out.append(label, start, end);
15214    }
15215
15216    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15217            ProcessList.NATIVE_ADJ,
15218            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15219            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15220            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15221            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15222            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15223            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15224    };
15225    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15226            "Native",
15227            "System", "Persistent", "Persistent Service", "Foreground",
15228            "Visible", "Perceptible",
15229            "Heavy Weight", "Backup",
15230            "A Services", "Home",
15231            "Previous", "B Services", "Cached"
15232    };
15233    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15234            "native",
15235            "sys", "pers", "persvc", "fore",
15236            "vis", "percept",
15237            "heavy", "backup",
15238            "servicea", "home",
15239            "prev", "serviceb", "cached"
15240    };
15241
15242    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15243            long realtime, boolean isCheckinRequest, boolean isCompact) {
15244        if (isCompact) {
15245            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15246        }
15247        if (isCheckinRequest || isCompact) {
15248            // short checkin version
15249            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15250        } else {
15251            pw.println("Applications Memory Usage (in Kilobytes):");
15252            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15253        }
15254    }
15255
15256    private static final int KSM_SHARED = 0;
15257    private static final int KSM_SHARING = 1;
15258    private static final int KSM_UNSHARED = 2;
15259    private static final int KSM_VOLATILE = 3;
15260
15261    private final long[] getKsmInfo() {
15262        long[] longOut = new long[4];
15263        final int[] SINGLE_LONG_FORMAT = new int[] {
15264            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15265        };
15266        long[] longTmp = new long[1];
15267        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15268                SINGLE_LONG_FORMAT, null, longTmp, null);
15269        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15270        longTmp[0] = 0;
15271        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15272                SINGLE_LONG_FORMAT, null, longTmp, null);
15273        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15274        longTmp[0] = 0;
15275        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15276                SINGLE_LONG_FORMAT, null, longTmp, null);
15277        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15278        longTmp[0] = 0;
15279        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15280                SINGLE_LONG_FORMAT, null, longTmp, null);
15281        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15282        return longOut;
15283    }
15284
15285    private static String stringifySize(long size, int order) {
15286        Locale locale = Locale.US;
15287        switch (order) {
15288            case 1:
15289                return String.format(locale, "%,13d", size);
15290            case 1024:
15291                return String.format(locale, "%,9dK", size / 1024);
15292            case 1024 * 1024:
15293                return String.format(locale, "%,5dM", size / 1024 / 1024);
15294            case 1024 * 1024 * 1024:
15295                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15296            default:
15297                throw new IllegalArgumentException("Invalid size order");
15298        }
15299    }
15300
15301    private static String stringifyKBSize(long size) {
15302        return stringifySize(size * 1024, 1024);
15303    }
15304
15305    // Update this version number in case you change the 'compact' format
15306    private static final int MEMINFO_COMPACT_VERSION = 1;
15307
15308    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15309            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15310        boolean dumpDetails = false;
15311        boolean dumpFullDetails = false;
15312        boolean dumpDalvik = false;
15313        boolean dumpSummaryOnly = false;
15314        boolean dumpUnreachable = false;
15315        boolean oomOnly = false;
15316        boolean isCompact = false;
15317        boolean localOnly = false;
15318        boolean packages = false;
15319        boolean isCheckinRequest = false;
15320        boolean dumpSwapPss = false;
15321
15322        int opti = 0;
15323        while (opti < args.length) {
15324            String opt = args[opti];
15325            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15326                break;
15327            }
15328            opti++;
15329            if ("-a".equals(opt)) {
15330                dumpDetails = true;
15331                dumpFullDetails = true;
15332                dumpDalvik = true;
15333                dumpSwapPss = true;
15334            } else if ("-d".equals(opt)) {
15335                dumpDalvik = true;
15336            } else if ("-c".equals(opt)) {
15337                isCompact = true;
15338            } else if ("-s".equals(opt)) {
15339                dumpDetails = true;
15340                dumpSummaryOnly = true;
15341            } else if ("-S".equals(opt)) {
15342                dumpSwapPss = true;
15343            } else if ("--unreachable".equals(opt)) {
15344                dumpUnreachable = true;
15345            } else if ("--oom".equals(opt)) {
15346                oomOnly = true;
15347            } else if ("--local".equals(opt)) {
15348                localOnly = true;
15349            } else if ("--package".equals(opt)) {
15350                packages = true;
15351            } else if ("--checkin".equals(opt)) {
15352                isCheckinRequest = true;
15353
15354            } else if ("-h".equals(opt)) {
15355                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15356                pw.println("  -a: include all available information for each process.");
15357                pw.println("  -d: include dalvik details.");
15358                pw.println("  -c: dump in a compact machine-parseable representation.");
15359                pw.println("  -s: dump only summary of application memory usage.");
15360                pw.println("  -S: dump also SwapPss.");
15361                pw.println("  --oom: only show processes organized by oom adj.");
15362                pw.println("  --local: only collect details locally, don't call process.");
15363                pw.println("  --package: interpret process arg as package, dumping all");
15364                pw.println("             processes that have loaded that package.");
15365                pw.println("  --checkin: dump data for a checkin");
15366                pw.println("If [process] is specified it can be the name or ");
15367                pw.println("pid of a specific process to dump.");
15368                return;
15369            } else {
15370                pw.println("Unknown argument: " + opt + "; use -h for help");
15371            }
15372        }
15373
15374        long uptime = SystemClock.uptimeMillis();
15375        long realtime = SystemClock.elapsedRealtime();
15376        final long[] tmpLong = new long[1];
15377
15378        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15379        if (procs == null) {
15380            // No Java processes.  Maybe they want to print a native process.
15381            if (args != null && args.length > opti
15382                    && args[opti].charAt(0) != '-') {
15383                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15384                        = new ArrayList<ProcessCpuTracker.Stats>();
15385                updateCpuStatsNow();
15386                int findPid = -1;
15387                try {
15388                    findPid = Integer.parseInt(args[opti]);
15389                } catch (NumberFormatException e) {
15390                }
15391                synchronized (mProcessCpuTracker) {
15392                    final int N = mProcessCpuTracker.countStats();
15393                    for (int i=0; i<N; i++) {
15394                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15395                        if (st.pid == findPid || (st.baseName != null
15396                                && st.baseName.equals(args[opti]))) {
15397                            nativeProcs.add(st);
15398                        }
15399                    }
15400                }
15401                if (nativeProcs.size() > 0) {
15402                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15403                            isCompact);
15404                    Debug.MemoryInfo mi = null;
15405                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15406                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15407                        final int pid = r.pid;
15408                        if (!isCheckinRequest && dumpDetails) {
15409                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15410                        }
15411                        if (mi == null) {
15412                            mi = new Debug.MemoryInfo();
15413                        }
15414                        if (dumpDetails || (!brief && !oomOnly)) {
15415                            Debug.getMemoryInfo(pid, mi);
15416                        } else {
15417                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15418                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15419                        }
15420                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15421                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15422                        if (isCheckinRequest) {
15423                            pw.println();
15424                        }
15425                    }
15426                    return;
15427                }
15428            }
15429            pw.println("No process found for: " + args[opti]);
15430            return;
15431        }
15432
15433        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15434            dumpDetails = true;
15435        }
15436
15437        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15438
15439        String[] innerArgs = new String[args.length-opti];
15440        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15441
15442        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15443        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15444        long nativePss = 0;
15445        long nativeSwapPss = 0;
15446        long dalvikPss = 0;
15447        long dalvikSwapPss = 0;
15448        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15449                EmptyArray.LONG;
15450        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15451                EmptyArray.LONG;
15452        long otherPss = 0;
15453        long otherSwapPss = 0;
15454        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15455        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15456
15457        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15458        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15459        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15460                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15461
15462        long totalPss = 0;
15463        long totalSwapPss = 0;
15464        long cachedPss = 0;
15465        long cachedSwapPss = 0;
15466        boolean hasSwapPss = false;
15467
15468        Debug.MemoryInfo mi = null;
15469        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15470            final ProcessRecord r = procs.get(i);
15471            final IApplicationThread thread;
15472            final int pid;
15473            final int oomAdj;
15474            final boolean hasActivities;
15475            synchronized (this) {
15476                thread = r.thread;
15477                pid = r.pid;
15478                oomAdj = r.getSetAdjWithServices();
15479                hasActivities = r.activities.size() > 0;
15480            }
15481            if (thread != null) {
15482                if (!isCheckinRequest && dumpDetails) {
15483                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15484                }
15485                if (mi == null) {
15486                    mi = new Debug.MemoryInfo();
15487                }
15488                if (dumpDetails || (!brief && !oomOnly)) {
15489                    Debug.getMemoryInfo(pid, mi);
15490                    hasSwapPss = mi.hasSwappedOutPss;
15491                } else {
15492                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15493                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15494                }
15495                if (dumpDetails) {
15496                    if (localOnly) {
15497                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15498                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15499                        if (isCheckinRequest) {
15500                            pw.println();
15501                        }
15502                    } else {
15503                        try {
15504                            pw.flush();
15505                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15506                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15507                        } catch (RemoteException e) {
15508                            if (!isCheckinRequest) {
15509                                pw.println("Got RemoteException!");
15510                                pw.flush();
15511                            }
15512                        }
15513                    }
15514                }
15515
15516                final long myTotalPss = mi.getTotalPss();
15517                final long myTotalUss = mi.getTotalUss();
15518                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15519
15520                synchronized (this) {
15521                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15522                        // Record this for posterity if the process has been stable.
15523                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15524                    }
15525                }
15526
15527                if (!isCheckinRequest && mi != null) {
15528                    totalPss += myTotalPss;
15529                    totalSwapPss += myTotalSwapPss;
15530                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15531                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15532                            myTotalSwapPss, pid, hasActivities);
15533                    procMems.add(pssItem);
15534                    procMemsMap.put(pid, pssItem);
15535
15536                    nativePss += mi.nativePss;
15537                    nativeSwapPss += mi.nativeSwappedOutPss;
15538                    dalvikPss += mi.dalvikPss;
15539                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15540                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15541                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15542                        dalvikSubitemSwapPss[j] +=
15543                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15544                    }
15545                    otherPss += mi.otherPss;
15546                    otherSwapPss += mi.otherSwappedOutPss;
15547                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15548                        long mem = mi.getOtherPss(j);
15549                        miscPss[j] += mem;
15550                        otherPss -= mem;
15551                        mem = mi.getOtherSwappedOutPss(j);
15552                        miscSwapPss[j] += mem;
15553                        otherSwapPss -= mem;
15554                    }
15555
15556                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15557                        cachedPss += myTotalPss;
15558                        cachedSwapPss += myTotalSwapPss;
15559                    }
15560
15561                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15562                        if (oomIndex == (oomPss.length - 1)
15563                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15564                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15565                            oomPss[oomIndex] += myTotalPss;
15566                            oomSwapPss[oomIndex] += myTotalSwapPss;
15567                            if (oomProcs[oomIndex] == null) {
15568                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15569                            }
15570                            oomProcs[oomIndex].add(pssItem);
15571                            break;
15572                        }
15573                    }
15574                }
15575            }
15576        }
15577
15578        long nativeProcTotalPss = 0;
15579
15580        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15581            // If we are showing aggregations, also look for native processes to
15582            // include so that our aggregations are more accurate.
15583            updateCpuStatsNow();
15584            mi = null;
15585            synchronized (mProcessCpuTracker) {
15586                final int N = mProcessCpuTracker.countStats();
15587                for (int i=0; i<N; i++) {
15588                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15589                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15590                        if (mi == null) {
15591                            mi = new Debug.MemoryInfo();
15592                        }
15593                        if (!brief && !oomOnly) {
15594                            Debug.getMemoryInfo(st.pid, mi);
15595                        } else {
15596                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15597                            mi.nativePrivateDirty = (int)tmpLong[0];
15598                        }
15599
15600                        final long myTotalPss = mi.getTotalPss();
15601                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15602                        totalPss += myTotalPss;
15603                        nativeProcTotalPss += myTotalPss;
15604
15605                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15606                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15607                        procMems.add(pssItem);
15608
15609                        nativePss += mi.nativePss;
15610                        nativeSwapPss += mi.nativeSwappedOutPss;
15611                        dalvikPss += mi.dalvikPss;
15612                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15613                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15614                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15615                            dalvikSubitemSwapPss[j] +=
15616                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15617                        }
15618                        otherPss += mi.otherPss;
15619                        otherSwapPss += mi.otherSwappedOutPss;
15620                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15621                            long mem = mi.getOtherPss(j);
15622                            miscPss[j] += mem;
15623                            otherPss -= mem;
15624                            mem = mi.getOtherSwappedOutPss(j);
15625                            miscSwapPss[j] += mem;
15626                            otherSwapPss -= mem;
15627                        }
15628                        oomPss[0] += myTotalPss;
15629                        oomSwapPss[0] += myTotalSwapPss;
15630                        if (oomProcs[0] == null) {
15631                            oomProcs[0] = new ArrayList<MemItem>();
15632                        }
15633                        oomProcs[0].add(pssItem);
15634                    }
15635                }
15636            }
15637
15638            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15639
15640            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15641            final MemItem dalvikItem =
15642                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15643            if (dalvikSubitemPss.length > 0) {
15644                dalvikItem.subitems = new ArrayList<MemItem>();
15645                for (int j=0; j<dalvikSubitemPss.length; j++) {
15646                    final String name = Debug.MemoryInfo.getOtherLabel(
15647                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15648                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15649                                    dalvikSubitemSwapPss[j], j));
15650                }
15651            }
15652            catMems.add(dalvikItem);
15653            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15654            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15655                String label = Debug.MemoryInfo.getOtherLabel(j);
15656                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15657            }
15658
15659            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15660            for (int j=0; j<oomPss.length; j++) {
15661                if (oomPss[j] != 0) {
15662                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15663                            : DUMP_MEM_OOM_LABEL[j];
15664                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15665                            DUMP_MEM_OOM_ADJ[j]);
15666                    item.subitems = oomProcs[j];
15667                    oomMems.add(item);
15668                }
15669            }
15670
15671            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15672            if (!brief && !oomOnly && !isCompact) {
15673                pw.println();
15674                pw.println("Total PSS by process:");
15675                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15676                pw.println();
15677            }
15678            if (!isCompact) {
15679                pw.println("Total PSS by OOM adjustment:");
15680            }
15681            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15682            if (!brief && !oomOnly) {
15683                PrintWriter out = categoryPw != null ? categoryPw : pw;
15684                if (!isCompact) {
15685                    out.println();
15686                    out.println("Total PSS by category:");
15687                }
15688                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15689            }
15690            if (!isCompact) {
15691                pw.println();
15692            }
15693            MemInfoReader memInfo = new MemInfoReader();
15694            memInfo.readMemInfo();
15695            if (nativeProcTotalPss > 0) {
15696                synchronized (this) {
15697                    final long cachedKb = memInfo.getCachedSizeKb();
15698                    final long freeKb = memInfo.getFreeSizeKb();
15699                    final long zramKb = memInfo.getZramTotalSizeKb();
15700                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15701                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15702                            kernelKb*1024, nativeProcTotalPss*1024);
15703                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15704                            nativeProcTotalPss);
15705                }
15706            }
15707            if (!brief) {
15708                if (!isCompact) {
15709                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15710                    pw.print(" (status ");
15711                    switch (mLastMemoryLevel) {
15712                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15713                            pw.println("normal)");
15714                            break;
15715                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15716                            pw.println("moderate)");
15717                            break;
15718                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15719                            pw.println("low)");
15720                            break;
15721                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15722                            pw.println("critical)");
15723                            break;
15724                        default:
15725                            pw.print(mLastMemoryLevel);
15726                            pw.println(")");
15727                            break;
15728                    }
15729                    pw.print(" Free RAM: ");
15730                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15731                            + memInfo.getFreeSizeKb()));
15732                    pw.print(" (");
15733                    pw.print(stringifyKBSize(cachedPss));
15734                    pw.print(" cached pss + ");
15735                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15736                    pw.print(" cached kernel + ");
15737                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15738                    pw.println(" free)");
15739                } else {
15740                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15741                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15742                            + memInfo.getFreeSizeKb()); pw.print(",");
15743                    pw.println(totalPss - cachedPss);
15744                }
15745            }
15746            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15747                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15748                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15749            if (!isCompact) {
15750                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15751                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15752                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15753                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15754                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15755            } else {
15756                pw.print("lostram,"); pw.println(lostRAM);
15757            }
15758            if (!brief) {
15759                if (memInfo.getZramTotalSizeKb() != 0) {
15760                    if (!isCompact) {
15761                        pw.print("     ZRAM: ");
15762                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15763                                pw.print(" physical used for ");
15764                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15765                                        - memInfo.getSwapFreeSizeKb()));
15766                                pw.print(" in swap (");
15767                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15768                                pw.println(" total swap)");
15769                    } else {
15770                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15771                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15772                                pw.println(memInfo.getSwapFreeSizeKb());
15773                    }
15774                }
15775                final long[] ksm = getKsmInfo();
15776                if (!isCompact) {
15777                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15778                            || ksm[KSM_VOLATILE] != 0) {
15779                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15780                                pw.print(" saved from shared ");
15781                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15782                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15783                                pw.print(" unshared; ");
15784                                pw.print(stringifyKBSize(
15785                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15786                    }
15787                    pw.print("   Tuning: ");
15788                    pw.print(ActivityManager.staticGetMemoryClass());
15789                    pw.print(" (large ");
15790                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15791                    pw.print("), oom ");
15792                    pw.print(stringifySize(
15793                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15794                    pw.print(", restore limit ");
15795                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15796                    if (ActivityManager.isLowRamDeviceStatic()) {
15797                        pw.print(" (low-ram)");
15798                    }
15799                    if (ActivityManager.isHighEndGfx()) {
15800                        pw.print(" (high-end-gfx)");
15801                    }
15802                    pw.println();
15803                } else {
15804                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15805                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15806                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15807                    pw.print("tuning,");
15808                    pw.print(ActivityManager.staticGetMemoryClass());
15809                    pw.print(',');
15810                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15811                    pw.print(',');
15812                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15813                    if (ActivityManager.isLowRamDeviceStatic()) {
15814                        pw.print(",low-ram");
15815                    }
15816                    if (ActivityManager.isHighEndGfx()) {
15817                        pw.print(",high-end-gfx");
15818                    }
15819                    pw.println();
15820                }
15821            }
15822        }
15823    }
15824
15825    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15826            long memtrack, String name) {
15827        sb.append("  ");
15828        sb.append(ProcessList.makeOomAdjString(oomAdj));
15829        sb.append(' ');
15830        sb.append(ProcessList.makeProcStateString(procState));
15831        sb.append(' ');
15832        ProcessList.appendRamKb(sb, pss);
15833        sb.append(": ");
15834        sb.append(name);
15835        if (memtrack > 0) {
15836            sb.append(" (");
15837            sb.append(stringifyKBSize(memtrack));
15838            sb.append(" memtrack)");
15839        }
15840    }
15841
15842    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15843        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15844        sb.append(" (pid ");
15845        sb.append(mi.pid);
15846        sb.append(") ");
15847        sb.append(mi.adjType);
15848        sb.append('\n');
15849        if (mi.adjReason != null) {
15850            sb.append("                      ");
15851            sb.append(mi.adjReason);
15852            sb.append('\n');
15853        }
15854    }
15855
15856    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15857        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15858        for (int i=0, N=memInfos.size(); i<N; i++) {
15859            ProcessMemInfo mi = memInfos.get(i);
15860            infoMap.put(mi.pid, mi);
15861        }
15862        updateCpuStatsNow();
15863        long[] memtrackTmp = new long[1];
15864        synchronized (mProcessCpuTracker) {
15865            final int N = mProcessCpuTracker.countStats();
15866            for (int i=0; i<N; i++) {
15867                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15868                if (st.vsize > 0) {
15869                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15870                    if (pss > 0) {
15871                        if (infoMap.indexOfKey(st.pid) < 0) {
15872                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15873                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15874                            mi.pss = pss;
15875                            mi.memtrack = memtrackTmp[0];
15876                            memInfos.add(mi);
15877                        }
15878                    }
15879                }
15880            }
15881        }
15882
15883        long totalPss = 0;
15884        long totalMemtrack = 0;
15885        for (int i=0, N=memInfos.size(); i<N; i++) {
15886            ProcessMemInfo mi = memInfos.get(i);
15887            if (mi.pss == 0) {
15888                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15889                mi.memtrack = memtrackTmp[0];
15890            }
15891            totalPss += mi.pss;
15892            totalMemtrack += mi.memtrack;
15893        }
15894        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15895            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15896                if (lhs.oomAdj != rhs.oomAdj) {
15897                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15898                }
15899                if (lhs.pss != rhs.pss) {
15900                    return lhs.pss < rhs.pss ? 1 : -1;
15901                }
15902                return 0;
15903            }
15904        });
15905
15906        StringBuilder tag = new StringBuilder(128);
15907        StringBuilder stack = new StringBuilder(128);
15908        tag.append("Low on memory -- ");
15909        appendMemBucket(tag, totalPss, "total", false);
15910        appendMemBucket(stack, totalPss, "total", true);
15911
15912        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15913        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15914        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15915
15916        boolean firstLine = true;
15917        int lastOomAdj = Integer.MIN_VALUE;
15918        long extraNativeRam = 0;
15919        long extraNativeMemtrack = 0;
15920        long cachedPss = 0;
15921        for (int i=0, N=memInfos.size(); i<N; i++) {
15922            ProcessMemInfo mi = memInfos.get(i);
15923
15924            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15925                cachedPss += mi.pss;
15926            }
15927
15928            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15929                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15930                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15931                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15932                if (lastOomAdj != mi.oomAdj) {
15933                    lastOomAdj = mi.oomAdj;
15934                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15935                        tag.append(" / ");
15936                    }
15937                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15938                        if (firstLine) {
15939                            stack.append(":");
15940                            firstLine = false;
15941                        }
15942                        stack.append("\n\t at ");
15943                    } else {
15944                        stack.append("$");
15945                    }
15946                } else {
15947                    tag.append(" ");
15948                    stack.append("$");
15949                }
15950                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15951                    appendMemBucket(tag, mi.pss, mi.name, false);
15952                }
15953                appendMemBucket(stack, mi.pss, mi.name, true);
15954                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15955                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15956                    stack.append("(");
15957                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15958                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15959                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15960                            stack.append(":");
15961                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15962                        }
15963                    }
15964                    stack.append(")");
15965                }
15966            }
15967
15968            appendMemInfo(fullNativeBuilder, mi);
15969            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15970                // The short form only has native processes that are >= 512K.
15971                if (mi.pss >= 512) {
15972                    appendMemInfo(shortNativeBuilder, mi);
15973                } else {
15974                    extraNativeRam += mi.pss;
15975                    extraNativeMemtrack += mi.memtrack;
15976                }
15977            } else {
15978                // Short form has all other details, but if we have collected RAM
15979                // from smaller native processes let's dump a summary of that.
15980                if (extraNativeRam > 0) {
15981                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15982                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15983                    shortNativeBuilder.append('\n');
15984                    extraNativeRam = 0;
15985                }
15986                appendMemInfo(fullJavaBuilder, mi);
15987            }
15988        }
15989
15990        fullJavaBuilder.append("           ");
15991        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15992        fullJavaBuilder.append(": TOTAL");
15993        if (totalMemtrack > 0) {
15994            fullJavaBuilder.append(" (");
15995            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15996            fullJavaBuilder.append(" memtrack)");
15997        } else {
15998        }
15999        fullJavaBuilder.append("\n");
16000
16001        MemInfoReader memInfo = new MemInfoReader();
16002        memInfo.readMemInfo();
16003        final long[] infos = memInfo.getRawInfo();
16004
16005        StringBuilder memInfoBuilder = new StringBuilder(1024);
16006        Debug.getMemInfo(infos);
16007        memInfoBuilder.append("  MemInfo: ");
16008        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16009        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16010        memInfoBuilder.append(stringifyKBSize(
16011                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16012        memInfoBuilder.append(stringifyKBSize(
16013                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16014        memInfoBuilder.append(stringifyKBSize(
16015                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16016        memInfoBuilder.append("           ");
16017        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16018        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16019        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16020        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16021        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16022            memInfoBuilder.append("  ZRAM: ");
16023            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16024            memInfoBuilder.append(" RAM, ");
16025            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16026            memInfoBuilder.append(" swap total, ");
16027            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16028            memInfoBuilder.append(" swap free\n");
16029        }
16030        final long[] ksm = getKsmInfo();
16031        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16032                || ksm[KSM_VOLATILE] != 0) {
16033            memInfoBuilder.append("  KSM: ");
16034            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16035            memInfoBuilder.append(" saved from shared ");
16036            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16037            memInfoBuilder.append("\n       ");
16038            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16039            memInfoBuilder.append(" unshared; ");
16040            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16041            memInfoBuilder.append(" volatile\n");
16042        }
16043        memInfoBuilder.append("  Free RAM: ");
16044        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16045                + memInfo.getFreeSizeKb()));
16046        memInfoBuilder.append("\n");
16047        memInfoBuilder.append("  Used RAM: ");
16048        memInfoBuilder.append(stringifyKBSize(
16049                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16050        memInfoBuilder.append("\n");
16051        memInfoBuilder.append("  Lost RAM: ");
16052        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16053                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16054                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16055        memInfoBuilder.append("\n");
16056        Slog.i(TAG, "Low on memory:");
16057        Slog.i(TAG, shortNativeBuilder.toString());
16058        Slog.i(TAG, fullJavaBuilder.toString());
16059        Slog.i(TAG, memInfoBuilder.toString());
16060
16061        StringBuilder dropBuilder = new StringBuilder(1024);
16062        /*
16063        StringWriter oomSw = new StringWriter();
16064        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16065        StringWriter catSw = new StringWriter();
16066        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16067        String[] emptyArgs = new String[] { };
16068        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16069        oomPw.flush();
16070        String oomString = oomSw.toString();
16071        */
16072        dropBuilder.append("Low on memory:");
16073        dropBuilder.append(stack);
16074        dropBuilder.append('\n');
16075        dropBuilder.append(fullNativeBuilder);
16076        dropBuilder.append(fullJavaBuilder);
16077        dropBuilder.append('\n');
16078        dropBuilder.append(memInfoBuilder);
16079        dropBuilder.append('\n');
16080        /*
16081        dropBuilder.append(oomString);
16082        dropBuilder.append('\n');
16083        */
16084        StringWriter catSw = new StringWriter();
16085        synchronized (ActivityManagerService.this) {
16086            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16087            String[] emptyArgs = new String[] { };
16088            catPw.println();
16089            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16090            catPw.println();
16091            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16092                    false, false, null);
16093            catPw.println();
16094            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16095            catPw.flush();
16096        }
16097        dropBuilder.append(catSw.toString());
16098        addErrorToDropBox("lowmem", null, "system_server", null,
16099                null, tag.toString(), dropBuilder.toString(), null, null);
16100        //Slog.i(TAG, "Sent to dropbox:");
16101        //Slog.i(TAG, dropBuilder.toString());
16102        synchronized (ActivityManagerService.this) {
16103            long now = SystemClock.uptimeMillis();
16104            if (mLastMemUsageReportTime < now) {
16105                mLastMemUsageReportTime = now;
16106            }
16107        }
16108    }
16109
16110    /**
16111     * Searches array of arguments for the specified string
16112     * @param args array of argument strings
16113     * @param value value to search for
16114     * @return true if the value is contained in the array
16115     */
16116    private static boolean scanArgs(String[] args, String value) {
16117        if (args != null) {
16118            for (String arg : args) {
16119                if (value.equals(arg)) {
16120                    return true;
16121                }
16122            }
16123        }
16124        return false;
16125    }
16126
16127    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16128            ContentProviderRecord cpr, boolean always) {
16129        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16130
16131        if (!inLaunching || always) {
16132            synchronized (cpr) {
16133                cpr.launchingApp = null;
16134                cpr.notifyAll();
16135            }
16136            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16137            String names[] = cpr.info.authority.split(";");
16138            for (int j = 0; j < names.length; j++) {
16139                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16140            }
16141        }
16142
16143        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16144            ContentProviderConnection conn = cpr.connections.get(i);
16145            if (conn.waiting) {
16146                // If this connection is waiting for the provider, then we don't
16147                // need to mess with its process unless we are always removing
16148                // or for some reason the provider is not currently launching.
16149                if (inLaunching && !always) {
16150                    continue;
16151                }
16152            }
16153            ProcessRecord capp = conn.client;
16154            conn.dead = true;
16155            if (conn.stableCount > 0) {
16156                if (!capp.persistent && capp.thread != null
16157                        && capp.pid != 0
16158                        && capp.pid != MY_PID) {
16159                    capp.kill("depends on provider "
16160                            + cpr.name.flattenToShortString()
16161                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16162                }
16163            } else if (capp.thread != null && conn.provider.provider != null) {
16164                try {
16165                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16166                } catch (RemoteException e) {
16167                }
16168                // In the protocol here, we don't expect the client to correctly
16169                // clean up this connection, we'll just remove it.
16170                cpr.connections.remove(i);
16171                if (conn.client.conProviders.remove(conn)) {
16172                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16173                }
16174            }
16175        }
16176
16177        if (inLaunching && always) {
16178            mLaunchingProviders.remove(cpr);
16179        }
16180        return inLaunching;
16181    }
16182
16183    /**
16184     * Main code for cleaning up a process when it has gone away.  This is
16185     * called both as a result of the process dying, or directly when stopping
16186     * a process when running in single process mode.
16187     *
16188     * @return Returns true if the given process has been restarted, so the
16189     * app that was passed in must remain on the process lists.
16190     */
16191    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16192            boolean restarting, boolean allowRestart, int index) {
16193        if (index >= 0) {
16194            removeLruProcessLocked(app);
16195            ProcessList.remove(app.pid);
16196        }
16197
16198        mProcessesToGc.remove(app);
16199        mPendingPssProcesses.remove(app);
16200
16201        // Dismiss any open dialogs.
16202        if (app.crashDialog != null && !app.forceCrashReport) {
16203            app.crashDialog.dismiss();
16204            app.crashDialog = null;
16205        }
16206        if (app.anrDialog != null) {
16207            app.anrDialog.dismiss();
16208            app.anrDialog = null;
16209        }
16210        if (app.waitDialog != null) {
16211            app.waitDialog.dismiss();
16212            app.waitDialog = null;
16213        }
16214
16215        app.crashing = false;
16216        app.notResponding = false;
16217
16218        app.resetPackageList(mProcessStats);
16219        app.unlinkDeathRecipient();
16220        app.makeInactive(mProcessStats);
16221        app.waitingToKill = null;
16222        app.forcingToForeground = null;
16223        updateProcessForegroundLocked(app, false, false);
16224        app.foregroundActivities = false;
16225        app.hasShownUi = false;
16226        app.treatLikeActivity = false;
16227        app.hasAboveClient = false;
16228        app.hasClientActivities = false;
16229
16230        mServices.killServicesLocked(app, allowRestart);
16231
16232        boolean restart = false;
16233
16234        // Remove published content providers.
16235        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16236            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16237            final boolean always = app.bad || !allowRestart;
16238            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16239            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16240                // We left the provider in the launching list, need to
16241                // restart it.
16242                restart = true;
16243            }
16244
16245            cpr.provider = null;
16246            cpr.proc = null;
16247        }
16248        app.pubProviders.clear();
16249
16250        // Take care of any launching providers waiting for this process.
16251        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16252            restart = true;
16253        }
16254
16255        // Unregister from connected content providers.
16256        if (!app.conProviders.isEmpty()) {
16257            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16258                ContentProviderConnection conn = app.conProviders.get(i);
16259                conn.provider.connections.remove(conn);
16260                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16261                        conn.provider.name);
16262            }
16263            app.conProviders.clear();
16264        }
16265
16266        // At this point there may be remaining entries in mLaunchingProviders
16267        // where we were the only one waiting, so they are no longer of use.
16268        // Look for these and clean up if found.
16269        // XXX Commented out for now.  Trying to figure out a way to reproduce
16270        // the actual situation to identify what is actually going on.
16271        if (false) {
16272            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16273                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16274                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16275                    synchronized (cpr) {
16276                        cpr.launchingApp = null;
16277                        cpr.notifyAll();
16278                    }
16279                }
16280            }
16281        }
16282
16283        skipCurrentReceiverLocked(app);
16284
16285        // Unregister any receivers.
16286        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16287            removeReceiverLocked(app.receivers.valueAt(i));
16288        }
16289        app.receivers.clear();
16290
16291        // If the app is undergoing backup, tell the backup manager about it
16292        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16293            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16294                    + mBackupTarget.appInfo + " died during backup");
16295            try {
16296                IBackupManager bm = IBackupManager.Stub.asInterface(
16297                        ServiceManager.getService(Context.BACKUP_SERVICE));
16298                bm.agentDisconnected(app.info.packageName);
16299            } catch (RemoteException e) {
16300                // can't happen; backup manager is local
16301            }
16302        }
16303
16304        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16305            ProcessChangeItem item = mPendingProcessChanges.get(i);
16306            if (item.pid == app.pid) {
16307                mPendingProcessChanges.remove(i);
16308                mAvailProcessChanges.add(item);
16309            }
16310        }
16311        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16312                null).sendToTarget();
16313
16314        // If the caller is restarting this app, then leave it in its
16315        // current lists and let the caller take care of it.
16316        if (restarting) {
16317            return false;
16318        }
16319
16320        if (!app.persistent || app.isolated) {
16321            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16322                    "Removing non-persistent process during cleanup: " + app);
16323            removeProcessNameLocked(app.processName, app.uid);
16324            if (mHeavyWeightProcess == app) {
16325                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16326                        mHeavyWeightProcess.userId, 0));
16327                mHeavyWeightProcess = null;
16328            }
16329        } else if (!app.removed) {
16330            // This app is persistent, so we need to keep its record around.
16331            // If it is not already on the pending app list, add it there
16332            // and start a new process for it.
16333            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16334                mPersistentStartingProcesses.add(app);
16335                restart = true;
16336            }
16337        }
16338        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16339                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16340        mProcessesOnHold.remove(app);
16341
16342        if (app == mHomeProcess) {
16343            mHomeProcess = null;
16344        }
16345        if (app == mPreviousProcess) {
16346            mPreviousProcess = null;
16347        }
16348
16349        if (restart && !app.isolated) {
16350            // We have components that still need to be running in the
16351            // process, so re-launch it.
16352            if (index < 0) {
16353                ProcessList.remove(app.pid);
16354            }
16355            addProcessNameLocked(app);
16356            startProcessLocked(app, "restart", app.processName);
16357            return true;
16358        } else if (app.pid > 0 && app.pid != MY_PID) {
16359            // Goodbye!
16360            boolean removed;
16361            synchronized (mPidsSelfLocked) {
16362                mPidsSelfLocked.remove(app.pid);
16363                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16364            }
16365            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16366            if (app.isolated) {
16367                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16368            }
16369            app.setPid(0);
16370        }
16371        return false;
16372    }
16373
16374    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16375        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16376            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16377            if (cpr.launchingApp == app) {
16378                return true;
16379            }
16380        }
16381        return false;
16382    }
16383
16384    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16385        // Look through the content providers we are waiting to have launched,
16386        // and if any run in this process then either schedule a restart of
16387        // the process or kill the client waiting for it if this process has
16388        // gone bad.
16389        boolean restart = false;
16390        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16391            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16392            if (cpr.launchingApp == app) {
16393                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16394                    restart = true;
16395                } else {
16396                    removeDyingProviderLocked(app, cpr, true);
16397                }
16398            }
16399        }
16400        return restart;
16401    }
16402
16403    // =========================================================
16404    // SERVICES
16405    // =========================================================
16406
16407    @Override
16408    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16409            int flags) {
16410        enforceNotIsolatedCaller("getServices");
16411        synchronized (this) {
16412            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16413        }
16414    }
16415
16416    @Override
16417    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16418        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16419        synchronized (this) {
16420            return mServices.getRunningServiceControlPanelLocked(name);
16421        }
16422    }
16423
16424    @Override
16425    public ComponentName startService(IApplicationThread caller, Intent service,
16426            String resolvedType, String callingPackage, int userId)
16427            throws TransactionTooLargeException {
16428        enforceNotIsolatedCaller("startService");
16429        // Refuse possible leaked file descriptors
16430        if (service != null && service.hasFileDescriptors() == true) {
16431            throw new IllegalArgumentException("File descriptors passed in Intent");
16432        }
16433
16434        if (callingPackage == null) {
16435            throw new IllegalArgumentException("callingPackage cannot be null");
16436        }
16437
16438        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16439                "startService: " + service + " type=" + resolvedType);
16440        synchronized(this) {
16441            final int callingPid = Binder.getCallingPid();
16442            final int callingUid = Binder.getCallingUid();
16443            final long origId = Binder.clearCallingIdentity();
16444            ComponentName res = mServices.startServiceLocked(caller, service,
16445                    resolvedType, callingPid, callingUid, callingPackage, userId);
16446            Binder.restoreCallingIdentity(origId);
16447            return res;
16448        }
16449    }
16450
16451    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16452            String callingPackage, int userId)
16453            throws TransactionTooLargeException {
16454        synchronized(this) {
16455            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16456                    "startServiceInPackage: " + service + " type=" + resolvedType);
16457            final long origId = Binder.clearCallingIdentity();
16458            ComponentName res = mServices.startServiceLocked(null, service,
16459                    resolvedType, -1, uid, callingPackage, userId);
16460            Binder.restoreCallingIdentity(origId);
16461            return res;
16462        }
16463    }
16464
16465    @Override
16466    public int stopService(IApplicationThread caller, Intent service,
16467            String resolvedType, int userId) {
16468        enforceNotIsolatedCaller("stopService");
16469        // Refuse possible leaked file descriptors
16470        if (service != null && service.hasFileDescriptors() == true) {
16471            throw new IllegalArgumentException("File descriptors passed in Intent");
16472        }
16473
16474        synchronized(this) {
16475            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16476        }
16477    }
16478
16479    @Override
16480    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16481        enforceNotIsolatedCaller("peekService");
16482        // Refuse possible leaked file descriptors
16483        if (service != null && service.hasFileDescriptors() == true) {
16484            throw new IllegalArgumentException("File descriptors passed in Intent");
16485        }
16486
16487        if (callingPackage == null) {
16488            throw new IllegalArgumentException("callingPackage cannot be null");
16489        }
16490
16491        synchronized(this) {
16492            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16493        }
16494    }
16495
16496    @Override
16497    public boolean stopServiceToken(ComponentName className, IBinder token,
16498            int startId) {
16499        synchronized(this) {
16500            return mServices.stopServiceTokenLocked(className, token, startId);
16501        }
16502    }
16503
16504    @Override
16505    public void setServiceForeground(ComponentName className, IBinder token,
16506            int id, Notification notification, int flags) {
16507        synchronized(this) {
16508            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16509        }
16510    }
16511
16512    @Override
16513    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16514            boolean requireFull, String name, String callerPackage) {
16515        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16516                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16517    }
16518
16519    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16520            String className, int flags) {
16521        boolean result = false;
16522        // For apps that don't have pre-defined UIDs, check for permission
16523        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16524            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16525                if (ActivityManager.checkUidPermission(
16526                        INTERACT_ACROSS_USERS,
16527                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16528                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16529                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16530                            + " requests FLAG_SINGLE_USER, but app does not hold "
16531                            + INTERACT_ACROSS_USERS;
16532                    Slog.w(TAG, msg);
16533                    throw new SecurityException(msg);
16534                }
16535                // Permission passed
16536                result = true;
16537            }
16538        } else if ("system".equals(componentProcessName)) {
16539            result = true;
16540        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16541            // Phone app and persistent apps are allowed to export singleuser providers.
16542            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16543                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16544        }
16545        if (DEBUG_MU) Slog.v(TAG_MU,
16546                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16547                + Integer.toHexString(flags) + ") = " + result);
16548        return result;
16549    }
16550
16551    /**
16552     * Checks to see if the caller is in the same app as the singleton
16553     * component, or the component is in a special app. It allows special apps
16554     * to export singleton components but prevents exporting singleton
16555     * components for regular apps.
16556     */
16557    boolean isValidSingletonCall(int callingUid, int componentUid) {
16558        int componentAppId = UserHandle.getAppId(componentUid);
16559        return UserHandle.isSameApp(callingUid, componentUid)
16560                || componentAppId == Process.SYSTEM_UID
16561                || componentAppId == Process.PHONE_UID
16562                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16563                        == PackageManager.PERMISSION_GRANTED;
16564    }
16565
16566    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16567            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16568            int userId) throws TransactionTooLargeException {
16569        enforceNotIsolatedCaller("bindService");
16570
16571        // Refuse possible leaked file descriptors
16572        if (service != null && service.hasFileDescriptors() == true) {
16573            throw new IllegalArgumentException("File descriptors passed in Intent");
16574        }
16575
16576        if (callingPackage == null) {
16577            throw new IllegalArgumentException("callingPackage cannot be null");
16578        }
16579
16580        synchronized(this) {
16581            return mServices.bindServiceLocked(caller, token, service,
16582                    resolvedType, connection, flags, callingPackage, userId);
16583        }
16584    }
16585
16586    public boolean unbindService(IServiceConnection connection) {
16587        synchronized (this) {
16588            return mServices.unbindServiceLocked(connection);
16589        }
16590    }
16591
16592    public void publishService(IBinder token, Intent intent, IBinder service) {
16593        // Refuse possible leaked file descriptors
16594        if (intent != null && intent.hasFileDescriptors() == true) {
16595            throw new IllegalArgumentException("File descriptors passed in Intent");
16596        }
16597
16598        synchronized(this) {
16599            if (!(token instanceof ServiceRecord)) {
16600                throw new IllegalArgumentException("Invalid service token");
16601            }
16602            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16603        }
16604    }
16605
16606    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16607        // Refuse possible leaked file descriptors
16608        if (intent != null && intent.hasFileDescriptors() == true) {
16609            throw new IllegalArgumentException("File descriptors passed in Intent");
16610        }
16611
16612        synchronized(this) {
16613            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16614        }
16615    }
16616
16617    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16618        synchronized(this) {
16619            if (!(token instanceof ServiceRecord)) {
16620                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16621                throw new IllegalArgumentException("Invalid service token");
16622            }
16623            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16624        }
16625    }
16626
16627    // =========================================================
16628    // BACKUP AND RESTORE
16629    // =========================================================
16630
16631    // Cause the target app to be launched if necessary and its backup agent
16632    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16633    // activity manager to announce its creation.
16634    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16635        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16636                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16637        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16638
16639        synchronized(this) {
16640            // !!! TODO: currently no check here that we're already bound
16641            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16642            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16643            synchronized (stats) {
16644                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16645            }
16646
16647            // Backup agent is now in use, its package can't be stopped.
16648            try {
16649                AppGlobals.getPackageManager().setPackageStoppedState(
16650                        app.packageName, false, UserHandle.getUserId(app.uid));
16651            } catch (RemoteException e) {
16652            } catch (IllegalArgumentException e) {
16653                Slog.w(TAG, "Failed trying to unstop package "
16654                        + app.packageName + ": " + e);
16655            }
16656
16657            BackupRecord r = new BackupRecord(ss, app, backupMode);
16658            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16659                    ? new ComponentName(app.packageName, app.backupAgentName)
16660                    : new ComponentName("android", "FullBackupAgent");
16661            // startProcessLocked() returns existing proc's record if it's already running
16662            ProcessRecord proc = startProcessLocked(app.processName, app,
16663                    false, 0, "backup", hostingName, false, false, false);
16664            if (proc == null) {
16665                Slog.e(TAG, "Unable to start backup agent process " + r);
16666                return false;
16667            }
16668
16669            r.app = proc;
16670            mBackupTarget = r;
16671            mBackupAppName = app.packageName;
16672
16673            // Try not to kill the process during backup
16674            updateOomAdjLocked(proc);
16675
16676            // If the process is already attached, schedule the creation of the backup agent now.
16677            // If it is not yet live, this will be done when it attaches to the framework.
16678            if (proc.thread != null) {
16679                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16680                try {
16681                    proc.thread.scheduleCreateBackupAgent(app,
16682                            compatibilityInfoForPackageLocked(app), backupMode);
16683                } catch (RemoteException e) {
16684                    // Will time out on the backup manager side
16685                }
16686            } else {
16687                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16688            }
16689            // Invariants: at this point, the target app process exists and the application
16690            // is either already running or in the process of coming up.  mBackupTarget and
16691            // mBackupAppName describe the app, so that when it binds back to the AM we
16692            // know that it's scheduled for a backup-agent operation.
16693        }
16694
16695        return true;
16696    }
16697
16698    @Override
16699    public void clearPendingBackup() {
16700        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16701        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16702
16703        synchronized (this) {
16704            mBackupTarget = null;
16705            mBackupAppName = null;
16706        }
16707    }
16708
16709    // A backup agent has just come up
16710    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16711        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16712                + " = " + agent);
16713
16714        synchronized(this) {
16715            if (!agentPackageName.equals(mBackupAppName)) {
16716                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16717                return;
16718            }
16719        }
16720
16721        long oldIdent = Binder.clearCallingIdentity();
16722        try {
16723            IBackupManager bm = IBackupManager.Stub.asInterface(
16724                    ServiceManager.getService(Context.BACKUP_SERVICE));
16725            bm.agentConnected(agentPackageName, agent);
16726        } catch (RemoteException e) {
16727            // can't happen; the backup manager service is local
16728        } catch (Exception e) {
16729            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16730            e.printStackTrace();
16731        } finally {
16732            Binder.restoreCallingIdentity(oldIdent);
16733        }
16734    }
16735
16736    // done with this agent
16737    public void unbindBackupAgent(ApplicationInfo appInfo) {
16738        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16739        if (appInfo == null) {
16740            Slog.w(TAG, "unbind backup agent for null app");
16741            return;
16742        }
16743
16744        synchronized(this) {
16745            try {
16746                if (mBackupAppName == null) {
16747                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16748                    return;
16749                }
16750
16751                if (!mBackupAppName.equals(appInfo.packageName)) {
16752                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16753                    return;
16754                }
16755
16756                // Not backing this app up any more; reset its OOM adjustment
16757                final ProcessRecord proc = mBackupTarget.app;
16758                updateOomAdjLocked(proc);
16759
16760                // If the app crashed during backup, 'thread' will be null here
16761                if (proc.thread != null) {
16762                    try {
16763                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16764                                compatibilityInfoForPackageLocked(appInfo));
16765                    } catch (Exception e) {
16766                        Slog.e(TAG, "Exception when unbinding backup agent:");
16767                        e.printStackTrace();
16768                    }
16769                }
16770            } finally {
16771                mBackupTarget = null;
16772                mBackupAppName = null;
16773            }
16774        }
16775    }
16776    // =========================================================
16777    // BROADCASTS
16778    // =========================================================
16779
16780    boolean isPendingBroadcastProcessLocked(int pid) {
16781        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16782                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16783    }
16784
16785    void skipPendingBroadcastLocked(int pid) {
16786            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16787            for (BroadcastQueue queue : mBroadcastQueues) {
16788                queue.skipPendingBroadcastLocked(pid);
16789            }
16790    }
16791
16792    // The app just attached; send any pending broadcasts that it should receive
16793    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16794        boolean didSomething = false;
16795        for (BroadcastQueue queue : mBroadcastQueues) {
16796            didSomething |= queue.sendPendingBroadcastsLocked(app);
16797        }
16798        return didSomething;
16799    }
16800
16801    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16802            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16803        enforceNotIsolatedCaller("registerReceiver");
16804        ArrayList<Intent> stickyIntents = null;
16805        ProcessRecord callerApp = null;
16806        int callingUid;
16807        int callingPid;
16808        synchronized(this) {
16809            if (caller != null) {
16810                callerApp = getRecordForAppLocked(caller);
16811                if (callerApp == null) {
16812                    throw new SecurityException(
16813                            "Unable to find app for caller " + caller
16814                            + " (pid=" + Binder.getCallingPid()
16815                            + ") when registering receiver " + receiver);
16816                }
16817                if (callerApp.info.uid != Process.SYSTEM_UID &&
16818                        !callerApp.pkgList.containsKey(callerPackage) &&
16819                        !"android".equals(callerPackage)) {
16820                    throw new SecurityException("Given caller package " + callerPackage
16821                            + " is not running in process " + callerApp);
16822                }
16823                callingUid = callerApp.info.uid;
16824                callingPid = callerApp.pid;
16825            } else {
16826                callerPackage = null;
16827                callingUid = Binder.getCallingUid();
16828                callingPid = Binder.getCallingPid();
16829            }
16830
16831            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16832                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16833
16834            Iterator<String> actions = filter.actionsIterator();
16835            if (actions == null) {
16836                ArrayList<String> noAction = new ArrayList<String>(1);
16837                noAction.add(null);
16838                actions = noAction.iterator();
16839            }
16840
16841            // Collect stickies of users
16842            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16843            while (actions.hasNext()) {
16844                String action = actions.next();
16845                for (int id : userIds) {
16846                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16847                    if (stickies != null) {
16848                        ArrayList<Intent> intents = stickies.get(action);
16849                        if (intents != null) {
16850                            if (stickyIntents == null) {
16851                                stickyIntents = new ArrayList<Intent>();
16852                            }
16853                            stickyIntents.addAll(intents);
16854                        }
16855                    }
16856                }
16857            }
16858        }
16859
16860        ArrayList<Intent> allSticky = null;
16861        if (stickyIntents != null) {
16862            final ContentResolver resolver = mContext.getContentResolver();
16863            // Look for any matching sticky broadcasts...
16864            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16865                Intent intent = stickyIntents.get(i);
16866                // If intent has scheme "content", it will need to acccess
16867                // provider that needs to lock mProviderMap in ActivityThread
16868                // and also it may need to wait application response, so we
16869                // cannot lock ActivityManagerService here.
16870                if (filter.match(resolver, intent, true, TAG) >= 0) {
16871                    if (allSticky == null) {
16872                        allSticky = new ArrayList<Intent>();
16873                    }
16874                    allSticky.add(intent);
16875                }
16876            }
16877        }
16878
16879        // The first sticky in the list is returned directly back to the client.
16880        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16881        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16882        if (receiver == null) {
16883            return sticky;
16884        }
16885
16886        synchronized (this) {
16887            if (callerApp != null && (callerApp.thread == null
16888                    || callerApp.thread.asBinder() != caller.asBinder())) {
16889                // Original caller already died
16890                return null;
16891            }
16892            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16893            if (rl == null) {
16894                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16895                        userId, receiver);
16896                if (rl.app != null) {
16897                    rl.app.receivers.add(rl);
16898                } else {
16899                    try {
16900                        receiver.asBinder().linkToDeath(rl, 0);
16901                    } catch (RemoteException e) {
16902                        return sticky;
16903                    }
16904                    rl.linkedToDeath = true;
16905                }
16906                mRegisteredReceivers.put(receiver.asBinder(), rl);
16907            } else if (rl.uid != callingUid) {
16908                throw new IllegalArgumentException(
16909                        "Receiver requested to register for uid " + callingUid
16910                        + " was previously registered for uid " + rl.uid);
16911            } else if (rl.pid != callingPid) {
16912                throw new IllegalArgumentException(
16913                        "Receiver requested to register for pid " + callingPid
16914                        + " was previously registered for pid " + rl.pid);
16915            } else if (rl.userId != userId) {
16916                throw new IllegalArgumentException(
16917                        "Receiver requested to register for user " + userId
16918                        + " was previously registered for user " + rl.userId);
16919            }
16920            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16921                    permission, callingUid, userId);
16922            rl.add(bf);
16923            if (!bf.debugCheck()) {
16924                Slog.w(TAG, "==> For Dynamic broadcast");
16925            }
16926            mReceiverResolver.addFilter(bf);
16927
16928            // Enqueue broadcasts for all existing stickies that match
16929            // this filter.
16930            if (allSticky != null) {
16931                ArrayList receivers = new ArrayList();
16932                receivers.add(bf);
16933
16934                final int stickyCount = allSticky.size();
16935                for (int i = 0; i < stickyCount; i++) {
16936                    Intent intent = allSticky.get(i);
16937                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16938                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16939                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16940                            null, 0, null, null, false, true, true, -1);
16941                    queue.enqueueParallelBroadcastLocked(r);
16942                    queue.scheduleBroadcastsLocked();
16943                }
16944            }
16945
16946            return sticky;
16947        }
16948    }
16949
16950    public void unregisterReceiver(IIntentReceiver receiver) {
16951        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16952
16953        final long origId = Binder.clearCallingIdentity();
16954        try {
16955            boolean doTrim = false;
16956
16957            synchronized(this) {
16958                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16959                if (rl != null) {
16960                    final BroadcastRecord r = rl.curBroadcast;
16961                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16962                        final boolean doNext = r.queue.finishReceiverLocked(
16963                                r, r.resultCode, r.resultData, r.resultExtras,
16964                                r.resultAbort, false);
16965                        if (doNext) {
16966                            doTrim = true;
16967                            r.queue.processNextBroadcast(false);
16968                        }
16969                    }
16970
16971                    if (rl.app != null) {
16972                        rl.app.receivers.remove(rl);
16973                    }
16974                    removeReceiverLocked(rl);
16975                    if (rl.linkedToDeath) {
16976                        rl.linkedToDeath = false;
16977                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16978                    }
16979                }
16980            }
16981
16982            // If we actually concluded any broadcasts, we might now be able
16983            // to trim the recipients' apps from our working set
16984            if (doTrim) {
16985                trimApplications();
16986                return;
16987            }
16988
16989        } finally {
16990            Binder.restoreCallingIdentity(origId);
16991        }
16992    }
16993
16994    void removeReceiverLocked(ReceiverList rl) {
16995        mRegisteredReceivers.remove(rl.receiver.asBinder());
16996        for (int i = rl.size() - 1; i >= 0; i--) {
16997            mReceiverResolver.removeFilter(rl.get(i));
16998        }
16999    }
17000
17001    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17002        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17003            ProcessRecord r = mLruProcesses.get(i);
17004            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17005                try {
17006                    r.thread.dispatchPackageBroadcast(cmd, packages);
17007                } catch (RemoteException ex) {
17008                }
17009            }
17010        }
17011    }
17012
17013    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17014            int callingUid, int[] users) {
17015        // TODO: come back and remove this assumption to triage all broadcasts
17016        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17017
17018        List<ResolveInfo> receivers = null;
17019        try {
17020            HashSet<ComponentName> singleUserReceivers = null;
17021            boolean scannedFirstReceivers = false;
17022            for (int user : users) {
17023                // Skip users that have Shell restrictions, with exception of always permitted
17024                // Shell broadcasts
17025                if (callingUid == Process.SHELL_UID
17026                        && mUserController.hasUserRestriction(
17027                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17028                        && !isPermittedShellBroadcast(intent)) {
17029                    continue;
17030                }
17031                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17032                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17033                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17034                    // If this is not the system user, we need to check for
17035                    // any receivers that should be filtered out.
17036                    for (int i=0; i<newReceivers.size(); i++) {
17037                        ResolveInfo ri = newReceivers.get(i);
17038                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17039                            newReceivers.remove(i);
17040                            i--;
17041                        }
17042                    }
17043                }
17044                if (newReceivers != null && newReceivers.size() == 0) {
17045                    newReceivers = null;
17046                }
17047                if (receivers == null) {
17048                    receivers = newReceivers;
17049                } else if (newReceivers != null) {
17050                    // We need to concatenate the additional receivers
17051                    // found with what we have do far.  This would be easy,
17052                    // but we also need to de-dup any receivers that are
17053                    // singleUser.
17054                    if (!scannedFirstReceivers) {
17055                        // Collect any single user receivers we had already retrieved.
17056                        scannedFirstReceivers = true;
17057                        for (int i=0; i<receivers.size(); i++) {
17058                            ResolveInfo ri = receivers.get(i);
17059                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17060                                ComponentName cn = new ComponentName(
17061                                        ri.activityInfo.packageName, ri.activityInfo.name);
17062                                if (singleUserReceivers == null) {
17063                                    singleUserReceivers = new HashSet<ComponentName>();
17064                                }
17065                                singleUserReceivers.add(cn);
17066                            }
17067                        }
17068                    }
17069                    // Add the new results to the existing results, tracking
17070                    // and de-dupping single user receivers.
17071                    for (int i=0; i<newReceivers.size(); i++) {
17072                        ResolveInfo ri = newReceivers.get(i);
17073                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17074                            ComponentName cn = new ComponentName(
17075                                    ri.activityInfo.packageName, ri.activityInfo.name);
17076                            if (singleUserReceivers == null) {
17077                                singleUserReceivers = new HashSet<ComponentName>();
17078                            }
17079                            if (!singleUserReceivers.contains(cn)) {
17080                                singleUserReceivers.add(cn);
17081                                receivers.add(ri);
17082                            }
17083                        } else {
17084                            receivers.add(ri);
17085                        }
17086                    }
17087                }
17088            }
17089        } catch (RemoteException ex) {
17090            // pm is in same process, this will never happen.
17091        }
17092        return receivers;
17093    }
17094
17095    private boolean isPermittedShellBroadcast(Intent intent) {
17096        // remote bugreport should always be allowed to be taken
17097        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17098    }
17099
17100    final int broadcastIntentLocked(ProcessRecord callerApp,
17101            String callerPackage, Intent intent, String resolvedType,
17102            IIntentReceiver resultTo, int resultCode, String resultData,
17103            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17104            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17105        intent = new Intent(intent);
17106
17107        // By default broadcasts do not go to stopped apps.
17108        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17109
17110        // If we have not finished booting, don't allow this to launch new processes.
17111        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17112            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17113        }
17114
17115        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17116                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17117                + " ordered=" + ordered + " userid=" + userId);
17118        if ((resultTo != null) && !ordered) {
17119            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17120        }
17121
17122        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17123                ALLOW_NON_FULL, "broadcast", callerPackage);
17124
17125        // Make sure that the user who is receiving this broadcast is running.
17126        // If not, we will just skip it. Make an exception for shutdown broadcasts
17127        // and upgrade steps.
17128
17129        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17130            if ((callingUid != Process.SYSTEM_UID
17131                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17132                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17133                Slog.w(TAG, "Skipping broadcast of " + intent
17134                        + ": user " + userId + " is stopped");
17135                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17136            }
17137        }
17138
17139        BroadcastOptions brOptions = null;
17140        if (bOptions != null) {
17141            brOptions = new BroadcastOptions(bOptions);
17142            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17143                // See if the caller is allowed to do this.  Note we are checking against
17144                // the actual real caller (not whoever provided the operation as say a
17145                // PendingIntent), because that who is actually supplied the arguments.
17146                if (checkComponentPermission(
17147                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17148                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17149                        != PackageManager.PERMISSION_GRANTED) {
17150                    String msg = "Permission Denial: " + intent.getAction()
17151                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17152                            + ", uid=" + callingUid + ")"
17153                            + " requires "
17154                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17155                    Slog.w(TAG, msg);
17156                    throw new SecurityException(msg);
17157                }
17158            }
17159        }
17160
17161        // Verify that protected broadcasts are only being sent by system code,
17162        // and that system code is only sending protected broadcasts.
17163        final String action = intent.getAction();
17164        final boolean isProtectedBroadcast;
17165        try {
17166            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17167        } catch (RemoteException e) {
17168            Slog.w(TAG, "Remote exception", e);
17169            return ActivityManager.BROADCAST_SUCCESS;
17170        }
17171
17172        final boolean isCallerSystem;
17173        switch (UserHandle.getAppId(callingUid)) {
17174            case Process.ROOT_UID:
17175            case Process.SYSTEM_UID:
17176            case Process.PHONE_UID:
17177            case Process.BLUETOOTH_UID:
17178            case Process.NFC_UID:
17179                isCallerSystem = true;
17180                break;
17181            default:
17182                isCallerSystem = (callerApp != null) && callerApp.persistent;
17183                break;
17184        }
17185
17186        if (isCallerSystem) {
17187            if (isProtectedBroadcast
17188                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17189                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17190                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17191                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17192                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17193                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17194                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17195                // Broadcast is either protected, or it's a public action that
17196                // we've relaxed, so it's fine for system internals to send.
17197            } else {
17198                // The vast majority of broadcasts sent from system internals
17199                // should be protected to avoid security holes, so yell loudly
17200                // to ensure we examine these cases.
17201                Log.wtf(TAG, "Sending non-protected broadcast " + action
17202                        + " from system", new Throwable());
17203            }
17204
17205        } else {
17206            if (isProtectedBroadcast) {
17207                String msg = "Permission Denial: not allowed to send broadcast "
17208                        + action + " from pid="
17209                        + callingPid + ", uid=" + callingUid;
17210                Slog.w(TAG, msg);
17211                throw new SecurityException(msg);
17212
17213            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17214                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17215                // Special case for compatibility: we don't want apps to send this,
17216                // but historically it has not been protected and apps may be using it
17217                // to poke their own app widget.  So, instead of making it protected,
17218                // just limit it to the caller.
17219                if (callerPackage == null) {
17220                    String msg = "Permission Denial: not allowed to send broadcast "
17221                            + action + " from unknown caller.";
17222                    Slog.w(TAG, msg);
17223                    throw new SecurityException(msg);
17224                } else if (intent.getComponent() != null) {
17225                    // They are good enough to send to an explicit component...  verify
17226                    // it is being sent to the calling app.
17227                    if (!intent.getComponent().getPackageName().equals(
17228                            callerPackage)) {
17229                        String msg = "Permission Denial: not allowed to send broadcast "
17230                                + action + " to "
17231                                + intent.getComponent().getPackageName() + " from "
17232                                + callerPackage;
17233                        Slog.w(TAG, msg);
17234                        throw new SecurityException(msg);
17235                    }
17236                } else {
17237                    // Limit broadcast to their own package.
17238                    intent.setPackage(callerPackage);
17239                }
17240            }
17241        }
17242
17243        if (action != null) {
17244            switch (action) {
17245                case Intent.ACTION_UID_REMOVED:
17246                case Intent.ACTION_PACKAGE_REMOVED:
17247                case Intent.ACTION_PACKAGE_CHANGED:
17248                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17249                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17250                case Intent.ACTION_PACKAGES_SUSPENDED:
17251                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17252                    // Handle special intents: if this broadcast is from the package
17253                    // manager about a package being removed, we need to remove all of
17254                    // its activities from the history stack.
17255                    if (checkComponentPermission(
17256                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17257                            callingPid, callingUid, -1, true)
17258                            != PackageManager.PERMISSION_GRANTED) {
17259                        String msg = "Permission Denial: " + intent.getAction()
17260                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17261                                + ", uid=" + callingUid + ")"
17262                                + " requires "
17263                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17264                        Slog.w(TAG, msg);
17265                        throw new SecurityException(msg);
17266                    }
17267                    switch (action) {
17268                        case Intent.ACTION_UID_REMOVED:
17269                            final Bundle intentExtras = intent.getExtras();
17270                            final int uid = intentExtras != null
17271                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17272                            if (uid >= 0) {
17273                                mBatteryStatsService.removeUid(uid);
17274                                mAppOpsService.uidRemoved(uid);
17275                            }
17276                            break;
17277                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17278                            // If resources are unavailable just force stop all those packages
17279                            // and flush the attribute cache as well.
17280                            String list[] =
17281                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17282                            if (list != null && list.length > 0) {
17283                                for (int i = 0; i < list.length; i++) {
17284                                    forceStopPackageLocked(list[i], -1, false, true, true,
17285                                            false, false, userId, "storage unmount");
17286                                }
17287                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17288                                sendPackageBroadcastLocked(
17289                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17290                                        userId);
17291                            }
17292                            break;
17293                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17294                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17295                            break;
17296                        case Intent.ACTION_PACKAGE_REMOVED:
17297                        case Intent.ACTION_PACKAGE_CHANGED:
17298                            Uri data = intent.getData();
17299                            String ssp;
17300                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17301                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17302                                final boolean replacing =
17303                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17304                                final boolean killProcess =
17305                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17306                                final boolean fullUninstall = removed && !replacing;
17307                                if (killProcess) {
17308                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17309                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17310                                            false, true, true, false, fullUninstall, userId,
17311                                            removed ? "pkg removed" : "pkg changed");
17312                                }
17313                                if (removed) {
17314                                    final int cmd = killProcess
17315                                            ? IApplicationThread.PACKAGE_REMOVED
17316                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17317                                    sendPackageBroadcastLocked(cmd,
17318                                            new String[] {ssp}, userId);
17319                                    if (fullUninstall) {
17320                                        mAppOpsService.packageRemoved(
17321                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17322
17323                                        // Remove all permissions granted from/to this package
17324                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17325
17326                                        removeTasksByPackageNameLocked(ssp, userId);
17327                                        mBatteryStatsService.notePackageUninstalled(ssp);
17328                                    }
17329                                } else {
17330                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17331                                            intent.getStringArrayExtra(
17332                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17333                                }
17334                            }
17335                            break;
17336                        case Intent.ACTION_PACKAGES_SUSPENDED:
17337                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17338                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17339                                    intent.getAction());
17340                            final String[] packageNames = intent.getStringArrayExtra(
17341                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17342                            final int userHandle = intent.getIntExtra(
17343                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17344
17345                            synchronized(ActivityManagerService.this) {
17346                                mRecentTasks.onPackagesSuspendedChanged(
17347                                        packageNames, suspended, userHandle);
17348                            }
17349                            break;
17350                    }
17351                    break;
17352                case Intent.ACTION_PACKAGE_REPLACED:
17353                {
17354                    final Uri data = intent.getData();
17355                    final String ssp;
17356                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17357                        final ApplicationInfo aInfo =
17358                                getPackageManagerInternalLocked().getApplicationInfo(
17359                                        ssp,
17360                                        userId);
17361                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17362                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17363                                new String[] {ssp}, userId);
17364                    }
17365                    break;
17366                }
17367                case Intent.ACTION_PACKAGE_ADDED:
17368                {
17369                    // Special case for adding a package: by default turn on compatibility mode.
17370                    Uri data = intent.getData();
17371                    String ssp;
17372                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17373                        final boolean replacing =
17374                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17375                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17376
17377                        try {
17378                            ApplicationInfo ai = AppGlobals.getPackageManager().
17379                                    getApplicationInfo(ssp, 0, 0);
17380                            mBatteryStatsService.notePackageInstalled(ssp,
17381                                    ai != null ? ai.versionCode : 0);
17382                        } catch (RemoteException e) {
17383                        }
17384                    }
17385                    break;
17386                }
17387                case Intent.ACTION_TIMEZONE_CHANGED:
17388                    // If this is the time zone changed action, queue up a message that will reset
17389                    // the timezone of all currently running processes. This message will get
17390                    // queued up before the broadcast happens.
17391                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17392                    break;
17393                case Intent.ACTION_TIME_CHANGED:
17394                    // If the user set the time, let all running processes know.
17395                    final int is24Hour =
17396                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17397                                    : 0;
17398                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17399                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17400                    synchronized (stats) {
17401                        stats.noteCurrentTimeChangedLocked();
17402                    }
17403                    break;
17404                case Intent.ACTION_CLEAR_DNS_CACHE:
17405                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17406                    break;
17407                case Proxy.PROXY_CHANGE_ACTION:
17408                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17409                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17410                    break;
17411                case android.hardware.Camera.ACTION_NEW_PICTURE:
17412                case android.hardware.Camera.ACTION_NEW_VIDEO:
17413                    // These broadcasts are no longer allowed by the system, since they can
17414                    // cause significant thrashing at a crictical point (using the camera).
17415                    // Apps should use JobScehduler to monitor for media provider changes.
17416                    Slog.w(TAG, action + " no longer allowed; dropping from "
17417                            + UserHandle.formatUid(callingUid));
17418                    // Lie; we don't want to crash the app.
17419                    return ActivityManager.BROADCAST_SUCCESS;
17420            }
17421        }
17422
17423        // Add to the sticky list if requested.
17424        if (sticky) {
17425            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17426                    callingPid, callingUid)
17427                    != PackageManager.PERMISSION_GRANTED) {
17428                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17429                        + callingPid + ", uid=" + callingUid
17430                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17431                Slog.w(TAG, msg);
17432                throw new SecurityException(msg);
17433            }
17434            if (requiredPermissions != null && requiredPermissions.length > 0) {
17435                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17436                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17437                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17438            }
17439            if (intent.getComponent() != null) {
17440                throw new SecurityException(
17441                        "Sticky broadcasts can't target a specific component");
17442            }
17443            // We use userId directly here, since the "all" target is maintained
17444            // as a separate set of sticky broadcasts.
17445            if (userId != UserHandle.USER_ALL) {
17446                // But first, if this is not a broadcast to all users, then
17447                // make sure it doesn't conflict with an existing broadcast to
17448                // all users.
17449                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17450                        UserHandle.USER_ALL);
17451                if (stickies != null) {
17452                    ArrayList<Intent> list = stickies.get(intent.getAction());
17453                    if (list != null) {
17454                        int N = list.size();
17455                        int i;
17456                        for (i=0; i<N; i++) {
17457                            if (intent.filterEquals(list.get(i))) {
17458                                throw new IllegalArgumentException(
17459                                        "Sticky broadcast " + intent + " for user "
17460                                        + userId + " conflicts with existing global broadcast");
17461                            }
17462                        }
17463                    }
17464                }
17465            }
17466            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17467            if (stickies == null) {
17468                stickies = new ArrayMap<>();
17469                mStickyBroadcasts.put(userId, stickies);
17470            }
17471            ArrayList<Intent> list = stickies.get(intent.getAction());
17472            if (list == null) {
17473                list = new ArrayList<>();
17474                stickies.put(intent.getAction(), list);
17475            }
17476            final int stickiesCount = list.size();
17477            int i;
17478            for (i = 0; i < stickiesCount; i++) {
17479                if (intent.filterEquals(list.get(i))) {
17480                    // This sticky already exists, replace it.
17481                    list.set(i, new Intent(intent));
17482                    break;
17483                }
17484            }
17485            if (i >= stickiesCount) {
17486                list.add(new Intent(intent));
17487            }
17488        }
17489
17490        int[] users;
17491        if (userId == UserHandle.USER_ALL) {
17492            // Caller wants broadcast to go to all started users.
17493            users = mUserController.getStartedUserArrayLocked();
17494        } else {
17495            // Caller wants broadcast to go to one specific user.
17496            users = new int[] {userId};
17497        }
17498
17499        // Figure out who all will receive this broadcast.
17500        List receivers = null;
17501        List<BroadcastFilter> registeredReceivers = null;
17502        // Need to resolve the intent to interested receivers...
17503        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17504                 == 0) {
17505            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17506        }
17507        if (intent.getComponent() == null) {
17508            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17509                // Query one target user at a time, excluding shell-restricted users
17510                for (int i = 0; i < users.length; i++) {
17511                    if (mUserController.hasUserRestriction(
17512                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17513                        continue;
17514                    }
17515                    List<BroadcastFilter> registeredReceiversForUser =
17516                            mReceiverResolver.queryIntent(intent,
17517                                    resolvedType, false, users[i]);
17518                    if (registeredReceivers == null) {
17519                        registeredReceivers = registeredReceiversForUser;
17520                    } else if (registeredReceiversForUser != null) {
17521                        registeredReceivers.addAll(registeredReceiversForUser);
17522                    }
17523                }
17524            } else {
17525                registeredReceivers = mReceiverResolver.queryIntent(intent,
17526                        resolvedType, false, userId);
17527            }
17528        }
17529
17530        final boolean replacePending =
17531                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17532
17533        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17534                + " replacePending=" + replacePending);
17535
17536        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17537        if (!ordered && NR > 0) {
17538            // If we are not serializing this broadcast, then send the
17539            // registered receivers separately so they don't wait for the
17540            // components to be launched.
17541            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17542            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17543                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17544                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17545                    resultExtras, ordered, sticky, false, userId);
17546            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17547            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17548            if (!replaced) {
17549                queue.enqueueParallelBroadcastLocked(r);
17550                queue.scheduleBroadcastsLocked();
17551            }
17552            registeredReceivers = null;
17553            NR = 0;
17554        }
17555
17556        // Merge into one list.
17557        int ir = 0;
17558        if (receivers != null) {
17559            // A special case for PACKAGE_ADDED: do not allow the package
17560            // being added to see this broadcast.  This prevents them from
17561            // using this as a back door to get run as soon as they are
17562            // installed.  Maybe in the future we want to have a special install
17563            // broadcast or such for apps, but we'd like to deliberately make
17564            // this decision.
17565            String skipPackages[] = null;
17566            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17567                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17568                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17569                Uri data = intent.getData();
17570                if (data != null) {
17571                    String pkgName = data.getSchemeSpecificPart();
17572                    if (pkgName != null) {
17573                        skipPackages = new String[] { pkgName };
17574                    }
17575                }
17576            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17577                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17578            }
17579            if (skipPackages != null && (skipPackages.length > 0)) {
17580                for (String skipPackage : skipPackages) {
17581                    if (skipPackage != null) {
17582                        int NT = receivers.size();
17583                        for (int it=0; it<NT; it++) {
17584                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17585                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17586                                receivers.remove(it);
17587                                it--;
17588                                NT--;
17589                            }
17590                        }
17591                    }
17592                }
17593            }
17594
17595            int NT = receivers != null ? receivers.size() : 0;
17596            int it = 0;
17597            ResolveInfo curt = null;
17598            BroadcastFilter curr = null;
17599            while (it < NT && ir < NR) {
17600                if (curt == null) {
17601                    curt = (ResolveInfo)receivers.get(it);
17602                }
17603                if (curr == null) {
17604                    curr = registeredReceivers.get(ir);
17605                }
17606                if (curr.getPriority() >= curt.priority) {
17607                    // Insert this broadcast record into the final list.
17608                    receivers.add(it, curr);
17609                    ir++;
17610                    curr = null;
17611                    it++;
17612                    NT++;
17613                } else {
17614                    // Skip to the next ResolveInfo in the final list.
17615                    it++;
17616                    curt = null;
17617                }
17618            }
17619        }
17620        while (ir < NR) {
17621            if (receivers == null) {
17622                receivers = new ArrayList();
17623            }
17624            receivers.add(registeredReceivers.get(ir));
17625            ir++;
17626        }
17627
17628        if ((receivers != null && receivers.size() > 0)
17629                || resultTo != null) {
17630            BroadcastQueue queue = broadcastQueueForIntent(intent);
17631            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17632                    callerPackage, callingPid, callingUid, resolvedType,
17633                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17634                    resultData, resultExtras, ordered, sticky, false, userId);
17635
17636            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17637                    + ": prev had " + queue.mOrderedBroadcasts.size());
17638            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17639                    "Enqueueing broadcast " + r.intent.getAction());
17640
17641            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17642            if (!replaced) {
17643                queue.enqueueOrderedBroadcastLocked(r);
17644                queue.scheduleBroadcastsLocked();
17645            }
17646        }
17647
17648        return ActivityManager.BROADCAST_SUCCESS;
17649    }
17650
17651    final Intent verifyBroadcastLocked(Intent intent) {
17652        // Refuse possible leaked file descriptors
17653        if (intent != null && intent.hasFileDescriptors() == true) {
17654            throw new IllegalArgumentException("File descriptors passed in Intent");
17655        }
17656
17657        int flags = intent.getFlags();
17658
17659        if (!mProcessesReady) {
17660            // if the caller really truly claims to know what they're doing, go
17661            // ahead and allow the broadcast without launching any receivers
17662            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17663                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17664            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17665                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17666                        + " before boot completion");
17667                throw new IllegalStateException("Cannot broadcast before boot completed");
17668            }
17669        }
17670
17671        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17672            throw new IllegalArgumentException(
17673                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17674        }
17675
17676        return intent;
17677    }
17678
17679    public final int broadcastIntent(IApplicationThread caller,
17680            Intent intent, String resolvedType, IIntentReceiver resultTo,
17681            int resultCode, String resultData, Bundle resultExtras,
17682            String[] requiredPermissions, int appOp, Bundle bOptions,
17683            boolean serialized, boolean sticky, int userId) {
17684        enforceNotIsolatedCaller("broadcastIntent");
17685        synchronized(this) {
17686            intent = verifyBroadcastLocked(intent);
17687
17688            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17689            final int callingPid = Binder.getCallingPid();
17690            final int callingUid = Binder.getCallingUid();
17691            final long origId = Binder.clearCallingIdentity();
17692            int res = broadcastIntentLocked(callerApp,
17693                    callerApp != null ? callerApp.info.packageName : null,
17694                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17695                    requiredPermissions, appOp, bOptions, serialized, sticky,
17696                    callingPid, callingUid, userId);
17697            Binder.restoreCallingIdentity(origId);
17698            return res;
17699        }
17700    }
17701
17702
17703    int broadcastIntentInPackage(String packageName, int uid,
17704            Intent intent, String resolvedType, IIntentReceiver resultTo,
17705            int resultCode, String resultData, Bundle resultExtras,
17706            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17707            int userId) {
17708        synchronized(this) {
17709            intent = verifyBroadcastLocked(intent);
17710
17711            final long origId = Binder.clearCallingIdentity();
17712            String[] requiredPermissions = requiredPermission == null ? null
17713                    : new String[] {requiredPermission};
17714            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17715                    resultTo, resultCode, resultData, resultExtras,
17716                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17717                    sticky, -1, uid, userId);
17718            Binder.restoreCallingIdentity(origId);
17719            return res;
17720        }
17721    }
17722
17723    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17724        // Refuse possible leaked file descriptors
17725        if (intent != null && intent.hasFileDescriptors() == true) {
17726            throw new IllegalArgumentException("File descriptors passed in Intent");
17727        }
17728
17729        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17730                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17731
17732        synchronized(this) {
17733            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17734                    != PackageManager.PERMISSION_GRANTED) {
17735                String msg = "Permission Denial: unbroadcastIntent() from pid="
17736                        + Binder.getCallingPid()
17737                        + ", uid=" + Binder.getCallingUid()
17738                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17739                Slog.w(TAG, msg);
17740                throw new SecurityException(msg);
17741            }
17742            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17743            if (stickies != null) {
17744                ArrayList<Intent> list = stickies.get(intent.getAction());
17745                if (list != null) {
17746                    int N = list.size();
17747                    int i;
17748                    for (i=0; i<N; i++) {
17749                        if (intent.filterEquals(list.get(i))) {
17750                            list.remove(i);
17751                            break;
17752                        }
17753                    }
17754                    if (list.size() <= 0) {
17755                        stickies.remove(intent.getAction());
17756                    }
17757                }
17758                if (stickies.size() <= 0) {
17759                    mStickyBroadcasts.remove(userId);
17760                }
17761            }
17762        }
17763    }
17764
17765    void backgroundServicesFinishedLocked(int userId) {
17766        for (BroadcastQueue queue : mBroadcastQueues) {
17767            queue.backgroundServicesFinishedLocked(userId);
17768        }
17769    }
17770
17771    public void finishReceiver(IBinder who, int resultCode, String resultData,
17772            Bundle resultExtras, boolean resultAbort, int flags) {
17773        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17774
17775        // Refuse possible leaked file descriptors
17776        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17777            throw new IllegalArgumentException("File descriptors passed in Bundle");
17778        }
17779
17780        final long origId = Binder.clearCallingIdentity();
17781        try {
17782            boolean doNext = false;
17783            BroadcastRecord r;
17784
17785            synchronized(this) {
17786                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17787                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17788                r = queue.getMatchingOrderedReceiver(who);
17789                if (r != null) {
17790                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17791                        resultData, resultExtras, resultAbort, true);
17792                }
17793            }
17794
17795            if (doNext) {
17796                r.queue.processNextBroadcast(false);
17797            }
17798            trimApplications();
17799        } finally {
17800            Binder.restoreCallingIdentity(origId);
17801        }
17802    }
17803
17804    // =========================================================
17805    // INSTRUMENTATION
17806    // =========================================================
17807
17808    public boolean startInstrumentation(ComponentName className,
17809            String profileFile, int flags, Bundle arguments,
17810            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17811            int userId, String abiOverride) {
17812        enforceNotIsolatedCaller("startInstrumentation");
17813        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17814                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17815        // Refuse possible leaked file descriptors
17816        if (arguments != null && arguments.hasFileDescriptors()) {
17817            throw new IllegalArgumentException("File descriptors passed in Bundle");
17818        }
17819
17820        synchronized(this) {
17821            InstrumentationInfo ii = null;
17822            ApplicationInfo ai = null;
17823            try {
17824                ii = mContext.getPackageManager().getInstrumentationInfo(
17825                    className, STOCK_PM_FLAGS);
17826                ai = AppGlobals.getPackageManager().getApplicationInfo(
17827                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17828            } catch (PackageManager.NameNotFoundException e) {
17829            } catch (RemoteException e) {
17830            }
17831            if (ii == null) {
17832                reportStartInstrumentationFailureLocked(watcher, className,
17833                        "Unable to find instrumentation info for: " + className);
17834                return false;
17835            }
17836            if (ai == null) {
17837                reportStartInstrumentationFailureLocked(watcher, className,
17838                        "Unable to find instrumentation target package: " + ii.targetPackage);
17839                return false;
17840            }
17841            if (!ai.hasCode()) {
17842                reportStartInstrumentationFailureLocked(watcher, className,
17843                        "Instrumentation target has no code: " + ii.targetPackage);
17844                return false;
17845            }
17846
17847            int match = mContext.getPackageManager().checkSignatures(
17848                    ii.targetPackage, ii.packageName);
17849            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17850                String msg = "Permission Denial: starting instrumentation "
17851                        + className + " from pid="
17852                        + Binder.getCallingPid()
17853                        + ", uid=" + Binder.getCallingPid()
17854                        + " not allowed because package " + ii.packageName
17855                        + " does not have a signature matching the target "
17856                        + ii.targetPackage;
17857                reportStartInstrumentationFailureLocked(watcher, className, msg);
17858                throw new SecurityException(msg);
17859            }
17860
17861            final long origId = Binder.clearCallingIdentity();
17862            // Instrumentation can kill and relaunch even persistent processes
17863            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17864                    "start instr");
17865            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17866            app.instrumentationClass = className;
17867            app.instrumentationInfo = ai;
17868            app.instrumentationProfileFile = profileFile;
17869            app.instrumentationArguments = arguments;
17870            app.instrumentationWatcher = watcher;
17871            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17872            app.instrumentationResultClass = className;
17873            Binder.restoreCallingIdentity(origId);
17874        }
17875
17876        return true;
17877    }
17878
17879    /**
17880     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17881     * error to the logs, but if somebody is watching, send the report there too.  This enables
17882     * the "am" command to report errors with more information.
17883     *
17884     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17885     * @param cn The component name of the instrumentation.
17886     * @param report The error report.
17887     */
17888    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17889            ComponentName cn, String report) {
17890        Slog.w(TAG, report);
17891        if (watcher != null) {
17892            Bundle results = new Bundle();
17893            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17894            results.putString("Error", report);
17895            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17896        }
17897    }
17898
17899    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17900        if (app.instrumentationWatcher != null) {
17901            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17902                    app.instrumentationClass, resultCode, results);
17903        }
17904
17905        // Can't call out of the system process with a lock held, so post a message.
17906        if (app.instrumentationUiAutomationConnection != null) {
17907            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17908                    app.instrumentationUiAutomationConnection).sendToTarget();
17909        }
17910
17911        app.instrumentationWatcher = null;
17912        app.instrumentationUiAutomationConnection = null;
17913        app.instrumentationClass = null;
17914        app.instrumentationInfo = null;
17915        app.instrumentationProfileFile = null;
17916        app.instrumentationArguments = null;
17917
17918        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17919                "finished inst");
17920    }
17921
17922    public void finishInstrumentation(IApplicationThread target,
17923            int resultCode, Bundle results) {
17924        int userId = UserHandle.getCallingUserId();
17925        // Refuse possible leaked file descriptors
17926        if (results != null && results.hasFileDescriptors()) {
17927            throw new IllegalArgumentException("File descriptors passed in Intent");
17928        }
17929
17930        synchronized(this) {
17931            ProcessRecord app = getRecordForAppLocked(target);
17932            if (app == null) {
17933                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17934                return;
17935            }
17936            final long origId = Binder.clearCallingIdentity();
17937            finishInstrumentationLocked(app, resultCode, results);
17938            Binder.restoreCallingIdentity(origId);
17939        }
17940    }
17941
17942    // =========================================================
17943    // CONFIGURATION
17944    // =========================================================
17945
17946    public ConfigurationInfo getDeviceConfigurationInfo() {
17947        ConfigurationInfo config = new ConfigurationInfo();
17948        synchronized (this) {
17949            config.reqTouchScreen = mConfiguration.touchscreen;
17950            config.reqKeyboardType = mConfiguration.keyboard;
17951            config.reqNavigation = mConfiguration.navigation;
17952            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17953                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17954                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17955            }
17956            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17957                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17958                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17959            }
17960            config.reqGlEsVersion = GL_ES_VERSION;
17961        }
17962        return config;
17963    }
17964
17965    ActivityStack getFocusedStack() {
17966        return mStackSupervisor.getFocusedStack();
17967    }
17968
17969    @Override
17970    public int getFocusedStackId() throws RemoteException {
17971        ActivityStack focusedStack = getFocusedStack();
17972        if (focusedStack != null) {
17973            return focusedStack.getStackId();
17974        }
17975        return -1;
17976    }
17977
17978    public Configuration getConfiguration() {
17979        Configuration ci;
17980        synchronized(this) {
17981            ci = new Configuration(mConfiguration);
17982            ci.userSetLocale = false;
17983        }
17984        return ci;
17985    }
17986
17987    @Override
17988    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17989        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17990        synchronized (this) {
17991            mSuppressResizeConfigChanges = suppress;
17992        }
17993    }
17994
17995    @Override
17996    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17997        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17998        if (fromStackId == HOME_STACK_ID) {
17999            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18000        }
18001        synchronized (this) {
18002            final long origId = Binder.clearCallingIdentity();
18003            try {
18004                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18005            } finally {
18006                Binder.restoreCallingIdentity(origId);
18007            }
18008        }
18009    }
18010
18011    @Override
18012    public void updatePersistentConfiguration(Configuration values) {
18013        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18014                "updateConfiguration()");
18015        enforceWriteSettingsPermission("updateConfiguration()");
18016        if (values == null) {
18017            throw new NullPointerException("Configuration must not be null");
18018        }
18019
18020        int userId = UserHandle.getCallingUserId();
18021
18022        synchronized(this) {
18023            final long origId = Binder.clearCallingIdentity();
18024            updateConfigurationLocked(values, null, false, true, userId);
18025            Binder.restoreCallingIdentity(origId);
18026        }
18027    }
18028
18029    private void updateFontScaleIfNeeded() {
18030        final int currentUserId;
18031        synchronized(this) {
18032            currentUserId = mUserController.getCurrentUserIdLocked();
18033        }
18034        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18035                FONT_SCALE, 1.0f, currentUserId);
18036        if (mConfiguration.fontScale != scaleFactor) {
18037            final Configuration configuration = mWindowManager.computeNewConfiguration();
18038            configuration.fontScale = scaleFactor;
18039            updatePersistentConfiguration(configuration);
18040        }
18041    }
18042
18043    private void enforceWriteSettingsPermission(String func) {
18044        int uid = Binder.getCallingUid();
18045        if (uid == Process.ROOT_UID) {
18046            return;
18047        }
18048
18049        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18050                Settings.getPackageNameForUid(mContext, uid), false)) {
18051            return;
18052        }
18053
18054        String msg = "Permission Denial: " + func + " from pid="
18055                + Binder.getCallingPid()
18056                + ", uid=" + uid
18057                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18058        Slog.w(TAG, msg);
18059        throw new SecurityException(msg);
18060    }
18061
18062    public void updateConfiguration(Configuration values) {
18063        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18064                "updateConfiguration()");
18065
18066        synchronized(this) {
18067            if (values == null && mWindowManager != null) {
18068                // sentinel: fetch the current configuration from the window manager
18069                values = mWindowManager.computeNewConfiguration();
18070            }
18071
18072            if (mWindowManager != null) {
18073                mProcessList.applyDisplaySize(mWindowManager);
18074            }
18075
18076            final long origId = Binder.clearCallingIdentity();
18077            if (values != null) {
18078                Settings.System.clearConfiguration(values);
18079            }
18080            updateConfigurationLocked(values, null, false);
18081            Binder.restoreCallingIdentity(origId);
18082        }
18083    }
18084
18085    void updateUserConfigurationLocked() {
18086        Configuration configuration = new Configuration(mConfiguration);
18087        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18088                mUserController.getCurrentUserIdLocked());
18089        updateConfigurationLocked(configuration, null, false);
18090    }
18091
18092    boolean updateConfigurationLocked(Configuration values,
18093            ActivityRecord starting, boolean initLocale) {
18094        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18095        return updateConfigurationLocked(values, starting, initLocale, false,
18096                UserHandle.USER_NULL);
18097    }
18098
18099    // To cache the list of supported system locales
18100    private String[] mSupportedSystemLocales = null;
18101
18102    /**
18103     * Do either or both things: (1) change the current configuration, and (2)
18104     * make sure the given activity is running with the (now) current
18105     * configuration.  Returns true if the activity has been left running, or
18106     * false if <var>starting</var> is being destroyed to match the new
18107     * configuration.
18108     *
18109     * @param userId is only used when persistent parameter is set to true to persist configuration
18110     *               for that particular user
18111     */
18112    private boolean updateConfigurationLocked(Configuration values,
18113            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18114        int changes = 0;
18115
18116        if (mWindowManager != null) {
18117            mWindowManager.deferSurfaceLayout();
18118        }
18119        if (values != null) {
18120            Configuration newConfig = new Configuration(mConfiguration);
18121            changes = newConfig.updateFrom(values);
18122            if (changes != 0) {
18123                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18124                        "Updating configuration to: " + values);
18125
18126                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18127
18128                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18129                    final Locale locale;
18130                    if (values.getLocales().size() == 1) {
18131                        // This is an optimization to avoid the JNI call when the result of
18132                        // getFirstMatch() does not depend on the supported locales.
18133                        locale = values.getLocales().get(0);
18134                    } else {
18135                        if (mSupportedSystemLocales == null) {
18136                            mSupportedSystemLocales =
18137                                    Resources.getSystem().getAssets().getLocales();
18138                        }
18139                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18140                    }
18141                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18142                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18143                            locale));
18144                }
18145
18146                mConfigurationSeq++;
18147                if (mConfigurationSeq <= 0) {
18148                    mConfigurationSeq = 1;
18149                }
18150                newConfig.seq = mConfigurationSeq;
18151                mConfiguration = newConfig;
18152                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18153                mUsageStatsService.reportConfigurationChange(newConfig,
18154                        mUserController.getCurrentUserIdLocked());
18155                //mUsageStatsService.noteStartConfig(newConfig);
18156
18157                final Configuration configCopy = new Configuration(mConfiguration);
18158
18159                // TODO: If our config changes, should we auto dismiss any currently
18160                // showing dialogs?
18161                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18162
18163                AttributeCache ac = AttributeCache.instance();
18164                if (ac != null) {
18165                    ac.updateConfiguration(configCopy);
18166                }
18167
18168                // Make sure all resources in our process are updated
18169                // right now, so that anyone who is going to retrieve
18170                // resource values after we return will be sure to get
18171                // the new ones.  This is especially important during
18172                // boot, where the first config change needs to guarantee
18173                // all resources have that config before following boot
18174                // code is executed.
18175                mSystemThread.applyConfigurationToResources(configCopy);
18176
18177                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18178                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18179                    msg.obj = new Configuration(configCopy);
18180                    msg.arg1 = userId;
18181                    mHandler.sendMessage(msg);
18182                }
18183
18184                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18185                if (isDensityChange) {
18186                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18187                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18188                }
18189
18190                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18191                    ProcessRecord app = mLruProcesses.get(i);
18192                    try {
18193                        if (app.thread != null) {
18194                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18195                                    + app.processName + " new config " + mConfiguration);
18196                            app.thread.scheduleConfigurationChanged(configCopy);
18197                        }
18198                    } catch (Exception e) {
18199                    }
18200                }
18201                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18202                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18203                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18204                        | Intent.FLAG_RECEIVER_FOREGROUND);
18205                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18206                        null, AppOpsManager.OP_NONE, null, false, false,
18207                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18208                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18209                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18210                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18211                    if (!mProcessesReady) {
18212                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18213                    }
18214                    broadcastIntentLocked(null, null, intent,
18215                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18216                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18217                }
18218            }
18219            // Update the configuration with WM first and check if any of the stacks need to be
18220            // resized due to the configuration change. If so, resize the stacks now and do any
18221            // relaunches if necessary. This way we don't need to relaunch again below in
18222            // ensureActivityConfigurationLocked().
18223            if (mWindowManager != null) {
18224                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18225                if (resizedStacks != null) {
18226                    for (int stackId : resizedStacks) {
18227                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18228                        mStackSupervisor.resizeStackLocked(
18229                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18230                    }
18231                }
18232            }
18233        }
18234
18235        boolean kept = true;
18236        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18237        // mainStack is null during startup.
18238        if (mainStack != null) {
18239            if (changes != 0 && starting == null) {
18240                // If the configuration changed, and the caller is not already
18241                // in the process of starting an activity, then find the top
18242                // activity to check if its configuration needs to change.
18243                starting = mainStack.topRunningActivityLocked();
18244            }
18245
18246            if (starting != null) {
18247                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18248                // And we need to make sure at this point that all other activities
18249                // are made visible with the correct configuration.
18250                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18251                        !PRESERVE_WINDOWS);
18252            }
18253        }
18254        if (mWindowManager != null) {
18255            mWindowManager.continueSurfaceLayout();
18256        }
18257        return kept;
18258    }
18259
18260    /**
18261     * Decide based on the configuration whether we should shouw the ANR,
18262     * crash, etc dialogs.  The idea is that if there is no affordnace to
18263     * press the on-screen buttons, we shouldn't show the dialog.
18264     *
18265     * A thought: SystemUI might also want to get told about this, the Power
18266     * dialog / global actions also might want different behaviors.
18267     */
18268    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18269        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18270                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18271                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18272        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18273                                    == Configuration.UI_MODE_TYPE_CAR);
18274        return inputMethodExists && uiIsNotCarType && !inVrMode;
18275    }
18276
18277    @Override
18278    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18279        synchronized (this) {
18280            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18281            if (srec != null) {
18282                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18283            }
18284        }
18285        return false;
18286    }
18287
18288    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18289            Intent resultData) {
18290
18291        synchronized (this) {
18292            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18293            if (r != null) {
18294                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18295            }
18296            return false;
18297        }
18298    }
18299
18300    public int getLaunchedFromUid(IBinder activityToken) {
18301        ActivityRecord srec;
18302        synchronized (this) {
18303            srec = ActivityRecord.forTokenLocked(activityToken);
18304        }
18305        if (srec == null) {
18306            return -1;
18307        }
18308        return srec.launchedFromUid;
18309    }
18310
18311    public String getLaunchedFromPackage(IBinder activityToken) {
18312        ActivityRecord srec;
18313        synchronized (this) {
18314            srec = ActivityRecord.forTokenLocked(activityToken);
18315        }
18316        if (srec == null) {
18317            return null;
18318        }
18319        return srec.launchedFromPackage;
18320    }
18321
18322    // =========================================================
18323    // LIFETIME MANAGEMENT
18324    // =========================================================
18325
18326    // Returns which broadcast queue the app is the current [or imminent] receiver
18327    // on, or 'null' if the app is not an active broadcast recipient.
18328    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18329        BroadcastRecord r = app.curReceiver;
18330        if (r != null) {
18331            return r.queue;
18332        }
18333
18334        // It's not the current receiver, but it might be starting up to become one
18335        synchronized (this) {
18336            for (BroadcastQueue queue : mBroadcastQueues) {
18337                r = queue.mPendingBroadcast;
18338                if (r != null && r.curApp == app) {
18339                    // found it; report which queue it's in
18340                    return queue;
18341                }
18342            }
18343        }
18344
18345        return null;
18346    }
18347
18348    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18349            int targetUid, ComponentName targetComponent, String targetProcess) {
18350        if (!mTrackingAssociations) {
18351            return null;
18352        }
18353        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18354                = mAssociations.get(targetUid);
18355        if (components == null) {
18356            components = new ArrayMap<>();
18357            mAssociations.put(targetUid, components);
18358        }
18359        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18360        if (sourceUids == null) {
18361            sourceUids = new SparseArray<>();
18362            components.put(targetComponent, sourceUids);
18363        }
18364        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18365        if (sourceProcesses == null) {
18366            sourceProcesses = new ArrayMap<>();
18367            sourceUids.put(sourceUid, sourceProcesses);
18368        }
18369        Association ass = sourceProcesses.get(sourceProcess);
18370        if (ass == null) {
18371            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18372                    targetProcess);
18373            sourceProcesses.put(sourceProcess, ass);
18374        }
18375        ass.mCount++;
18376        ass.mNesting++;
18377        if (ass.mNesting == 1) {
18378            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18379            ass.mLastState = sourceState;
18380        }
18381        return ass;
18382    }
18383
18384    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18385            ComponentName targetComponent) {
18386        if (!mTrackingAssociations) {
18387            return;
18388        }
18389        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18390                = mAssociations.get(targetUid);
18391        if (components == null) {
18392            return;
18393        }
18394        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18395        if (sourceUids == null) {
18396            return;
18397        }
18398        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18399        if (sourceProcesses == null) {
18400            return;
18401        }
18402        Association ass = sourceProcesses.get(sourceProcess);
18403        if (ass == null || ass.mNesting <= 0) {
18404            return;
18405        }
18406        ass.mNesting--;
18407        if (ass.mNesting == 0) {
18408            long uptime = SystemClock.uptimeMillis();
18409            ass.mTime += uptime - ass.mStartTime;
18410            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18411                    += uptime - ass.mLastStateUptime;
18412            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18413        }
18414    }
18415
18416    private void noteUidProcessState(final int uid, final int state) {
18417        mBatteryStatsService.noteUidProcessState(uid, state);
18418        if (mTrackingAssociations) {
18419            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18420                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18421                        = mAssociations.valueAt(i1);
18422                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18423                    SparseArray<ArrayMap<String, Association>> sourceUids
18424                            = targetComponents.valueAt(i2);
18425                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18426                    if (sourceProcesses != null) {
18427                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18428                            Association ass = sourceProcesses.valueAt(i4);
18429                            if (ass.mNesting >= 1) {
18430                                // currently associated
18431                                long uptime = SystemClock.uptimeMillis();
18432                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18433                                        += uptime - ass.mLastStateUptime;
18434                                ass.mLastState = state;
18435                                ass.mLastStateUptime = uptime;
18436                            }
18437                        }
18438                    }
18439                }
18440            }
18441        }
18442    }
18443
18444    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18445            boolean doingAll, long now) {
18446        if (mAdjSeq == app.adjSeq) {
18447            // This adjustment has already been computed.
18448            return app.curRawAdj;
18449        }
18450
18451        if (app.thread == null) {
18452            app.adjSeq = mAdjSeq;
18453            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18454            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18455            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18456        }
18457
18458        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18459        app.adjSource = null;
18460        app.adjTarget = null;
18461        app.empty = false;
18462        app.cached = false;
18463
18464        final int activitiesSize = app.activities.size();
18465
18466        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18467            // The max adjustment doesn't allow this app to be anything
18468            // below foreground, so it is not worth doing work for it.
18469            app.adjType = "fixed";
18470            app.adjSeq = mAdjSeq;
18471            app.curRawAdj = app.maxAdj;
18472            app.foregroundActivities = false;
18473            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18474            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18475            // System processes can do UI, and when they do we want to have
18476            // them trim their memory after the user leaves the UI.  To
18477            // facilitate this, here we need to determine whether or not it
18478            // is currently showing UI.
18479            app.systemNoUi = true;
18480            if (app == TOP_APP) {
18481                app.systemNoUi = false;
18482            } else if (activitiesSize > 0) {
18483                for (int j = 0; j < activitiesSize; j++) {
18484                    final ActivityRecord r = app.activities.get(j);
18485                    if (r.visible) {
18486                        app.systemNoUi = false;
18487                    }
18488                }
18489            }
18490            if (!app.systemNoUi) {
18491                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18492            }
18493            return (app.curAdj=app.maxAdj);
18494        }
18495
18496        app.systemNoUi = false;
18497
18498        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18499
18500        // Determine the importance of the process, starting with most
18501        // important to least, and assign an appropriate OOM adjustment.
18502        int adj;
18503        int schedGroup;
18504        int procState;
18505        boolean foregroundActivities = false;
18506        BroadcastQueue queue;
18507        if (app == TOP_APP) {
18508            // The last app on the list is the foreground app.
18509            adj = ProcessList.FOREGROUND_APP_ADJ;
18510            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18511            app.adjType = "top-activity";
18512            foregroundActivities = true;
18513            procState = PROCESS_STATE_CUR_TOP;
18514        } else if (app.instrumentationClass != null) {
18515            // Don't want to kill running instrumentation.
18516            adj = ProcessList.FOREGROUND_APP_ADJ;
18517            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18518            app.adjType = "instrumentation";
18519            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18520        } else if ((queue = isReceivingBroadcast(app)) != null) {
18521            // An app that is currently receiving a broadcast also
18522            // counts as being in the foreground for OOM killer purposes.
18523            // It's placed in a sched group based on the nature of the
18524            // broadcast as reflected by which queue it's active in.
18525            adj = ProcessList.FOREGROUND_APP_ADJ;
18526            schedGroup = (queue == mFgBroadcastQueue)
18527                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18528            app.adjType = "broadcast";
18529            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18530        } else if (app.executingServices.size() > 0) {
18531            // An app that is currently executing a service callback also
18532            // counts as being in the foreground.
18533            adj = ProcessList.FOREGROUND_APP_ADJ;
18534            schedGroup = app.execServicesFg ?
18535                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18536            app.adjType = "exec-service";
18537            procState = ActivityManager.PROCESS_STATE_SERVICE;
18538            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18539        } else {
18540            // As far as we know the process is empty.  We may change our mind later.
18541            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18542            // At this point we don't actually know the adjustment.  Use the cached adj
18543            // value that the caller wants us to.
18544            adj = cachedAdj;
18545            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18546            app.cached = true;
18547            app.empty = true;
18548            app.adjType = "cch-empty";
18549        }
18550
18551        // Examine all activities if not already foreground.
18552        if (!foregroundActivities && activitiesSize > 0) {
18553            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18554            for (int j = 0; j < activitiesSize; j++) {
18555                final ActivityRecord r = app.activities.get(j);
18556                if (r.app != app) {
18557                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18558                            + " instead of expected " + app);
18559                    if (r.app == null || (r.app.uid == app.uid)) {
18560                        // Only fix things up when they look sane
18561                        r.app = app;
18562                    } else {
18563                        continue;
18564                    }
18565                }
18566                if (r.visible) {
18567                    // App has a visible activity; only upgrade adjustment.
18568                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18569                        adj = ProcessList.VISIBLE_APP_ADJ;
18570                        app.adjType = "visible";
18571                    }
18572                    if (procState > PROCESS_STATE_CUR_TOP) {
18573                        procState = PROCESS_STATE_CUR_TOP;
18574                    }
18575                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18576                    app.cached = false;
18577                    app.empty = false;
18578                    foregroundActivities = true;
18579                    if (r.task != null && minLayer > 0) {
18580                        final int layer = r.task.mLayerRank;
18581                        if (layer >= 0 && minLayer > layer) {
18582                            minLayer = layer;
18583                        }
18584                    }
18585                    break;
18586                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18587                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18588                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18589                        app.adjType = "pausing";
18590                    }
18591                    if (procState > PROCESS_STATE_CUR_TOP) {
18592                        procState = PROCESS_STATE_CUR_TOP;
18593                    }
18594                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18595                    app.cached = false;
18596                    app.empty = false;
18597                    foregroundActivities = true;
18598                } else if (r.state == ActivityState.STOPPING) {
18599                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18600                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18601                        app.adjType = "stopping";
18602                    }
18603                    // For the process state, we will at this point consider the
18604                    // process to be cached.  It will be cached either as an activity
18605                    // or empty depending on whether the activity is finishing.  We do
18606                    // this so that we can treat the process as cached for purposes of
18607                    // memory trimming (determing current memory level, trim command to
18608                    // send to process) since there can be an arbitrary number of stopping
18609                    // processes and they should soon all go into the cached state.
18610                    if (!r.finishing) {
18611                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18612                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18613                        }
18614                    }
18615                    app.cached = false;
18616                    app.empty = false;
18617                    foregroundActivities = true;
18618                } else {
18619                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18620                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18621                        app.adjType = "cch-act";
18622                    }
18623                }
18624            }
18625            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18626                adj += minLayer;
18627            }
18628        }
18629
18630        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18631                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18632            if (app.foregroundServices) {
18633                // The user is aware of this app, so make it visible.
18634                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18635                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18636                app.cached = false;
18637                app.adjType = "fg-service";
18638                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18639            } else if (app.forcingToForeground != null) {
18640                // The user is aware of this app, so make it visible.
18641                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18642                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18643                app.cached = false;
18644                app.adjType = "force-fg";
18645                app.adjSource = app.forcingToForeground;
18646                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18647            }
18648        }
18649
18650        if (app == mHeavyWeightProcess) {
18651            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18652                // We don't want to kill the current heavy-weight process.
18653                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18654                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18655                app.cached = false;
18656                app.adjType = "heavy";
18657            }
18658            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18659                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18660            }
18661        }
18662
18663        if (app == mHomeProcess) {
18664            if (adj > ProcessList.HOME_APP_ADJ) {
18665                // This process is hosting what we currently consider to be the
18666                // home app, so we don't want to let it go into the background.
18667                adj = ProcessList.HOME_APP_ADJ;
18668                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18669                app.cached = false;
18670                app.adjType = "home";
18671            }
18672            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18673                procState = ActivityManager.PROCESS_STATE_HOME;
18674            }
18675        }
18676
18677        if (app == mPreviousProcess && app.activities.size() > 0) {
18678            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18679                // This was the previous process that showed UI to the user.
18680                // We want to try to keep it around more aggressively, to give
18681                // a good experience around switching between two apps.
18682                adj = ProcessList.PREVIOUS_APP_ADJ;
18683                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18684                app.cached = false;
18685                app.adjType = "previous";
18686            }
18687            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18688                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18689            }
18690        }
18691
18692        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18693                + " reason=" + app.adjType);
18694
18695        // By default, we use the computed adjustment.  It may be changed if
18696        // there are applications dependent on our services or providers, but
18697        // this gives us a baseline and makes sure we don't get into an
18698        // infinite recursion.
18699        app.adjSeq = mAdjSeq;
18700        app.curRawAdj = adj;
18701        app.hasStartedServices = false;
18702
18703        if (mBackupTarget != null && app == mBackupTarget.app) {
18704            // If possible we want to avoid killing apps while they're being backed up
18705            if (adj > ProcessList.BACKUP_APP_ADJ) {
18706                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18707                adj = ProcessList.BACKUP_APP_ADJ;
18708                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18709                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18710                }
18711                app.adjType = "backup";
18712                app.cached = false;
18713            }
18714            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18715                procState = ActivityManager.PROCESS_STATE_BACKUP;
18716            }
18717        }
18718
18719        boolean mayBeTop = false;
18720
18721        for (int is = app.services.size()-1;
18722                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18723                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18724                        || procState > ActivityManager.PROCESS_STATE_TOP);
18725                is--) {
18726            ServiceRecord s = app.services.valueAt(is);
18727            if (s.startRequested) {
18728                app.hasStartedServices = true;
18729                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18730                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18731                }
18732                if (app.hasShownUi && app != mHomeProcess) {
18733                    // If this process has shown some UI, let it immediately
18734                    // go to the LRU list because it may be pretty heavy with
18735                    // UI stuff.  We'll tag it with a label just to help
18736                    // debug and understand what is going on.
18737                    if (adj > ProcessList.SERVICE_ADJ) {
18738                        app.adjType = "cch-started-ui-services";
18739                    }
18740                } else {
18741                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18742                        // This service has seen some activity within
18743                        // recent memory, so we will keep its process ahead
18744                        // of the background processes.
18745                        if (adj > ProcessList.SERVICE_ADJ) {
18746                            adj = ProcessList.SERVICE_ADJ;
18747                            app.adjType = "started-services";
18748                            app.cached = false;
18749                        }
18750                    }
18751                    // If we have let the service slide into the background
18752                    // state, still have some text describing what it is doing
18753                    // even though the service no longer has an impact.
18754                    if (adj > ProcessList.SERVICE_ADJ) {
18755                        app.adjType = "cch-started-services";
18756                    }
18757                }
18758            }
18759            for (int conni = s.connections.size()-1;
18760                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18761                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18762                            || procState > ActivityManager.PROCESS_STATE_TOP);
18763                    conni--) {
18764                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18765                for (int i = 0;
18766                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18767                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18768                                || procState > ActivityManager.PROCESS_STATE_TOP);
18769                        i++) {
18770                    // XXX should compute this based on the max of
18771                    // all connected clients.
18772                    ConnectionRecord cr = clist.get(i);
18773                    if (cr.binding.client == app) {
18774                        // Binding to ourself is not interesting.
18775                        continue;
18776                    }
18777                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18778                        ProcessRecord client = cr.binding.client;
18779                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18780                                TOP_APP, doingAll, now);
18781                        int clientProcState = client.curProcState;
18782                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18783                            // If the other app is cached for any reason, for purposes here
18784                            // we are going to consider it empty.  The specific cached state
18785                            // doesn't propagate except under certain conditions.
18786                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18787                        }
18788                        String adjType = null;
18789                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18790                            // Not doing bind OOM management, so treat
18791                            // this guy more like a started service.
18792                            if (app.hasShownUi && app != mHomeProcess) {
18793                                // If this process has shown some UI, let it immediately
18794                                // go to the LRU list because it may be pretty heavy with
18795                                // UI stuff.  We'll tag it with a label just to help
18796                                // debug and understand what is going on.
18797                                if (adj > clientAdj) {
18798                                    adjType = "cch-bound-ui-services";
18799                                }
18800                                app.cached = false;
18801                                clientAdj = adj;
18802                                clientProcState = procState;
18803                            } else {
18804                                if (now >= (s.lastActivity
18805                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18806                                    // This service has not seen activity within
18807                                    // recent memory, so allow it to drop to the
18808                                    // LRU list if there is no other reason to keep
18809                                    // it around.  We'll also tag it with a label just
18810                                    // to help debug and undertand what is going on.
18811                                    if (adj > clientAdj) {
18812                                        adjType = "cch-bound-services";
18813                                    }
18814                                    clientAdj = adj;
18815                                }
18816                            }
18817                        }
18818                        if (adj > clientAdj) {
18819                            // If this process has recently shown UI, and
18820                            // the process that is binding to it is less
18821                            // important than being visible, then we don't
18822                            // care about the binding as much as we care
18823                            // about letting this process get into the LRU
18824                            // list to be killed and restarted if needed for
18825                            // memory.
18826                            if (app.hasShownUi && app != mHomeProcess
18827                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18828                                adjType = "cch-bound-ui-services";
18829                            } else {
18830                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18831                                        |Context.BIND_IMPORTANT)) != 0) {
18832                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18833                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18834                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18835                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18836                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18837                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18838                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18839                                    adj = clientAdj;
18840                                } else {
18841                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18842                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18843                                    }
18844                                }
18845                                if (!client.cached) {
18846                                    app.cached = false;
18847                                }
18848                                adjType = "service";
18849                            }
18850                        }
18851                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18852                            // This will treat important bound services identically to
18853                            // the top app, which may behave differently than generic
18854                            // foreground work.
18855                            if (client.curSchedGroup > schedGroup) {
18856                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18857                                    schedGroup = client.curSchedGroup;
18858                                } else {
18859                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18860                                }
18861                            }
18862                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18863                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18864                                    // Special handling of clients who are in the top state.
18865                                    // We *may* want to consider this process to be in the
18866                                    // top state as well, but only if there is not another
18867                                    // reason for it to be running.  Being on the top is a
18868                                    // special state, meaning you are specifically running
18869                                    // for the current top app.  If the process is already
18870                                    // running in the background for some other reason, it
18871                                    // is more important to continue considering it to be
18872                                    // in the background state.
18873                                    mayBeTop = true;
18874                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18875                                } else {
18876                                    // Special handling for above-top states (persistent
18877                                    // processes).  These should not bring the current process
18878                                    // into the top state, since they are not on top.  Instead
18879                                    // give them the best state after that.
18880                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18881                                        clientProcState =
18882                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18883                                    } else if (mWakefulness
18884                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18885                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18886                                                    != 0) {
18887                                        clientProcState =
18888                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18889                                    } else {
18890                                        clientProcState =
18891                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18892                                    }
18893                                }
18894                            }
18895                        } else {
18896                            if (clientProcState <
18897                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18898                                clientProcState =
18899                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18900                            }
18901                        }
18902                        if (procState > clientProcState) {
18903                            procState = clientProcState;
18904                        }
18905                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18906                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18907                            app.pendingUiClean = true;
18908                        }
18909                        if (adjType != null) {
18910                            app.adjType = adjType;
18911                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18912                                    .REASON_SERVICE_IN_USE;
18913                            app.adjSource = cr.binding.client;
18914                            app.adjSourceProcState = clientProcState;
18915                            app.adjTarget = s.name;
18916                        }
18917                    }
18918                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18919                        app.treatLikeActivity = true;
18920                    }
18921                    final ActivityRecord a = cr.activity;
18922                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18923                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18924                            (a.visible || a.state == ActivityState.RESUMED ||
18925                             a.state == ActivityState.PAUSING)) {
18926                            adj = ProcessList.FOREGROUND_APP_ADJ;
18927                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18928                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18929                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18930                                } else {
18931                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18932                                }
18933                            }
18934                            app.cached = false;
18935                            app.adjType = "service";
18936                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18937                                    .REASON_SERVICE_IN_USE;
18938                            app.adjSource = a;
18939                            app.adjSourceProcState = procState;
18940                            app.adjTarget = s.name;
18941                        }
18942                    }
18943                }
18944            }
18945        }
18946
18947        for (int provi = app.pubProviders.size()-1;
18948                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18949                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18950                        || procState > ActivityManager.PROCESS_STATE_TOP);
18951                provi--) {
18952            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18953            for (int i = cpr.connections.size()-1;
18954                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18955                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18956                            || procState > ActivityManager.PROCESS_STATE_TOP);
18957                    i--) {
18958                ContentProviderConnection conn = cpr.connections.get(i);
18959                ProcessRecord client = conn.client;
18960                if (client == app) {
18961                    // Being our own client is not interesting.
18962                    continue;
18963                }
18964                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18965                int clientProcState = client.curProcState;
18966                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18967                    // If the other app is cached for any reason, for purposes here
18968                    // we are going to consider it empty.
18969                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18970                }
18971                if (adj > clientAdj) {
18972                    if (app.hasShownUi && app != mHomeProcess
18973                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18974                        app.adjType = "cch-ui-provider";
18975                    } else {
18976                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18977                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18978                        app.adjType = "provider";
18979                    }
18980                    app.cached &= client.cached;
18981                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18982                            .REASON_PROVIDER_IN_USE;
18983                    app.adjSource = client;
18984                    app.adjSourceProcState = clientProcState;
18985                    app.adjTarget = cpr.name;
18986                }
18987                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18988                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18989                        // Special handling of clients who are in the top state.
18990                        // We *may* want to consider this process to be in the
18991                        // top state as well, but only if there is not another
18992                        // reason for it to be running.  Being on the top is a
18993                        // special state, meaning you are specifically running
18994                        // for the current top app.  If the process is already
18995                        // running in the background for some other reason, it
18996                        // is more important to continue considering it to be
18997                        // in the background state.
18998                        mayBeTop = true;
18999                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19000                    } else {
19001                        // Special handling for above-top states (persistent
19002                        // processes).  These should not bring the current process
19003                        // into the top state, since they are not on top.  Instead
19004                        // give them the best state after that.
19005                        clientProcState =
19006                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19007                    }
19008                }
19009                if (procState > clientProcState) {
19010                    procState = clientProcState;
19011                }
19012                if (client.curSchedGroup > schedGroup) {
19013                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19014                }
19015            }
19016            // If the provider has external (non-framework) process
19017            // dependencies, ensure that its adjustment is at least
19018            // FOREGROUND_APP_ADJ.
19019            if (cpr.hasExternalProcessHandles()) {
19020                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19021                    adj = ProcessList.FOREGROUND_APP_ADJ;
19022                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19023                    app.cached = false;
19024                    app.adjType = "provider";
19025                    app.adjTarget = cpr.name;
19026                }
19027                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19028                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19029                }
19030            }
19031        }
19032
19033        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19034            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19035                adj = ProcessList.PREVIOUS_APP_ADJ;
19036                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19037                app.cached = false;
19038                app.adjType = "provider";
19039            }
19040            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19041                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19042            }
19043        }
19044
19045        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19046            // A client of one of our services or providers is in the top state.  We
19047            // *may* want to be in the top state, but not if we are already running in
19048            // the background for some other reason.  For the decision here, we are going
19049            // to pick out a few specific states that we want to remain in when a client
19050            // is top (states that tend to be longer-term) and otherwise allow it to go
19051            // to the top state.
19052            switch (procState) {
19053                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19054                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19055                case ActivityManager.PROCESS_STATE_SERVICE:
19056                    // These all are longer-term states, so pull them up to the top
19057                    // of the background states, but not all the way to the top state.
19058                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19059                    break;
19060                default:
19061                    // Otherwise, top is a better choice, so take it.
19062                    procState = ActivityManager.PROCESS_STATE_TOP;
19063                    break;
19064            }
19065        }
19066
19067        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19068            if (app.hasClientActivities) {
19069                // This is a cached process, but with client activities.  Mark it so.
19070                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19071                app.adjType = "cch-client-act";
19072            } else if (app.treatLikeActivity) {
19073                // This is a cached process, but somebody wants us to treat it like it has
19074                // an activity, okay!
19075                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19076                app.adjType = "cch-as-act";
19077            }
19078        }
19079
19080        if (adj == ProcessList.SERVICE_ADJ) {
19081            if (doingAll) {
19082                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19083                mNewNumServiceProcs++;
19084                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19085                if (!app.serviceb) {
19086                    // This service isn't far enough down on the LRU list to
19087                    // normally be a B service, but if we are low on RAM and it
19088                    // is large we want to force it down since we would prefer to
19089                    // keep launcher over it.
19090                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19091                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19092                        app.serviceHighRam = true;
19093                        app.serviceb = true;
19094                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19095                    } else {
19096                        mNewNumAServiceProcs++;
19097                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19098                    }
19099                } else {
19100                    app.serviceHighRam = false;
19101                }
19102            }
19103            if (app.serviceb) {
19104                adj = ProcessList.SERVICE_B_ADJ;
19105            }
19106        }
19107
19108        app.curRawAdj = adj;
19109
19110        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19111        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19112        if (adj > app.maxAdj) {
19113            adj = app.maxAdj;
19114            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19115                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19116            }
19117        }
19118
19119        // Do final modification to adj.  Everything we do between here and applying
19120        // the final setAdj must be done in this function, because we will also use
19121        // it when computing the final cached adj later.  Note that we don't need to
19122        // worry about this for max adj above, since max adj will always be used to
19123        // keep it out of the cached vaues.
19124        app.curAdj = app.modifyRawOomAdj(adj);
19125        app.curSchedGroup = schedGroup;
19126        app.curProcState = procState;
19127        app.foregroundActivities = foregroundActivities;
19128
19129        return app.curRawAdj;
19130    }
19131
19132    /**
19133     * Record new PSS sample for a process.
19134     */
19135    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19136            long now) {
19137        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19138                swapPss * 1024);
19139        proc.lastPssTime = now;
19140        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19141        if (DEBUG_PSS) Slog.d(TAG_PSS,
19142                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19143                + " state=" + ProcessList.makeProcStateString(procState));
19144        if (proc.initialIdlePss == 0) {
19145            proc.initialIdlePss = pss;
19146        }
19147        proc.lastPss = pss;
19148        proc.lastSwapPss = swapPss;
19149        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19150            proc.lastCachedPss = pss;
19151            proc.lastCachedSwapPss = swapPss;
19152        }
19153
19154        final SparseArray<Pair<Long, String>> watchUids
19155                = mMemWatchProcesses.getMap().get(proc.processName);
19156        Long check = null;
19157        if (watchUids != null) {
19158            Pair<Long, String> val = watchUids.get(proc.uid);
19159            if (val == null) {
19160                val = watchUids.get(0);
19161            }
19162            if (val != null) {
19163                check = val.first;
19164            }
19165        }
19166        if (check != null) {
19167            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19168                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19169                if (!isDebuggable) {
19170                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19171                        isDebuggable = true;
19172                    }
19173                }
19174                if (isDebuggable) {
19175                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19176                    final ProcessRecord myProc = proc;
19177                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19178                    mMemWatchDumpProcName = proc.processName;
19179                    mMemWatchDumpFile = heapdumpFile.toString();
19180                    mMemWatchDumpPid = proc.pid;
19181                    mMemWatchDumpUid = proc.uid;
19182                    BackgroundThread.getHandler().post(new Runnable() {
19183                        @Override
19184                        public void run() {
19185                            revokeUriPermission(ActivityThread.currentActivityThread()
19186                                            .getApplicationThread(),
19187                                    DumpHeapActivity.JAVA_URI,
19188                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19189                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19190                                    UserHandle.myUserId());
19191                            ParcelFileDescriptor fd = null;
19192                            try {
19193                                heapdumpFile.delete();
19194                                fd = ParcelFileDescriptor.open(heapdumpFile,
19195                                        ParcelFileDescriptor.MODE_CREATE |
19196                                                ParcelFileDescriptor.MODE_TRUNCATE |
19197                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19198                                                ParcelFileDescriptor.MODE_APPEND);
19199                                IApplicationThread thread = myProc.thread;
19200                                if (thread != null) {
19201                                    try {
19202                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19203                                                "Requesting dump heap from "
19204                                                + myProc + " to " + heapdumpFile);
19205                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19206                                    } catch (RemoteException e) {
19207                                    }
19208                                }
19209                            } catch (FileNotFoundException e) {
19210                                e.printStackTrace();
19211                            } finally {
19212                                if (fd != null) {
19213                                    try {
19214                                        fd.close();
19215                                    } catch (IOException e) {
19216                                    }
19217                                }
19218                            }
19219                        }
19220                    });
19221                } else {
19222                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19223                            + ", but debugging not enabled");
19224                }
19225            }
19226        }
19227    }
19228
19229    /**
19230     * Schedule PSS collection of a process.
19231     */
19232    void requestPssLocked(ProcessRecord proc, int procState) {
19233        if (mPendingPssProcesses.contains(proc)) {
19234            return;
19235        }
19236        if (mPendingPssProcesses.size() == 0) {
19237            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19238        }
19239        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19240        proc.pssProcState = procState;
19241        mPendingPssProcesses.add(proc);
19242    }
19243
19244    /**
19245     * Schedule PSS collection of all processes.
19246     */
19247    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19248        if (!always) {
19249            if (now < (mLastFullPssTime +
19250                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19251                return;
19252            }
19253        }
19254        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19255        mLastFullPssTime = now;
19256        mFullPssPending = true;
19257        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19258        mPendingPssProcesses.clear();
19259        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19260            ProcessRecord app = mLruProcesses.get(i);
19261            if (app.thread == null
19262                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19263                continue;
19264            }
19265            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19266                app.pssProcState = app.setProcState;
19267                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19268                        mTestPssMode, isSleeping(), now);
19269                mPendingPssProcesses.add(app);
19270            }
19271        }
19272        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19273    }
19274
19275    public void setTestPssMode(boolean enabled) {
19276        synchronized (this) {
19277            mTestPssMode = enabled;
19278            if (enabled) {
19279                // Whenever we enable the mode, we want to take a snapshot all of current
19280                // process mem use.
19281                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19282            }
19283        }
19284    }
19285
19286    /**
19287     * Ask a given process to GC right now.
19288     */
19289    final void performAppGcLocked(ProcessRecord app) {
19290        try {
19291            app.lastRequestedGc = SystemClock.uptimeMillis();
19292            if (app.thread != null) {
19293                if (app.reportLowMemory) {
19294                    app.reportLowMemory = false;
19295                    app.thread.scheduleLowMemory();
19296                } else {
19297                    app.thread.processInBackground();
19298                }
19299            }
19300        } catch (Exception e) {
19301            // whatever.
19302        }
19303    }
19304
19305    /**
19306     * Returns true if things are idle enough to perform GCs.
19307     */
19308    private final boolean canGcNowLocked() {
19309        boolean processingBroadcasts = false;
19310        for (BroadcastQueue q : mBroadcastQueues) {
19311            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19312                processingBroadcasts = true;
19313            }
19314        }
19315        return !processingBroadcasts
19316                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19317    }
19318
19319    /**
19320     * Perform GCs on all processes that are waiting for it, but only
19321     * if things are idle.
19322     */
19323    final void performAppGcsLocked() {
19324        final int N = mProcessesToGc.size();
19325        if (N <= 0) {
19326            return;
19327        }
19328        if (canGcNowLocked()) {
19329            while (mProcessesToGc.size() > 0) {
19330                ProcessRecord proc = mProcessesToGc.remove(0);
19331                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19332                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19333                            <= SystemClock.uptimeMillis()) {
19334                        // To avoid spamming the system, we will GC processes one
19335                        // at a time, waiting a few seconds between each.
19336                        performAppGcLocked(proc);
19337                        scheduleAppGcsLocked();
19338                        return;
19339                    } else {
19340                        // It hasn't been long enough since we last GCed this
19341                        // process...  put it in the list to wait for its time.
19342                        addProcessToGcListLocked(proc);
19343                        break;
19344                    }
19345                }
19346            }
19347
19348            scheduleAppGcsLocked();
19349        }
19350    }
19351
19352    /**
19353     * If all looks good, perform GCs on all processes waiting for them.
19354     */
19355    final void performAppGcsIfAppropriateLocked() {
19356        if (canGcNowLocked()) {
19357            performAppGcsLocked();
19358            return;
19359        }
19360        // Still not idle, wait some more.
19361        scheduleAppGcsLocked();
19362    }
19363
19364    /**
19365     * Schedule the execution of all pending app GCs.
19366     */
19367    final void scheduleAppGcsLocked() {
19368        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19369
19370        if (mProcessesToGc.size() > 0) {
19371            // Schedule a GC for the time to the next process.
19372            ProcessRecord proc = mProcessesToGc.get(0);
19373            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19374
19375            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19376            long now = SystemClock.uptimeMillis();
19377            if (when < (now+GC_TIMEOUT)) {
19378                when = now + GC_TIMEOUT;
19379            }
19380            mHandler.sendMessageAtTime(msg, when);
19381        }
19382    }
19383
19384    /**
19385     * Add a process to the array of processes waiting to be GCed.  Keeps the
19386     * list in sorted order by the last GC time.  The process can't already be
19387     * on the list.
19388     */
19389    final void addProcessToGcListLocked(ProcessRecord proc) {
19390        boolean added = false;
19391        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19392            if (mProcessesToGc.get(i).lastRequestedGc <
19393                    proc.lastRequestedGc) {
19394                added = true;
19395                mProcessesToGc.add(i+1, proc);
19396                break;
19397            }
19398        }
19399        if (!added) {
19400            mProcessesToGc.add(0, proc);
19401        }
19402    }
19403
19404    /**
19405     * Set up to ask a process to GC itself.  This will either do it
19406     * immediately, or put it on the list of processes to gc the next
19407     * time things are idle.
19408     */
19409    final void scheduleAppGcLocked(ProcessRecord app) {
19410        long now = SystemClock.uptimeMillis();
19411        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19412            return;
19413        }
19414        if (!mProcessesToGc.contains(app)) {
19415            addProcessToGcListLocked(app);
19416            scheduleAppGcsLocked();
19417        }
19418    }
19419
19420    final void checkExcessivePowerUsageLocked(boolean doKills) {
19421        updateCpuStatsNow();
19422
19423        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19424        boolean doWakeKills = doKills;
19425        boolean doCpuKills = doKills;
19426        if (mLastPowerCheckRealtime == 0) {
19427            doWakeKills = false;
19428        }
19429        if (mLastPowerCheckUptime == 0) {
19430            doCpuKills = false;
19431        }
19432        if (stats.isScreenOn()) {
19433            doWakeKills = false;
19434        }
19435        final long curRealtime = SystemClock.elapsedRealtime();
19436        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19437        final long curUptime = SystemClock.uptimeMillis();
19438        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19439        mLastPowerCheckRealtime = curRealtime;
19440        mLastPowerCheckUptime = curUptime;
19441        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19442            doWakeKills = false;
19443        }
19444        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19445            doCpuKills = false;
19446        }
19447        int i = mLruProcesses.size();
19448        while (i > 0) {
19449            i--;
19450            ProcessRecord app = mLruProcesses.get(i);
19451            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19452                long wtime;
19453                synchronized (stats) {
19454                    wtime = stats.getProcessWakeTime(app.info.uid,
19455                            app.pid, curRealtime);
19456                }
19457                long wtimeUsed = wtime - app.lastWakeTime;
19458                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19459                if (DEBUG_POWER) {
19460                    StringBuilder sb = new StringBuilder(128);
19461                    sb.append("Wake for ");
19462                    app.toShortString(sb);
19463                    sb.append(": over ");
19464                    TimeUtils.formatDuration(realtimeSince, sb);
19465                    sb.append(" used ");
19466                    TimeUtils.formatDuration(wtimeUsed, sb);
19467                    sb.append(" (");
19468                    sb.append((wtimeUsed*100)/realtimeSince);
19469                    sb.append("%)");
19470                    Slog.i(TAG_POWER, sb.toString());
19471                    sb.setLength(0);
19472                    sb.append("CPU for ");
19473                    app.toShortString(sb);
19474                    sb.append(": over ");
19475                    TimeUtils.formatDuration(uptimeSince, sb);
19476                    sb.append(" used ");
19477                    TimeUtils.formatDuration(cputimeUsed, sb);
19478                    sb.append(" (");
19479                    sb.append((cputimeUsed*100)/uptimeSince);
19480                    sb.append("%)");
19481                    Slog.i(TAG_POWER, sb.toString());
19482                }
19483                // If a process has held a wake lock for more
19484                // than 50% of the time during this period,
19485                // that sounds bad.  Kill!
19486                if (doWakeKills && realtimeSince > 0
19487                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19488                    synchronized (stats) {
19489                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19490                                realtimeSince, wtimeUsed);
19491                    }
19492                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19493                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19494                } else if (doCpuKills && uptimeSince > 0
19495                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19496                    synchronized (stats) {
19497                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19498                                uptimeSince, cputimeUsed);
19499                    }
19500                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19501                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19502                } else {
19503                    app.lastWakeTime = wtime;
19504                    app.lastCpuTime = app.curCpuTime;
19505                }
19506            }
19507        }
19508    }
19509
19510    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19511            long nowElapsed) {
19512        boolean success = true;
19513
19514        if (app.curRawAdj != app.setRawAdj) {
19515            app.setRawAdj = app.curRawAdj;
19516        }
19517
19518        int changes = 0;
19519
19520        if (app.curAdj != app.setAdj) {
19521            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19522            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19523                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19524                    + app.adjType);
19525            app.setAdj = app.curAdj;
19526        }
19527
19528        if (app.setSchedGroup != app.curSchedGroup) {
19529            app.setSchedGroup = app.curSchedGroup;
19530            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19531                    "Setting sched group of " + app.processName
19532                    + " to " + app.curSchedGroup);
19533            if (app.waitingToKill != null && app.curReceiver == null
19534                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19535                app.kill(app.waitingToKill, true);
19536                success = false;
19537            } else {
19538                int processGroup;
19539                switch (app.curSchedGroup) {
19540                    case ProcessList.SCHED_GROUP_BACKGROUND:
19541                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19542                        break;
19543                    case ProcessList.SCHED_GROUP_TOP_APP:
19544                        processGroup = Process.THREAD_GROUP_TOP_APP;
19545                        break;
19546                    default:
19547                        processGroup = Process.THREAD_GROUP_DEFAULT;
19548                        break;
19549                }
19550                if (true) {
19551                    long oldId = Binder.clearCallingIdentity();
19552                    try {
19553                        Process.setProcessGroup(app.pid, processGroup);
19554                    } catch (Exception e) {
19555                        Slog.w(TAG, "Failed setting process group of " + app.pid
19556                                + " to " + app.curSchedGroup);
19557                        e.printStackTrace();
19558                    } finally {
19559                        Binder.restoreCallingIdentity(oldId);
19560                    }
19561                } else {
19562                    if (app.thread != null) {
19563                        try {
19564                            app.thread.setSchedulingGroup(processGroup);
19565                        } catch (RemoteException e) {
19566                        }
19567                    }
19568                }
19569            }
19570        }
19571        if (app.repForegroundActivities != app.foregroundActivities) {
19572            app.repForegroundActivities = app.foregroundActivities;
19573            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19574        }
19575        if (app.repProcState != app.curProcState) {
19576            app.repProcState = app.curProcState;
19577            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19578            if (app.thread != null) {
19579                try {
19580                    if (false) {
19581                        //RuntimeException h = new RuntimeException("here");
19582                        Slog.i(TAG, "Sending new process state " + app.repProcState
19583                                + " to " + app /*, h*/);
19584                    }
19585                    app.thread.setProcessState(app.repProcState);
19586                } catch (RemoteException e) {
19587                }
19588            }
19589        }
19590        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19591                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19592            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19593                // Experimental code to more aggressively collect pss while
19594                // running test...  the problem is that this tends to collect
19595                // the data right when a process is transitioning between process
19596                // states, which well tend to give noisy data.
19597                long start = SystemClock.uptimeMillis();
19598                long pss = Debug.getPss(app.pid, mTmpLong, null);
19599                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19600                mPendingPssProcesses.remove(app);
19601                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19602                        + " to " + app.curProcState + ": "
19603                        + (SystemClock.uptimeMillis()-start) + "ms");
19604            }
19605            app.lastStateTime = now;
19606            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19607                    mTestPssMode, isSleeping(), now);
19608            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19609                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19610                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19611                    + (app.nextPssTime-now) + ": " + app);
19612        } else {
19613            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19614                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19615                    mTestPssMode)))) {
19616                requestPssLocked(app, app.setProcState);
19617                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19618                        mTestPssMode, isSleeping(), now);
19619            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19620                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19621        }
19622        if (app.setProcState != app.curProcState) {
19623            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19624                    "Proc state change of " + app.processName
19625                            + " to " + app.curProcState);
19626            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19627            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19628            if (setImportant && !curImportant) {
19629                // This app is no longer something we consider important enough to allow to
19630                // use arbitrary amounts of battery power.  Note
19631                // its current wake lock time to later know to kill it if
19632                // it is not behaving well.
19633                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19634                synchronized (stats) {
19635                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19636                            app.pid, nowElapsed);
19637                }
19638                app.lastCpuTime = app.curCpuTime;
19639
19640            }
19641            // Inform UsageStats of important process state change
19642            // Must be called before updating setProcState
19643            maybeUpdateUsageStatsLocked(app, nowElapsed);
19644
19645            app.setProcState = app.curProcState;
19646            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19647                app.notCachedSinceIdle = false;
19648            }
19649            if (!doingAll) {
19650                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19651            } else {
19652                app.procStateChanged = true;
19653            }
19654        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19655                > USAGE_STATS_INTERACTION_INTERVAL) {
19656            // For apps that sit around for a long time in the interactive state, we need
19657            // to report this at least once a day so they don't go idle.
19658            maybeUpdateUsageStatsLocked(app, nowElapsed);
19659        }
19660
19661        if (changes != 0) {
19662            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19663                    "Changes in " + app + ": " + changes);
19664            int i = mPendingProcessChanges.size()-1;
19665            ProcessChangeItem item = null;
19666            while (i >= 0) {
19667                item = mPendingProcessChanges.get(i);
19668                if (item.pid == app.pid) {
19669                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19670                            "Re-using existing item: " + item);
19671                    break;
19672                }
19673                i--;
19674            }
19675            if (i < 0) {
19676                // No existing item in pending changes; need a new one.
19677                final int NA = mAvailProcessChanges.size();
19678                if (NA > 0) {
19679                    item = mAvailProcessChanges.remove(NA-1);
19680                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19681                            "Retrieving available item: " + item);
19682                } else {
19683                    item = new ProcessChangeItem();
19684                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19685                            "Allocating new item: " + item);
19686                }
19687                item.changes = 0;
19688                item.pid = app.pid;
19689                item.uid = app.info.uid;
19690                if (mPendingProcessChanges.size() == 0) {
19691                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19692                            "*** Enqueueing dispatch processes changed!");
19693                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19694                }
19695                mPendingProcessChanges.add(item);
19696            }
19697            item.changes |= changes;
19698            item.processState = app.repProcState;
19699            item.foregroundActivities = app.repForegroundActivities;
19700            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19701                    "Item " + Integer.toHexString(System.identityHashCode(item))
19702                    + " " + app.toShortString() + ": changes=" + item.changes
19703                    + " procState=" + item.processState
19704                    + " foreground=" + item.foregroundActivities
19705                    + " type=" + app.adjType + " source=" + app.adjSource
19706                    + " target=" + app.adjTarget);
19707        }
19708
19709        return success;
19710    }
19711
19712    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19713        final UidRecord.ChangeItem pendingChange;
19714        if (uidRec == null || uidRec.pendingChange == null) {
19715            if (mPendingUidChanges.size() == 0) {
19716                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19717                        "*** Enqueueing dispatch uid changed!");
19718                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19719            }
19720            final int NA = mAvailUidChanges.size();
19721            if (NA > 0) {
19722                pendingChange = mAvailUidChanges.remove(NA-1);
19723                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19724                        "Retrieving available item: " + pendingChange);
19725            } else {
19726                pendingChange = new UidRecord.ChangeItem();
19727                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19728                        "Allocating new item: " + pendingChange);
19729            }
19730            if (uidRec != null) {
19731                uidRec.pendingChange = pendingChange;
19732                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19733                    // If this uid is going away, and we haven't yet reported it is gone,
19734                    // then do so now.
19735                    change = UidRecord.CHANGE_GONE_IDLE;
19736                }
19737            } else if (uid < 0) {
19738                throw new IllegalArgumentException("No UidRecord or uid");
19739            }
19740            pendingChange.uidRecord = uidRec;
19741            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19742            mPendingUidChanges.add(pendingChange);
19743        } else {
19744            pendingChange = uidRec.pendingChange;
19745            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19746                change = UidRecord.CHANGE_GONE_IDLE;
19747            }
19748        }
19749        pendingChange.change = change;
19750        pendingChange.processState = uidRec != null
19751                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19752    }
19753
19754    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19755            String authority) {
19756        if (app == null) return;
19757        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19758            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19759            if (userState == null) return;
19760            final long now = SystemClock.elapsedRealtime();
19761            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19762            if (lastReported == null || lastReported < now - 60 * 1000L) {
19763                mUsageStatsService.reportContentProviderUsage(
19764                        authority, providerPkgName, app.userId);
19765                userState.mProviderLastReportedFg.put(authority, now);
19766            }
19767        }
19768    }
19769
19770    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19771        if (DEBUG_USAGE_STATS) {
19772            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19773                    + "] state changes: old = " + app.setProcState + ", new = "
19774                    + app.curProcState);
19775        }
19776        if (mUsageStatsService == null) {
19777            return;
19778        }
19779        boolean isInteraction;
19780        // To avoid some abuse patterns, we are going to be careful about what we consider
19781        // to be an app interaction.  Being the top activity doesn't count while the display
19782        // is sleeping, nor do short foreground services.
19783        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19784            isInteraction = true;
19785            app.fgInteractionTime = 0;
19786        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19787            if (app.fgInteractionTime == 0) {
19788                app.fgInteractionTime = nowElapsed;
19789                isInteraction = false;
19790            } else {
19791                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19792            }
19793        } else {
19794            isInteraction = app.curProcState
19795                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19796            app.fgInteractionTime = 0;
19797        }
19798        if (isInteraction && (!app.reportedInteraction
19799                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19800            app.interactionEventTime = nowElapsed;
19801            String[] packages = app.getPackageList();
19802            if (packages != null) {
19803                for (int i = 0; i < packages.length; i++) {
19804                    mUsageStatsService.reportEvent(packages[i], app.userId,
19805                            UsageEvents.Event.SYSTEM_INTERACTION);
19806                }
19807            }
19808        }
19809        app.reportedInteraction = isInteraction;
19810        if (!isInteraction) {
19811            app.interactionEventTime = 0;
19812        }
19813    }
19814
19815    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19816        if (proc.thread != null) {
19817            if (proc.baseProcessTracker != null) {
19818                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19819            }
19820        }
19821    }
19822
19823    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19824            ProcessRecord TOP_APP, boolean doingAll, long now) {
19825        if (app.thread == null) {
19826            return false;
19827        }
19828
19829        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19830
19831        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19832    }
19833
19834    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19835            boolean oomAdj) {
19836        if (isForeground != proc.foregroundServices) {
19837            proc.foregroundServices = isForeground;
19838            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19839                    proc.info.uid);
19840            if (isForeground) {
19841                if (curProcs == null) {
19842                    curProcs = new ArrayList<ProcessRecord>();
19843                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19844                }
19845                if (!curProcs.contains(proc)) {
19846                    curProcs.add(proc);
19847                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19848                            proc.info.packageName, proc.info.uid);
19849                }
19850            } else {
19851                if (curProcs != null) {
19852                    if (curProcs.remove(proc)) {
19853                        mBatteryStatsService.noteEvent(
19854                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19855                                proc.info.packageName, proc.info.uid);
19856                        if (curProcs.size() <= 0) {
19857                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19858                        }
19859                    }
19860                }
19861            }
19862            if (oomAdj) {
19863                updateOomAdjLocked();
19864            }
19865        }
19866    }
19867
19868    private final ActivityRecord resumedAppLocked() {
19869        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19870        String pkg;
19871        int uid;
19872        if (act != null) {
19873            pkg = act.packageName;
19874            uid = act.info.applicationInfo.uid;
19875        } else {
19876            pkg = null;
19877            uid = -1;
19878        }
19879        // Has the UID or resumed package name changed?
19880        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19881                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19882            if (mCurResumedPackage != null) {
19883                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19884                        mCurResumedPackage, mCurResumedUid);
19885            }
19886            mCurResumedPackage = pkg;
19887            mCurResumedUid = uid;
19888            if (mCurResumedPackage != null) {
19889                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19890                        mCurResumedPackage, mCurResumedUid);
19891            }
19892        }
19893        return act;
19894    }
19895
19896    final boolean updateOomAdjLocked(ProcessRecord app) {
19897        final ActivityRecord TOP_ACT = resumedAppLocked();
19898        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19899        final boolean wasCached = app.cached;
19900
19901        mAdjSeq++;
19902
19903        // This is the desired cached adjusment we want to tell it to use.
19904        // If our app is currently cached, we know it, and that is it.  Otherwise,
19905        // we don't know it yet, and it needs to now be cached we will then
19906        // need to do a complete oom adj.
19907        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19908                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19909        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19910                SystemClock.uptimeMillis());
19911        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19912            // Changed to/from cached state, so apps after it in the LRU
19913            // list may also be changed.
19914            updateOomAdjLocked();
19915        }
19916        return success;
19917    }
19918
19919    final void updateOomAdjLocked() {
19920        final ActivityRecord TOP_ACT = resumedAppLocked();
19921        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19922        final long now = SystemClock.uptimeMillis();
19923        final long nowElapsed = SystemClock.elapsedRealtime();
19924        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19925        final int N = mLruProcesses.size();
19926
19927        if (false) {
19928            RuntimeException e = new RuntimeException();
19929            e.fillInStackTrace();
19930            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19931        }
19932
19933        // Reset state in all uid records.
19934        for (int i=mActiveUids.size()-1; i>=0; i--) {
19935            final UidRecord uidRec = mActiveUids.valueAt(i);
19936            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19937                    "Starting update of " + uidRec);
19938            uidRec.reset();
19939        }
19940
19941        mStackSupervisor.rankTaskLayersIfNeeded();
19942
19943        mAdjSeq++;
19944        mNewNumServiceProcs = 0;
19945        mNewNumAServiceProcs = 0;
19946
19947        final int emptyProcessLimit;
19948        final int cachedProcessLimit;
19949        if (mProcessLimit <= 0) {
19950            emptyProcessLimit = cachedProcessLimit = 0;
19951        } else if (mProcessLimit == 1) {
19952            emptyProcessLimit = 1;
19953            cachedProcessLimit = 0;
19954        } else {
19955            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19956            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19957        }
19958
19959        // Let's determine how many processes we have running vs.
19960        // how many slots we have for background processes; we may want
19961        // to put multiple processes in a slot of there are enough of
19962        // them.
19963        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19964                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19965        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19966        if (numEmptyProcs > cachedProcessLimit) {
19967            // If there are more empty processes than our limit on cached
19968            // processes, then use the cached process limit for the factor.
19969            // This ensures that the really old empty processes get pushed
19970            // down to the bottom, so if we are running low on memory we will
19971            // have a better chance at keeping around more cached processes
19972            // instead of a gazillion empty processes.
19973            numEmptyProcs = cachedProcessLimit;
19974        }
19975        int emptyFactor = numEmptyProcs/numSlots;
19976        if (emptyFactor < 1) emptyFactor = 1;
19977        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19978        if (cachedFactor < 1) cachedFactor = 1;
19979        int stepCached = 0;
19980        int stepEmpty = 0;
19981        int numCached = 0;
19982        int numEmpty = 0;
19983        int numTrimming = 0;
19984
19985        mNumNonCachedProcs = 0;
19986        mNumCachedHiddenProcs = 0;
19987
19988        // First update the OOM adjustment for each of the
19989        // application processes based on their current state.
19990        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19991        int nextCachedAdj = curCachedAdj+1;
19992        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19993        int nextEmptyAdj = curEmptyAdj+2;
19994        for (int i=N-1; i>=0; i--) {
19995            ProcessRecord app = mLruProcesses.get(i);
19996            if (!app.killedByAm && app.thread != null) {
19997                app.procStateChanged = false;
19998                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19999
20000                // If we haven't yet assigned the final cached adj
20001                // to the process, do that now.
20002                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20003                    switch (app.curProcState) {
20004                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20005                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20006                            // This process is a cached process holding activities...
20007                            // assign it the next cached value for that type, and then
20008                            // step that cached level.
20009                            app.curRawAdj = curCachedAdj;
20010                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20011                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20012                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20013                                    + ")");
20014                            if (curCachedAdj != nextCachedAdj) {
20015                                stepCached++;
20016                                if (stepCached >= cachedFactor) {
20017                                    stepCached = 0;
20018                                    curCachedAdj = nextCachedAdj;
20019                                    nextCachedAdj += 2;
20020                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20021                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20022                                    }
20023                                }
20024                            }
20025                            break;
20026                        default:
20027                            // For everything else, assign next empty cached process
20028                            // level and bump that up.  Note that this means that
20029                            // long-running services that have dropped down to the
20030                            // cached level will be treated as empty (since their process
20031                            // state is still as a service), which is what we want.
20032                            app.curRawAdj = curEmptyAdj;
20033                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20034                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20035                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20036                                    + ")");
20037                            if (curEmptyAdj != nextEmptyAdj) {
20038                                stepEmpty++;
20039                                if (stepEmpty >= emptyFactor) {
20040                                    stepEmpty = 0;
20041                                    curEmptyAdj = nextEmptyAdj;
20042                                    nextEmptyAdj += 2;
20043                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20044                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20045                                    }
20046                                }
20047                            }
20048                            break;
20049                    }
20050                }
20051
20052                applyOomAdjLocked(app, true, now, nowElapsed);
20053
20054                // Count the number of process types.
20055                switch (app.curProcState) {
20056                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20057                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20058                        mNumCachedHiddenProcs++;
20059                        numCached++;
20060                        if (numCached > cachedProcessLimit) {
20061                            app.kill("cached #" + numCached, true);
20062                        }
20063                        break;
20064                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20065                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20066                                && app.lastActivityTime < oldTime) {
20067                            app.kill("empty for "
20068                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20069                                    / 1000) + "s", true);
20070                        } else {
20071                            numEmpty++;
20072                            if (numEmpty > emptyProcessLimit) {
20073                                app.kill("empty #" + numEmpty, true);
20074                            }
20075                        }
20076                        break;
20077                    default:
20078                        mNumNonCachedProcs++;
20079                        break;
20080                }
20081
20082                if (app.isolated && app.services.size() <= 0) {
20083                    // If this is an isolated process, and there are no
20084                    // services running in it, then the process is no longer
20085                    // needed.  We agressively kill these because we can by
20086                    // definition not re-use the same process again, and it is
20087                    // good to avoid having whatever code was running in them
20088                    // left sitting around after no longer needed.
20089                    app.kill("isolated not needed", true);
20090                } else {
20091                    // Keeping this process, update its uid.
20092                    final UidRecord uidRec = app.uidRecord;
20093                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20094                        uidRec.curProcState = app.curProcState;
20095                    }
20096                }
20097
20098                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20099                        && !app.killedByAm) {
20100                    numTrimming++;
20101                }
20102            }
20103        }
20104
20105        mNumServiceProcs = mNewNumServiceProcs;
20106
20107        // Now determine the memory trimming level of background processes.
20108        // Unfortunately we need to start at the back of the list to do this
20109        // properly.  We only do this if the number of background apps we
20110        // are managing to keep around is less than half the maximum we desire;
20111        // if we are keeping a good number around, we'll let them use whatever
20112        // memory they want.
20113        final int numCachedAndEmpty = numCached + numEmpty;
20114        int memFactor;
20115        if (numCached <= ProcessList.TRIM_CACHED_APPS
20116                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20117            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20118                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20119            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20120                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20121            } else {
20122                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20123            }
20124        } else {
20125            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20126        }
20127        // We always allow the memory level to go up (better).  We only allow it to go
20128        // down if we are in a state where that is allowed, *and* the total number of processes
20129        // has gone down since last time.
20130        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20131                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20132                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20133        if (memFactor > mLastMemoryLevel) {
20134            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20135                memFactor = mLastMemoryLevel;
20136                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20137            }
20138        }
20139        if (memFactor != mLastMemoryLevel) {
20140            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20141        }
20142        mLastMemoryLevel = memFactor;
20143        mLastNumProcesses = mLruProcesses.size();
20144        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20145        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20146        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20147            if (mLowRamStartTime == 0) {
20148                mLowRamStartTime = now;
20149            }
20150            int step = 0;
20151            int fgTrimLevel;
20152            switch (memFactor) {
20153                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20154                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20155                    break;
20156                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20157                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20158                    break;
20159                default:
20160                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20161                    break;
20162            }
20163            int factor = numTrimming/3;
20164            int minFactor = 2;
20165            if (mHomeProcess != null) minFactor++;
20166            if (mPreviousProcess != null) minFactor++;
20167            if (factor < minFactor) factor = minFactor;
20168            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20169            for (int i=N-1; i>=0; i--) {
20170                ProcessRecord app = mLruProcesses.get(i);
20171                if (allChanged || app.procStateChanged) {
20172                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20173                    app.procStateChanged = false;
20174                }
20175                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20176                        && !app.killedByAm) {
20177                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20178                        try {
20179                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20180                                    "Trimming memory of " + app.processName + " to " + curLevel);
20181                            app.thread.scheduleTrimMemory(curLevel);
20182                        } catch (RemoteException e) {
20183                        }
20184                        if (false) {
20185                            // For now we won't do this; our memory trimming seems
20186                            // to be good enough at this point that destroying
20187                            // activities causes more harm than good.
20188                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20189                                    && app != mHomeProcess && app != mPreviousProcess) {
20190                                // Need to do this on its own message because the stack may not
20191                                // be in a consistent state at this point.
20192                                // For these apps we will also finish their activities
20193                                // to help them free memory.
20194                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20195                            }
20196                        }
20197                    }
20198                    app.trimMemoryLevel = curLevel;
20199                    step++;
20200                    if (step >= factor) {
20201                        step = 0;
20202                        switch (curLevel) {
20203                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20204                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20205                                break;
20206                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20207                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20208                                break;
20209                        }
20210                    }
20211                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20212                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20213                            && app.thread != null) {
20214                        try {
20215                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20216                                    "Trimming memory of heavy-weight " + app.processName
20217                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20218                            app.thread.scheduleTrimMemory(
20219                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20220                        } catch (RemoteException e) {
20221                        }
20222                    }
20223                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20224                } else {
20225                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20226                            || app.systemNoUi) && app.pendingUiClean) {
20227                        // If this application is now in the background and it
20228                        // had done UI, then give it the special trim level to
20229                        // have it free UI resources.
20230                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20231                        if (app.trimMemoryLevel < level && app.thread != null) {
20232                            try {
20233                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20234                                        "Trimming memory of bg-ui " + app.processName
20235                                        + " to " + level);
20236                                app.thread.scheduleTrimMemory(level);
20237                            } catch (RemoteException e) {
20238                            }
20239                        }
20240                        app.pendingUiClean = false;
20241                    }
20242                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20243                        try {
20244                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20245                                    "Trimming memory of fg " + app.processName
20246                                    + " to " + fgTrimLevel);
20247                            app.thread.scheduleTrimMemory(fgTrimLevel);
20248                        } catch (RemoteException e) {
20249                        }
20250                    }
20251                    app.trimMemoryLevel = fgTrimLevel;
20252                }
20253            }
20254        } else {
20255            if (mLowRamStartTime != 0) {
20256                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20257                mLowRamStartTime = 0;
20258            }
20259            for (int i=N-1; i>=0; i--) {
20260                ProcessRecord app = mLruProcesses.get(i);
20261                if (allChanged || app.procStateChanged) {
20262                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20263                    app.procStateChanged = false;
20264                }
20265                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20266                        || app.systemNoUi) && app.pendingUiClean) {
20267                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20268                            && app.thread != null) {
20269                        try {
20270                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20271                                    "Trimming memory of ui hidden " + app.processName
20272                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20273                            app.thread.scheduleTrimMemory(
20274                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20275                        } catch (RemoteException e) {
20276                        }
20277                    }
20278                    app.pendingUiClean = false;
20279                }
20280                app.trimMemoryLevel = 0;
20281            }
20282        }
20283
20284        if (mAlwaysFinishActivities) {
20285            // Need to do this on its own message because the stack may not
20286            // be in a consistent state at this point.
20287            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20288        }
20289
20290        if (allChanged) {
20291            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20292        }
20293
20294        // Update from any uid changes.
20295        for (int i=mActiveUids.size()-1; i>=0; i--) {
20296            final UidRecord uidRec = mActiveUids.valueAt(i);
20297            int uidChange = UidRecord.CHANGE_PROCSTATE;
20298            if (uidRec.setProcState != uidRec.curProcState) {
20299                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20300                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20301                        + " to " + uidRec.curProcState);
20302                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20303                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20304                        uidRec.lastBackgroundTime = nowElapsed;
20305                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20306                            // Note: the background settle time is in elapsed realtime, while
20307                            // the handler time base is uptime.  All this means is that we may
20308                            // stop background uids later than we had intended, but that only
20309                            // happens because the device was sleeping so we are okay anyway.
20310                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20311                        }
20312                    }
20313                } else {
20314                    if (uidRec.idle) {
20315                        uidChange = UidRecord.CHANGE_ACTIVE;
20316                        uidRec.idle = false;
20317                    }
20318                    uidRec.lastBackgroundTime = 0;
20319                }
20320                uidRec.setProcState = uidRec.curProcState;
20321                enqueueUidChangeLocked(uidRec, -1, uidChange);
20322                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20323            }
20324        }
20325
20326        if (mProcessStats.shouldWriteNowLocked(now)) {
20327            mHandler.post(new Runnable() {
20328                @Override public void run() {
20329                    synchronized (ActivityManagerService.this) {
20330                        mProcessStats.writeStateAsyncLocked();
20331                    }
20332                }
20333            });
20334        }
20335
20336        if (DEBUG_OOM_ADJ) {
20337            final long duration = SystemClock.uptimeMillis() - now;
20338            if (false) {
20339                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20340                        new RuntimeException("here").fillInStackTrace());
20341            } else {
20342                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20343            }
20344        }
20345    }
20346
20347    final void idleUids() {
20348        synchronized (this) {
20349            final long nowElapsed = SystemClock.elapsedRealtime();
20350            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20351            long nextTime = 0;
20352            for (int i=mActiveUids.size()-1; i>=0; i--) {
20353                final UidRecord uidRec = mActiveUids.valueAt(i);
20354                final long bgTime = uidRec.lastBackgroundTime;
20355                if (bgTime > 0 && !uidRec.idle) {
20356                    if (bgTime <= maxBgTime) {
20357                        uidRec.idle = true;
20358                        doStopUidLocked(uidRec.uid, uidRec);
20359                    } else {
20360                        if (nextTime == 0 || nextTime > bgTime) {
20361                            nextTime = bgTime;
20362                        }
20363                    }
20364                }
20365            }
20366            if (nextTime > 0) {
20367                mHandler.removeMessages(IDLE_UIDS_MSG);
20368                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20369                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20370            }
20371        }
20372    }
20373
20374    final void runInBackgroundDisabled(int uid) {
20375        synchronized (this) {
20376            UidRecord uidRec = mActiveUids.get(uid);
20377            if (uidRec != null) {
20378                // This uid is actually running...  should it be considered background now?
20379                if (uidRec.idle) {
20380                    doStopUidLocked(uidRec.uid, uidRec);
20381                }
20382            } else {
20383                // This uid isn't actually running...  still send a report about it being "stopped".
20384                doStopUidLocked(uid, null);
20385            }
20386        }
20387    }
20388
20389    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20390        mServices.stopInBackgroundLocked(uid);
20391        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20392    }
20393
20394    final void trimApplications() {
20395        synchronized (this) {
20396            int i;
20397
20398            // First remove any unused application processes whose package
20399            // has been removed.
20400            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20401                final ProcessRecord app = mRemovedProcesses.get(i);
20402                if (app.activities.size() == 0
20403                        && app.curReceiver == null && app.services.size() == 0) {
20404                    Slog.i(
20405                        TAG, "Exiting empty application process "
20406                        + app.processName + " ("
20407                        + (app.thread != null ? app.thread.asBinder() : null)
20408                        + ")\n");
20409                    if (app.pid > 0 && app.pid != MY_PID) {
20410                        app.kill("empty", false);
20411                    } else {
20412                        try {
20413                            app.thread.scheduleExit();
20414                        } catch (Exception e) {
20415                            // Ignore exceptions.
20416                        }
20417                    }
20418                    cleanUpApplicationRecordLocked(app, false, true, -1);
20419                    mRemovedProcesses.remove(i);
20420
20421                    if (app.persistent) {
20422                        addAppLocked(app.info, false, null /* ABI override */);
20423                    }
20424                }
20425            }
20426
20427            // Now update the oom adj for all processes.
20428            updateOomAdjLocked();
20429        }
20430    }
20431
20432    /** This method sends the specified signal to each of the persistent apps */
20433    public void signalPersistentProcesses(int sig) throws RemoteException {
20434        if (sig != Process.SIGNAL_USR1) {
20435            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20436        }
20437
20438        synchronized (this) {
20439            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20440                    != PackageManager.PERMISSION_GRANTED) {
20441                throw new SecurityException("Requires permission "
20442                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20443            }
20444
20445            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20446                ProcessRecord r = mLruProcesses.get(i);
20447                if (r.thread != null && r.persistent) {
20448                    Process.sendSignal(r.pid, sig);
20449                }
20450            }
20451        }
20452    }
20453
20454    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20455        if (proc == null || proc == mProfileProc) {
20456            proc = mProfileProc;
20457            profileType = mProfileType;
20458            clearProfilerLocked();
20459        }
20460        if (proc == null) {
20461            return;
20462        }
20463        try {
20464            proc.thread.profilerControl(false, null, profileType);
20465        } catch (RemoteException e) {
20466            throw new IllegalStateException("Process disappeared");
20467        }
20468    }
20469
20470    private void clearProfilerLocked() {
20471        if (mProfileFd != null) {
20472            try {
20473                mProfileFd.close();
20474            } catch (IOException e) {
20475            }
20476        }
20477        mProfileApp = null;
20478        mProfileProc = null;
20479        mProfileFile = null;
20480        mProfileType = 0;
20481        mAutoStopProfiler = false;
20482        mSamplingInterval = 0;
20483    }
20484
20485    public boolean profileControl(String process, int userId, boolean start,
20486            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20487
20488        try {
20489            synchronized (this) {
20490                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20491                // its own permission.
20492                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20493                        != PackageManager.PERMISSION_GRANTED) {
20494                    throw new SecurityException("Requires permission "
20495                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20496                }
20497
20498                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20499                    throw new IllegalArgumentException("null profile info or fd");
20500                }
20501
20502                ProcessRecord proc = null;
20503                if (process != null) {
20504                    proc = findProcessLocked(process, userId, "profileControl");
20505                }
20506
20507                if (start && (proc == null || proc.thread == null)) {
20508                    throw new IllegalArgumentException("Unknown process: " + process);
20509                }
20510
20511                if (start) {
20512                    stopProfilerLocked(null, 0);
20513                    setProfileApp(proc.info, proc.processName, profilerInfo);
20514                    mProfileProc = proc;
20515                    mProfileType = profileType;
20516                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20517                    try {
20518                        fd = fd.dup();
20519                    } catch (IOException e) {
20520                        fd = null;
20521                    }
20522                    profilerInfo.profileFd = fd;
20523                    proc.thread.profilerControl(start, profilerInfo, profileType);
20524                    fd = null;
20525                    mProfileFd = null;
20526                } else {
20527                    stopProfilerLocked(proc, profileType);
20528                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20529                        try {
20530                            profilerInfo.profileFd.close();
20531                        } catch (IOException e) {
20532                        }
20533                    }
20534                }
20535
20536                return true;
20537            }
20538        } catch (RemoteException e) {
20539            throw new IllegalStateException("Process disappeared");
20540        } finally {
20541            if (profilerInfo != null && profilerInfo.profileFd != null) {
20542                try {
20543                    profilerInfo.profileFd.close();
20544                } catch (IOException e) {
20545                }
20546            }
20547        }
20548    }
20549
20550    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20551        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20552                userId, true, ALLOW_FULL_ONLY, callName, null);
20553        ProcessRecord proc = null;
20554        try {
20555            int pid = Integer.parseInt(process);
20556            synchronized (mPidsSelfLocked) {
20557                proc = mPidsSelfLocked.get(pid);
20558            }
20559        } catch (NumberFormatException e) {
20560        }
20561
20562        if (proc == null) {
20563            ArrayMap<String, SparseArray<ProcessRecord>> all
20564                    = mProcessNames.getMap();
20565            SparseArray<ProcessRecord> procs = all.get(process);
20566            if (procs != null && procs.size() > 0) {
20567                proc = procs.valueAt(0);
20568                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20569                    for (int i=1; i<procs.size(); i++) {
20570                        ProcessRecord thisProc = procs.valueAt(i);
20571                        if (thisProc.userId == userId) {
20572                            proc = thisProc;
20573                            break;
20574                        }
20575                    }
20576                }
20577            }
20578        }
20579
20580        return proc;
20581    }
20582
20583    public boolean dumpHeap(String process, int userId, boolean managed,
20584            String path, ParcelFileDescriptor fd) throws RemoteException {
20585
20586        try {
20587            synchronized (this) {
20588                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20589                // its own permission (same as profileControl).
20590                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20591                        != PackageManager.PERMISSION_GRANTED) {
20592                    throw new SecurityException("Requires permission "
20593                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20594                }
20595
20596                if (fd == null) {
20597                    throw new IllegalArgumentException("null fd");
20598                }
20599
20600                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20601                if (proc == null || proc.thread == null) {
20602                    throw new IllegalArgumentException("Unknown process: " + process);
20603                }
20604
20605                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20606                if (!isDebuggable) {
20607                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20608                        throw new SecurityException("Process not debuggable: " + proc);
20609                    }
20610                }
20611
20612                proc.thread.dumpHeap(managed, path, fd);
20613                fd = null;
20614                return true;
20615            }
20616        } catch (RemoteException e) {
20617            throw new IllegalStateException("Process disappeared");
20618        } finally {
20619            if (fd != null) {
20620                try {
20621                    fd.close();
20622                } catch (IOException e) {
20623                }
20624            }
20625        }
20626    }
20627
20628    @Override
20629    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20630            String reportPackage) {
20631        if (processName != null) {
20632            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20633                    "setDumpHeapDebugLimit()");
20634        } else {
20635            synchronized (mPidsSelfLocked) {
20636                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20637                if (proc == null) {
20638                    throw new SecurityException("No process found for calling pid "
20639                            + Binder.getCallingPid());
20640                }
20641                if (!Build.IS_DEBUGGABLE
20642                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20643                    throw new SecurityException("Not running a debuggable build");
20644                }
20645                processName = proc.processName;
20646                uid = proc.uid;
20647                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20648                    throw new SecurityException("Package " + reportPackage + " is not running in "
20649                            + proc);
20650                }
20651            }
20652        }
20653        synchronized (this) {
20654            if (maxMemSize > 0) {
20655                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20656            } else {
20657                if (uid != 0) {
20658                    mMemWatchProcesses.remove(processName, uid);
20659                } else {
20660                    mMemWatchProcesses.getMap().remove(processName);
20661                }
20662            }
20663        }
20664    }
20665
20666    @Override
20667    public void dumpHeapFinished(String path) {
20668        synchronized (this) {
20669            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20670                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20671                        + " does not match last pid " + mMemWatchDumpPid);
20672                return;
20673            }
20674            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20675                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20676                        + " does not match last path " + mMemWatchDumpFile);
20677                return;
20678            }
20679            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20680            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20681        }
20682    }
20683
20684    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20685    public void monitor() {
20686        synchronized (this) { }
20687    }
20688
20689    void onCoreSettingsChange(Bundle settings) {
20690        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20691            ProcessRecord processRecord = mLruProcesses.get(i);
20692            try {
20693                if (processRecord.thread != null) {
20694                    processRecord.thread.setCoreSettings(settings);
20695                }
20696            } catch (RemoteException re) {
20697                /* ignore */
20698            }
20699        }
20700    }
20701
20702    // Multi-user methods
20703
20704    /**
20705     * Start user, if its not already running, but don't bring it to foreground.
20706     */
20707    @Override
20708    public boolean startUserInBackground(final int userId) {
20709        return mUserController.startUser(userId, /* foreground */ false);
20710    }
20711
20712    @Override
20713    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20714        return mUserController.unlockUser(userId, token, secret, listener);
20715    }
20716
20717    @Override
20718    public boolean switchUser(final int targetUserId) {
20719        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20720        UserInfo currentUserInfo;
20721        UserInfo targetUserInfo;
20722        synchronized (this) {
20723            int currentUserId = mUserController.getCurrentUserIdLocked();
20724            currentUserInfo = mUserController.getUserInfo(currentUserId);
20725            targetUserInfo = mUserController.getUserInfo(targetUserId);
20726            if (targetUserInfo == null) {
20727                Slog.w(TAG, "No user info for user #" + targetUserId);
20728                return false;
20729            }
20730            if (!targetUserInfo.supportsSwitchTo()) {
20731                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20732                return false;
20733            }
20734            if (targetUserInfo.isManagedProfile()) {
20735                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20736                return false;
20737            }
20738            mUserController.setTargetUserIdLocked(targetUserId);
20739        }
20740        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20741        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20742        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20743        return true;
20744    }
20745
20746    void scheduleStartProfilesLocked() {
20747        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20748            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20749                    DateUtils.SECOND_IN_MILLIS);
20750        }
20751    }
20752
20753    @Override
20754    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20755        return mUserController.stopUser(userId, force, callback);
20756    }
20757
20758    @Override
20759    public UserInfo getCurrentUser() {
20760        return mUserController.getCurrentUser();
20761    }
20762
20763    @Override
20764    public boolean isUserRunning(int userId, int flags) {
20765        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20766                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20767            String msg = "Permission Denial: isUserRunning() from pid="
20768                    + Binder.getCallingPid()
20769                    + ", uid=" + Binder.getCallingUid()
20770                    + " requires " + INTERACT_ACROSS_USERS;
20771            Slog.w(TAG, msg);
20772            throw new SecurityException(msg);
20773        }
20774        synchronized (this) {
20775            return mUserController.isUserRunningLocked(userId, flags);
20776        }
20777    }
20778
20779    @Override
20780    public int[] getRunningUserIds() {
20781        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20782                != PackageManager.PERMISSION_GRANTED) {
20783            String msg = "Permission Denial: isUserRunning() from pid="
20784                    + Binder.getCallingPid()
20785                    + ", uid=" + Binder.getCallingUid()
20786                    + " requires " + INTERACT_ACROSS_USERS;
20787            Slog.w(TAG, msg);
20788            throw new SecurityException(msg);
20789        }
20790        synchronized (this) {
20791            return mUserController.getStartedUserArrayLocked();
20792        }
20793    }
20794
20795    @Override
20796    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20797        mUserController.registerUserSwitchObserver(observer);
20798    }
20799
20800    @Override
20801    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20802        mUserController.unregisterUserSwitchObserver(observer);
20803    }
20804
20805    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20806        if (info == null) return null;
20807        ApplicationInfo newInfo = new ApplicationInfo(info);
20808        newInfo.initForUser(userId);
20809        return newInfo;
20810    }
20811
20812    public boolean isUserStopped(int userId) {
20813        synchronized (this) {
20814            return mUserController.getStartedUserStateLocked(userId) == null;
20815        }
20816    }
20817
20818    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20819        if (aInfo == null
20820                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20821            return aInfo;
20822        }
20823
20824        ActivityInfo info = new ActivityInfo(aInfo);
20825        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20826        return info;
20827    }
20828
20829    private boolean processSanityChecksLocked(ProcessRecord process) {
20830        if (process == null || process.thread == null) {
20831            return false;
20832        }
20833
20834        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20835        if (!isDebuggable) {
20836            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20837                return false;
20838            }
20839        }
20840
20841        return true;
20842    }
20843
20844    public boolean startBinderTracking() throws RemoteException {
20845        synchronized (this) {
20846            mBinderTransactionTrackingEnabled = true;
20847            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20848            // permission (same as profileControl).
20849            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20850                    != PackageManager.PERMISSION_GRANTED) {
20851                throw new SecurityException("Requires permission "
20852                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20853            }
20854
20855            for (int i = 0; i < mLruProcesses.size(); i++) {
20856                ProcessRecord process = mLruProcesses.get(i);
20857                if (!processSanityChecksLocked(process)) {
20858                    continue;
20859                }
20860                try {
20861                    process.thread.startBinderTracking();
20862                } catch (RemoteException e) {
20863                    Log.v(TAG, "Process disappared");
20864                }
20865            }
20866            return true;
20867        }
20868    }
20869
20870    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20871        try {
20872            synchronized (this) {
20873                mBinderTransactionTrackingEnabled = false;
20874                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20875                // permission (same as profileControl).
20876                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20877                        != PackageManager.PERMISSION_GRANTED) {
20878                    throw new SecurityException("Requires permission "
20879                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20880                }
20881
20882                if (fd == null) {
20883                    throw new IllegalArgumentException("null fd");
20884                }
20885
20886                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20887                pw.println("Binder transaction traces for all processes.\n");
20888                for (ProcessRecord process : mLruProcesses) {
20889                    if (!processSanityChecksLocked(process)) {
20890                        continue;
20891                    }
20892
20893                    pw.println("Traces for process: " + process.processName);
20894                    pw.flush();
20895                    try {
20896                        TransferPipe tp = new TransferPipe();
20897                        try {
20898                            process.thread.stopBinderTrackingAndDump(
20899                                    tp.getWriteFd().getFileDescriptor());
20900                            tp.go(fd.getFileDescriptor());
20901                        } finally {
20902                            tp.kill();
20903                        }
20904                    } catch (IOException e) {
20905                        pw.println("Failure while dumping IPC traces from " + process +
20906                                ".  Exception: " + e);
20907                        pw.flush();
20908                    } catch (RemoteException e) {
20909                        pw.println("Got a RemoteException while dumping IPC traces from " +
20910                                process + ".  Exception: " + e);
20911                        pw.flush();
20912                    }
20913                }
20914                fd = null;
20915                return true;
20916            }
20917        } finally {
20918            if (fd != null) {
20919                try {
20920                    fd.close();
20921                } catch (IOException e) {
20922                }
20923            }
20924        }
20925    }
20926
20927    private final class LocalService extends ActivityManagerInternal {
20928        @Override
20929        public void onWakefulnessChanged(int wakefulness) {
20930            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20931        }
20932
20933        @Override
20934        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20935                String processName, String abiOverride, int uid, Runnable crashHandler) {
20936            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20937                    processName, abiOverride, uid, crashHandler);
20938        }
20939
20940        @Override
20941        public SleepToken acquireSleepToken(String tag) {
20942            Preconditions.checkNotNull(tag);
20943
20944            synchronized (ActivityManagerService.this) {
20945                SleepTokenImpl token = new SleepTokenImpl(tag);
20946                mSleepTokens.add(token);
20947                updateSleepIfNeededLocked();
20948                applyVrModeIfNeededLocked(mFocusedActivity, false);
20949                return token;
20950            }
20951        }
20952
20953        @Override
20954        public ComponentName getHomeActivityForUser(int userId) {
20955            synchronized (ActivityManagerService.this) {
20956                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20957                return homeActivity == null ? null : homeActivity.realActivity;
20958            }
20959        }
20960
20961        @Override
20962        public void onUserRemoved(int userId) {
20963            synchronized (ActivityManagerService.this) {
20964                ActivityManagerService.this.onUserStoppedLocked(userId);
20965            }
20966        }
20967
20968        @Override
20969        public void onLocalVoiceInteractionStarted(IBinder activity,
20970                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20971            synchronized (ActivityManagerService.this) {
20972                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20973                        voiceSession, voiceInteractor);
20974            }
20975        }
20976
20977        @Override
20978        public void notifyStartingWindowDrawn() {
20979            synchronized (ActivityManagerService.this) {
20980                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20981            }
20982        }
20983
20984        @Override
20985        public void notifyAppTransitionStarting(int reason) {
20986            synchronized (ActivityManagerService.this) {
20987                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20988            }
20989        }
20990
20991        @Override
20992        public void notifyAppTransitionFinished() {
20993            synchronized (ActivityManagerService.this) {
20994                mStackSupervisor.notifyAppTransitionDone();
20995            }
20996        }
20997
20998        @Override
20999        public void notifyAppTransitionCancelled() {
21000            synchronized (ActivityManagerService.this) {
21001                mStackSupervisor.notifyAppTransitionDone();
21002            }
21003        }
21004
21005        @Override
21006        public List<IBinder> getTopVisibleActivities() {
21007            synchronized (ActivityManagerService.this) {
21008                return mStackSupervisor.getTopVisibleActivities();
21009            }
21010        }
21011
21012        @Override
21013        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21014            synchronized (ActivityManagerService.this) {
21015                mStackSupervisor.setDockedStackMinimized(minimized);
21016            }
21017        }
21018
21019        @Override
21020        public void killForegroundAppsForUser(int userHandle) {
21021            synchronized (ActivityManagerService.this) {
21022                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21023                final int NP = mProcessNames.getMap().size();
21024                for (int ip = 0; ip < NP; ip++) {
21025                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21026                    final int NA = apps.size();
21027                    for (int ia = 0; ia < NA; ia++) {
21028                        final ProcessRecord app = apps.valueAt(ia);
21029                        if (app.persistent) {
21030                            // We don't kill persistent processes.
21031                            continue;
21032                        }
21033                        if (app.removed) {
21034                            procs.add(app);
21035                        } else if (app.userId == userHandle && app.foregroundActivities) {
21036                            app.removed = true;
21037                            procs.add(app);
21038                        }
21039                    }
21040                }
21041
21042                final int N = procs.size();
21043                for (int i = 0; i < N; i++) {
21044                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21045                }
21046            }
21047        }
21048    }
21049
21050    private final class SleepTokenImpl extends SleepToken {
21051        private final String mTag;
21052        private final long mAcquireTime;
21053
21054        public SleepTokenImpl(String tag) {
21055            mTag = tag;
21056            mAcquireTime = SystemClock.uptimeMillis();
21057        }
21058
21059        @Override
21060        public void release() {
21061            synchronized (ActivityManagerService.this) {
21062                if (mSleepTokens.remove(this)) {
21063                    updateSleepIfNeededLocked();
21064                }
21065            }
21066        }
21067
21068        @Override
21069        public String toString() {
21070            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21071        }
21072    }
21073
21074    /**
21075     * An implementation of IAppTask, that allows an app to manage its own tasks via
21076     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21077     * only the process that calls getAppTasks() can call the AppTask methods.
21078     */
21079    class AppTaskImpl extends IAppTask.Stub {
21080        private int mTaskId;
21081        private int mCallingUid;
21082
21083        public AppTaskImpl(int taskId, int callingUid) {
21084            mTaskId = taskId;
21085            mCallingUid = callingUid;
21086        }
21087
21088        private void checkCaller() {
21089            if (mCallingUid != Binder.getCallingUid()) {
21090                throw new SecurityException("Caller " + mCallingUid
21091                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21092            }
21093        }
21094
21095        @Override
21096        public void finishAndRemoveTask() {
21097            checkCaller();
21098
21099            synchronized (ActivityManagerService.this) {
21100                long origId = Binder.clearCallingIdentity();
21101                try {
21102                    // We remove the task from recents to preserve backwards
21103                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21104                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21105                    }
21106                } finally {
21107                    Binder.restoreCallingIdentity(origId);
21108                }
21109            }
21110        }
21111
21112        @Override
21113        public ActivityManager.RecentTaskInfo getTaskInfo() {
21114            checkCaller();
21115
21116            synchronized (ActivityManagerService.this) {
21117                long origId = Binder.clearCallingIdentity();
21118                try {
21119                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21120                    if (tr == null) {
21121                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21122                    }
21123                    return createRecentTaskInfoFromTaskRecord(tr);
21124                } finally {
21125                    Binder.restoreCallingIdentity(origId);
21126                }
21127            }
21128        }
21129
21130        @Override
21131        public void moveToFront() {
21132            checkCaller();
21133            // Will bring task to front if it already has a root activity.
21134            final long origId = Binder.clearCallingIdentity();
21135            try {
21136                synchronized (this) {
21137                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21138                }
21139            } finally {
21140                Binder.restoreCallingIdentity(origId);
21141            }
21142        }
21143
21144        @Override
21145        public int startActivity(IBinder whoThread, String callingPackage,
21146                Intent intent, String resolvedType, Bundle bOptions) {
21147            checkCaller();
21148
21149            int callingUser = UserHandle.getCallingUserId();
21150            TaskRecord tr;
21151            IApplicationThread appThread;
21152            synchronized (ActivityManagerService.this) {
21153                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21154                if (tr == null) {
21155                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21156                }
21157                appThread = ApplicationThreadNative.asInterface(whoThread);
21158                if (appThread == null) {
21159                    throw new IllegalArgumentException("Bad app thread " + appThread);
21160                }
21161            }
21162            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21163                    resolvedType, null, null, null, null, 0, 0, null, null,
21164                    null, bOptions, false, callingUser, null, tr);
21165        }
21166
21167        @Override
21168        public void setExcludeFromRecents(boolean exclude) {
21169            checkCaller();
21170
21171            synchronized (ActivityManagerService.this) {
21172                long origId = Binder.clearCallingIdentity();
21173                try {
21174                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21175                    if (tr == null) {
21176                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21177                    }
21178                    Intent intent = tr.getBaseIntent();
21179                    if (exclude) {
21180                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21181                    } else {
21182                        intent.setFlags(intent.getFlags()
21183                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21184                    }
21185                } finally {
21186                    Binder.restoreCallingIdentity(origId);
21187                }
21188            }
21189        }
21190    }
21191
21192    /**
21193     * Kill processes for the user with id userId and that depend on the package named packageName
21194     */
21195    @Override
21196    public void killPackageDependents(String packageName, int userId) {
21197        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21198        if (packageName == null) {
21199            throw new NullPointerException(
21200                    "Cannot kill the dependents of a package without its name.");
21201        }
21202
21203        long callingId = Binder.clearCallingIdentity();
21204        IPackageManager pm = AppGlobals.getPackageManager();
21205        int pkgUid = -1;
21206        try {
21207            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21208        } catch (RemoteException e) {
21209        }
21210        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21211            throw new IllegalArgumentException(
21212                    "Cannot kill dependents of non-existing package " + packageName);
21213        }
21214        try {
21215            synchronized(this) {
21216                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21217                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21218                        "dep: " + packageName);
21219            }
21220        } finally {
21221            Binder.restoreCallingIdentity(callingId);
21222        }
21223    }
21224}
21225